diff options
author | Arnold Daniels <arnold@jasny.net> | 2015-09-27 16:55:48 +0200 |
---|---|---|
committer | Arnold Daniels <arnold@jasny.net> | 2015-09-27 16:55:48 +0200 |
commit | 3323715e88c22eeae359d9b7cb40ec921c97199e (patch) | |
tree | 63ccf1c19240612122232caab24fc7bcaef1becc | |
parent | bb037525545f1cc36ad15f6a0719c807ab878591 (diff) | |
parent | 06d3638c4e66d607435ac0e4f784560b34d3927f (diff) | |
download | sso-3323715e88c22eeae359d9b7cb40ec921c97199e.zip sso-3323715e88c22eeae359d9b7cb40ec921c97199e.tar.gz sso-3323715e88c22eeae359d9b7cb40ec921c97199e.tar.bz2 |
Merge pull request #16 from jasny/library
Turn demo into a library
356 files changed, 4616 insertions, 102673 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..622097a --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +.DS_Store +nbproject +/vendor +composer.lock + +tests/_output/* +# Elastic Beanstalk Files +.elasticbeanstalk/* +!.elasticbeanstalk/*.cfg.yml +!.elasticbeanstalk/*.global.yml +/tests/_support/_generated/ @@ -1,12 +1,28 @@ -Simple Single Sign-On for PHP (Ajax compatible) +Single Sign-On for PHP (Ajax compatible) --- -Associated websites often share user information, so a visitor only has to register once and can use that username and password for all sites. A good example for this is Google. You can use you google account for GMail, Blogger, iGoogle, google code, etc. This is nice, but it would be even nicer if logging in for GMail would mean I’m also logged in for the other websites. For that you need to implement [single sign-on](http://en.wikipedia.org/wiki/Single_sign-on) (SSO). +Jasny\SSO is a relatively simply and strait forward solution for an single sign on (SSO) implementation. With SSO, +logging into a single website will authenticate you for all affiliate sites. There are many single sign-on applications and protocols. Most of these are fairly complex. Applications often come with full user management solutions. This makes them difficult to integrate. Most solutions also don’t work well with AJAX, because redirection is used to let the visitor log in at the SSO server. I’ve written a simple single sign-on solution (400 lines of code), which works by linking sessions. This solutions works for normal websites as well as AJAX sites. +## Installation and examples +The dependencies can be installed with the use of composer. + +``` +composer install +``` + +This library makes use of curl so make sure it is one of the enabled functions. +The test can be executed by starting two PHP web-servers at the root of the +package, and running `vendor/bin/codecept run`. One of the web-servers must listen to +`127.0.0.1:9000`, the other to `127.0.0.1:9001`. The first is the server and the +second is used for the broker and the client. + +Similarly, to run the examples, run the two web servers, and navigate to `127.0.0.1:9001/examples/<example>`. + ## Without SSO Let’s start with a website that doesn’t have SSO. @@ -41,24 +57,29 @@ The client logs in, sending the username and password to the broker. The broker [](http://blog.jasny.net/wp-content/uploads/sso-diagram_binck.png) -You visit another broker. It also checks for a token cookie. Since each broker is on their own domain, they have different cookies, so no token cookie will be found. The broker will redirect to the server attach to the user session. +#### Broker -The server attaches a session key generated for this broker, which differs from the one for the first broker. It attaches it to the user session. This is the same session the first broker used. The server will redirect back to the original URL. +When creating a Jasny\SSO\Broker instance, you need to pass the server url, broker id and broker secret. The broker id +and secret needs to be registered at the server (so fetched when using `getBrokerInfo($brokerId)`). -The client requests the index page at the broker. The broker will request user information from the server. Since the visitor is already logged in, the server returns this information. The index page is shown to the visitor. +Next you need to call `attach()`. This will generate a token an redirect the client to the server to attach the token +to the client's session. If the client is already attached, the function will simply return. -## Using AJAX / Javascript +When the session is attached you can do actions as login/logout or get the user's info. SSO and AJAX / RIA applications often don’t go well together. With this type of application, you do not want to leave the page. The application is static and you get the data and do all actions through AJAX. Redirecting an AJAX call to a different website won’t because of cross-site scripting protection within the browser. -With this solution the client only needs to attach the session by providing the server with a token generated by the broker. That attach request doesn’t return any information. After attaching the client doesn’t talk at all to the server any more. Authentication can be done as normal. +## Examples [](http://blog.jasny.net/wp-content/uploads/sso-diagram_ajax.png) The client check for the token cookie. If it doesn’t exists, he requests the attach URL from the broker. This attach url includes the broker name and the token, but not a original request URL. The client will open the received url in an <img> and wait until the image is loaded. -The server attaches the browser session key to the user session. When it’s done it outputs a PNG image. When this image is received by the client, it knows the server has connected the sessions and the broker can be used for authentication. The broker will work as a proxy, passing commands and requests to the sso server and return results to the client. + php -S localhost:9000 -t examples/server/ + export SSO_SERVER=http://localhost:9000 SSO_BROKER_ID=Alice SSO_BROKER_SECRET=8iwzik1bwd; php -S localhost:9001 -t examples/broker/ + export SSO_SERVER=http://localhost:9000 SSO_BROKER_ID=Greg SSO_BROKER_SECRET=7pypoox2pc; php -S localhost:9002 -t examples/broker/ + export SSO_SERVER=http://localhost:9000 SSO_BROKER_ID=Julias SSO_BROKER_SECRET=ceda63kmhp; php -S localhost:9003 -t examples/ajax-broker/ -## To conclude +Now open some tabs and visit http://localhost:9001, http://localhost:9002 and http://localhost:9003. -By connecting sessions, you give the broker the power to act as the client. This method can only be used if you trust all brokers involved. The login information is send through the broker, which he can easily store if the broker has bad intentions. +_Note that after logging in, you need to refresh on the other brokers to see the effect._ diff --git a/ajax-broker/code.js b/ajax-broker/code.js deleted file mode 100644 index 426729e..0000000 --- a/ajax-broker/code.js +++ /dev/null @@ -1,68 +0,0 @@ -jpf.onload = function() {
- var session_token = jpf.getcookie("session_token");
-
- if (session_token) {
- comm.info();
- //M_WINmain.show();
- }
- else {
- comm.attachurl();
- }
-}
-
-jpf.auth.onloginsuccess = function(data) {
- comm.info();
- M_WINinfo.show();
- M_WINmain.hide();
-}
-
-jpf.auth.onlogoutsuccess = function(data) {
- M_WINinfo.hide();
- M_WINmain.show();
-}
-
-jpf.auth.onlogoutfail = function(data) {
-
-}
-jpf.auth.onloginfail = function(data) {
-
-}
-
-function M_afterAttachURL(data, state, extra) {
- if (state == jpf.SUCCESS) {
- img = new Image();
-
- document.body.appendChild(img);
-
- img.src = data;
-
- img.onerror = function(e) {
- alert("Image loading error");
- jpf.flow.alert_r(e);
- }
-
- img.onabort = function() {
- alert("Image loading aborted");
- }
-
- img.onload = function() {
- jpf.console.info("Image has been loaded");
- comm.info();
- }
- }
- else {
- alert("An error occur: " + extra.message);
- }
-}
-
-function M_afterInfo(data, state, extra) {
- if (state == jpf.SUCCESS) {
- lblLoggedIn.setValue("You are logged in as " + jpf.getXmlValue(jpf.getXml(data), "fullname"));
-
- M_WINmain.hide();
- M_WINinfo.show();
- }
- else {
- M_WINmain.show();
- }
-}
diff --git a/ajax-broker/images/Bestekteksten_.gif b/ajax-broker/images/Bestekteksten_.gif Binary files differdeleted file mode 100644 index 7a533d3..0000000 --- a/ajax-broker/images/Bestekteksten_.gif +++ /dev/null diff --git a/ajax-broker/images/Productbrochures_.gif b/ajax-broker/images/Productbrochures_.gif Binary files differdeleted file mode 100644 index aeaa09b..0000000 --- a/ajax-broker/images/Productbrochures_.gif +++ /dev/null diff --git a/ajax-broker/images/Productfilm_.gif b/ajax-broker/images/Productfilm_.gif Binary files differdeleted file mode 100644 index 798da09..0000000 --- a/ajax-broker/images/Productfilm_.gif +++ /dev/null diff --git a/ajax-broker/images/alert.png b/ajax-broker/images/alert.png Binary files differdeleted file mode 100644 index 7205bff..0000000 --- a/ajax-broker/images/alert.png +++ /dev/null diff --git a/ajax-broker/images/arrow_down_black.png b/ajax-broker/images/arrow_down_black.png Binary files differdeleted file mode 100644 index 1b1c2c3..0000000 --- a/ajax-broker/images/arrow_down_black.png +++ /dev/null diff --git a/ajax-broker/images/arrow_down_white.png b/ajax-broker/images/arrow_down_white.png Binary files differdeleted file mode 100644 index e989caf..0000000 --- a/ajax-broker/images/arrow_down_white.png +++ /dev/null diff --git a/ajax-broker/images/arrow_left.gif b/ajax-broker/images/arrow_left.gif Binary files differdeleted file mode 100644 index fff66b7..0000000 --- a/ajax-broker/images/arrow_left.gif +++ /dev/null diff --git a/ajax-broker/images/arrow_right.gif b/ajax-broker/images/arrow_right.gif Binary files differdeleted file mode 100644 index d9c246f..0000000 --- a/ajax-broker/images/arrow_right.gif +++ /dev/null diff --git a/ajax-broker/images/arrow_right.png b/ajax-broker/images/arrow_right.png Binary files differdeleted file mode 100644 index 28f8345..0000000 --- a/ajax-broker/images/arrow_right.png +++ /dev/null diff --git a/ajax-broker/images/bar11x_left.png b/ajax-broker/images/bar11x_left.png Binary files differdeleted file mode 100644 index 7362d5f..0000000 --- a/ajax-broker/images/bar11x_left.png +++ /dev/null diff --git a/ajax-broker/images/bar11x_right.png b/ajax-broker/images/bar11x_right.png Binary files differdeleted file mode 100644 index 2e73fe9..0000000 --- a/ajax-broker/images/bar11x_right.png +++ /dev/null diff --git a/ajax-broker/images/bar16x_left.png b/ajax-broker/images/bar16x_left.png Binary files differdeleted file mode 100644 index eacb70f..0000000 --- a/ajax-broker/images/bar16x_left.png +++ /dev/null diff --git a/ajax-broker/images/bar16x_right.png b/ajax-broker/images/bar16x_right.png Binary files differdeleted file mode 100644 index 9acf490..0000000 --- a/ajax-broker/images/bar16x_right.png +++ /dev/null diff --git a/ajax-broker/images/bar_left.png b/ajax-broker/images/bar_left.png Binary files differdeleted file mode 100644 index eedc3b0..0000000 --- a/ajax-broker/images/bar_left.png +++ /dev/null diff --git a/ajax-broker/images/bar_right.png b/ajax-broker/images/bar_right.png Binary files differdeleted file mode 100644 index a285428..0000000 --- a/ajax-broker/images/bar_right.png +++ /dev/null diff --git a/ajax-broker/images/bold.png b/ajax-broker/images/bold.png Binary files differdeleted file mode 100644 index 783dd4b..0000000 --- a/ajax-broker/images/bold.png +++ /dev/null diff --git a/ajax-broker/images/bubble_body.png b/ajax-broker/images/bubble_body.png Binary files differdeleted file mode 100644 index b043d1f..0000000 --- a/ajax-broker/images/bubble_body.png +++ /dev/null diff --git a/ajax-broker/images/bubble_body_small.png b/ajax-broker/images/bubble_body_small.png Binary files differdeleted file mode 100644 index f35fee3..0000000 --- a/ajax-broker/images/bubble_body_small.png +++ /dev/null diff --git a/ajax-broker/images/bubble_lb.gif b/ajax-broker/images/bubble_lb.gif Binary files differdeleted file mode 100644 index 7a25a6c..0000000 --- a/ajax-broker/images/bubble_lb.gif +++ /dev/null diff --git a/ajax-broker/images/bubble_line_b.gif b/ajax-broker/images/bubble_line_b.gif Binary files differdeleted file mode 100644 index 08b7289..0000000 --- a/ajax-broker/images/bubble_line_b.gif +++ /dev/null diff --git a/ajax-broker/images/bubble_line_t.gif b/ajax-broker/images/bubble_line_t.gif Binary files differdeleted file mode 100644 index d9d39e2..0000000 --- a/ajax-broker/images/bubble_line_t.gif +++ /dev/null diff --git a/ajax-broker/images/bubble_lt.gif b/ajax-broker/images/bubble_lt.gif Binary files differdeleted file mode 100644 index 4fa7b91..0000000 --- a/ajax-broker/images/bubble_lt.gif +++ /dev/null diff --git a/ajax-broker/images/bubble_rb.gif b/ajax-broker/images/bubble_rb.gif Binary files differdeleted file mode 100644 index 3e2e63d..0000000 --- a/ajax-broker/images/bubble_rb.gif +++ /dev/null diff --git a/ajax-broker/images/bubble_rt.gif b/ajax-broker/images/bubble_rt.gif Binary files differdeleted file mode 100644 index 724fee8..0000000 --- a/ajax-broker/images/bubble_rt.gif +++ /dev/null diff --git a/ajax-broker/images/button_left.png b/ajax-broker/images/button_left.png Binary files differdeleted file mode 100644 index 2341aac..0000000 --- a/ajax-broker/images/button_left.png +++ /dev/null diff --git a/ajax-broker/images/button_left.psd b/ajax-broker/images/button_left.psd Binary files differdeleted file mode 100644 index 482052e..0000000 --- a/ajax-broker/images/button_left.psd +++ /dev/null diff --git a/ajax-broker/images/button_middle.png b/ajax-broker/images/button_middle.png Binary files differdeleted file mode 100644 index f012bf8..0000000 --- a/ajax-broker/images/button_middle.png +++ /dev/null diff --git a/ajax-broker/images/button_right.png b/ajax-broker/images/button_right.png Binary files differdeleted file mode 100644 index 66cf4ac..0000000 --- a/ajax-broker/images/button_right.png +++ /dev/null diff --git a/ajax-broker/images/calendar_bg.png b/ajax-broker/images/calendar_bg.png Binary files differdeleted file mode 100644 index d444054..0000000 --- a/ajax-broker/images/calendar_bg.png +++ /dev/null diff --git a/ajax-broker/images/calendar_body.png b/ajax-broker/images/calendar_body.png Binary files differdeleted file mode 100644 index 1db6ce2..0000000 --- a/ajax-broker/images/calendar_body.png +++ /dev/null diff --git a/ajax-broker/images/calendar_button.png b/ajax-broker/images/calendar_button.png Binary files differdeleted file mode 100644 index 7210c3d..0000000 --- a/ajax-broker/images/calendar_button.png +++ /dev/null diff --git a/ajax-broker/images/calendar_left.png b/ajax-broker/images/calendar_left.png Binary files differdeleted file mode 100644 index 42b97ab..0000000 --- a/ajax-broker/images/calendar_left.png +++ /dev/null diff --git a/ajax-broker/images/calendar_m_minus.png b/ajax-broker/images/calendar_m_minus.png Binary files differdeleted file mode 100644 index 90d6161..0000000 --- a/ajax-broker/images/calendar_m_minus.png +++ /dev/null diff --git a/ajax-broker/images/calendar_m_plus.png b/ajax-broker/images/calendar_m_plus.png Binary files differdeleted file mode 100644 index 4c7e9e4..0000000 --- a/ajax-broker/images/calendar_m_plus.png +++ /dev/null diff --git a/ajax-broker/images/calendar_y_minus.png b/ajax-broker/images/calendar_y_minus.png Binary files differdeleted file mode 100644 index 614f465..0000000 --- a/ajax-broker/images/calendar_y_minus.png +++ /dev/null diff --git a/ajax-broker/images/calendar_y_plus.png b/ajax-broker/images/calendar_y_plus.png Binary files differdeleted file mode 100644 index 6a4fe04..0000000 --- a/ajax-broker/images/calendar_y_plus.png +++ /dev/null diff --git a/ajax-broker/images/check.gif b/ajax-broker/images/check.gif Binary files differdeleted file mode 100644 index 3e2265b..0000000 --- a/ajax-broker/images/check.gif +++ /dev/null diff --git a/ajax-broker/images/checkbox.old.png b/ajax-broker/images/checkbox.old.png Binary files differdeleted file mode 100644 index 0ac1e10..0000000 --- a/ajax-broker/images/checkbox.old.png +++ /dev/null diff --git a/ajax-broker/images/checkbox.png b/ajax-broker/images/checkbox.png Binary files differdeleted file mode 100644 index f81e0b0..0000000 --- a/ajax-broker/images/checkbox.png +++ /dev/null diff --git a/ajax-broker/images/checkbox2.png b/ajax-broker/images/checkbox2.png Binary files differdeleted file mode 100644 index b827f9e..0000000 --- a/ajax-broker/images/checkbox2.png +++ /dev/null diff --git a/ajax-broker/images/checkbox3.png b/ajax-broker/images/checkbox3.png Binary files differdeleted file mode 100644 index 174cdd7..0000000 --- a/ajax-broker/images/checkbox3.png +++ /dev/null diff --git a/ajax-broker/images/close.png b/ajax-broker/images/close.png Binary files differdeleted file mode 100644 index 9be559a..0000000 --- a/ajax-broker/images/close.png +++ /dev/null diff --git a/ajax-broker/images/colorbox.png b/ajax-broker/images/colorbox.png Binary files differdeleted file mode 100644 index 3100ab3..0000000 --- a/ajax-broker/images/colorbox.png +++ /dev/null diff --git a/ajax-broker/images/column_picker.gif b/ajax-broker/images/column_picker.gif Binary files differdeleted file mode 100644 index 3ccdaa6..0000000 --- a/ajax-broker/images/column_picker.gif +++ /dev/null diff --git a/ajax-broker/images/copy.png b/ajax-broker/images/copy.png Binary files differdeleted file mode 100644 index f1a0c79..0000000 --- a/ajax-broker/images/copy.png +++ /dev/null diff --git a/ajax-broker/images/cut.png b/ajax-broker/images/cut.png Binary files differdeleted file mode 100644 index 4f8d6c8..0000000 --- a/ajax-broker/images/cut.png +++ /dev/null diff --git a/ajax-broker/images/dropdown.old.20081120.png b/ajax-broker/images/dropdown.old.20081120.png Binary files differdeleted file mode 100644 index 2e38ab7..0000000 --- a/ajax-broker/images/dropdown.old.20081120.png +++ /dev/null diff --git a/ajax-broker/images/dropdown.old.big.png b/ajax-broker/images/dropdown.old.big.png Binary files differdeleted file mode 100644 index fc8f615..0000000 --- a/ajax-broker/images/dropdown.old.big.png +++ /dev/null diff --git a/ajax-broker/images/dropdown.old.png b/ajax-broker/images/dropdown.old.png Binary files differdeleted file mode 100644 index d300bd7..0000000 --- a/ajax-broker/images/dropdown.old.png +++ /dev/null diff --git a/ajax-broker/images/dropdown.png b/ajax-broker/images/dropdown.png Binary files differdeleted file mode 100644 index 3695333..0000000 --- a/ajax-broker/images/dropdown.png +++ /dev/null diff --git a/ajax-broker/images/dropdown_background.png b/ajax-broker/images/dropdown_background.png Binary files differdeleted file mode 100644 index 50cde3b..0000000 --- a/ajax-broker/images/dropdown_background.png +++ /dev/null diff --git a/ajax-broker/images/dropdown_background2.png b/ajax-broker/images/dropdown_background2.png Binary files differdeleted file mode 100644 index 63c2a96..0000000 --- a/ajax-broker/images/dropdown_background2.png +++ /dev/null diff --git a/ajax-broker/images/dropdown_background_top.png b/ajax-broker/images/dropdown_background_top.png Binary files differdeleted file mode 100644 index c19c672..0000000 --- a/ajax-broker/images/dropdown_background_top.png +++ /dev/null diff --git a/ajax-broker/images/editor/Thumbs.db b/ajax-broker/images/editor/Thumbs.db Binary files differdeleted file mode 100644 index e1629f5..0000000 --- a/ajax-broker/images/editor/Thumbs.db +++ /dev/null diff --git a/ajax-broker/images/editor/Untitled-1.gif b/ajax-broker/images/editor/Untitled-1.gif Binary files differdeleted file mode 100644 index 1d9458c..0000000 --- a/ajax-broker/images/editor/Untitled-1.gif +++ /dev/null diff --git a/ajax-broker/images/editor/items.gif b/ajax-broker/images/editor/items.gif Binary files differdeleted file mode 100644 index 2eafd79..0000000 --- a/ajax-broker/images/editor/items.gif +++ /dev/null diff --git a/ajax-broker/images/editor/smiley-cool.gif b/ajax-broker/images/editor/smiley-cool.gif Binary files differdeleted file mode 100644 index ba90cc3..0000000 --- a/ajax-broker/images/editor/smiley-cool.gif +++ /dev/null diff --git a/ajax-broker/images/editor/smiley-cry.gif b/ajax-broker/images/editor/smiley-cry.gif Binary files differdeleted file mode 100644 index 74d897a..0000000 --- a/ajax-broker/images/editor/smiley-cry.gif +++ /dev/null diff --git a/ajax-broker/images/editor/smiley-embarassed.gif b/ajax-broker/images/editor/smiley-embarassed.gif Binary files differdeleted file mode 100644 index 963a96b..0000000 --- a/ajax-broker/images/editor/smiley-embarassed.gif +++ /dev/null diff --git a/ajax-broker/images/editor/smiley-foot-in-mouth.gif b/ajax-broker/images/editor/smiley-foot-in-mouth.gif Binary files differdeleted file mode 100644 index 16f68cc..0000000 --- a/ajax-broker/images/editor/smiley-foot-in-mouth.gif +++ /dev/null diff --git a/ajax-broker/images/editor/smiley-frown.gif b/ajax-broker/images/editor/smiley-frown.gif Binary files differdeleted file mode 100644 index 716f55e..0000000 --- a/ajax-broker/images/editor/smiley-frown.gif +++ /dev/null diff --git a/ajax-broker/images/editor/smiley-innocent.gif b/ajax-broker/images/editor/smiley-innocent.gif Binary files differdeleted file mode 100644 index 334d49e..0000000 --- a/ajax-broker/images/editor/smiley-innocent.gif +++ /dev/null diff --git a/ajax-broker/images/editor/smiley-kiss.gif b/ajax-broker/images/editor/smiley-kiss.gif Binary files differdeleted file mode 100644 index 4efd549..0000000 --- a/ajax-broker/images/editor/smiley-kiss.gif +++ /dev/null diff --git a/ajax-broker/images/editor/smiley-laughing.gif b/ajax-broker/images/editor/smiley-laughing.gif Binary files differdeleted file mode 100644 index 1606c11..0000000 --- a/ajax-broker/images/editor/smiley-laughing.gif +++ /dev/null diff --git a/ajax-broker/images/editor/smiley-money-mouth.gif b/ajax-broker/images/editor/smiley-money-mouth.gif Binary files differdeleted file mode 100644 index ca2451e..0000000 --- a/ajax-broker/images/editor/smiley-money-mouth.gif +++ /dev/null diff --git a/ajax-broker/images/editor/smiley-sealed.gif b/ajax-broker/images/editor/smiley-sealed.gif Binary files differdeleted file mode 100644 index b33d3cc..0000000 --- a/ajax-broker/images/editor/smiley-sealed.gif +++ /dev/null diff --git a/ajax-broker/images/editor/smiley-smile.gif b/ajax-broker/images/editor/smiley-smile.gif Binary files differdeleted file mode 100644 index e6a9e60..0000000 --- a/ajax-broker/images/editor/smiley-smile.gif +++ /dev/null diff --git a/ajax-broker/images/editor/smiley-surprised.gif b/ajax-broker/images/editor/smiley-surprised.gif Binary files differdeleted file mode 100644 index cb99cdd..0000000 --- a/ajax-broker/images/editor/smiley-surprised.gif +++ /dev/null diff --git a/ajax-broker/images/editor/smiley-tongue-out.gif b/ajax-broker/images/editor/smiley-tongue-out.gif Binary files differdeleted file mode 100644 index 2075dc1..0000000 --- a/ajax-broker/images/editor/smiley-tongue-out.gif +++ /dev/null diff --git a/ajax-broker/images/editor/smiley-undecided.gif b/ajax-broker/images/editor/smiley-undecided.gif Binary files differdeleted file mode 100644 index bef7e25..0000000 --- a/ajax-broker/images/editor/smiley-undecided.gif +++ /dev/null diff --git a/ajax-broker/images/editor/smiley-wink.gif b/ajax-broker/images/editor/smiley-wink.gif Binary files differdeleted file mode 100644 index 9faf1af..0000000 --- a/ajax-broker/images/editor/smiley-wink.gif +++ /dev/null diff --git a/ajax-broker/images/editor/smiley-yell.gif b/ajax-broker/images/editor/smiley-yell.gif Binary files differdeleted file mode 100644 index 648e6e8..0000000 --- a/ajax-broker/images/editor/smiley-yell.gif +++ /dev/null diff --git a/ajax-broker/images/editor/tablecell.gif b/ajax-broker/images/editor/tablecell.gif Binary files differdeleted file mode 100644 index c5933e4..0000000 --- a/ajax-broker/images/editor/tablecell.gif +++ /dev/null diff --git a/ajax-broker/images/editor/toolbar.icons.gif b/ajax-broker/images/editor/toolbar.icons.gif Binary files differdeleted file mode 100644 index ccac36f..0000000 --- a/ajax-broker/images/editor/toolbar.icons.gif +++ /dev/null diff --git a/ajax-broker/images/error_box_b.png b/ajax-broker/images/error_box_b.png Binary files differdeleted file mode 100644 index 4389c9e..0000000 --- a/ajax-broker/images/error_box_b.png +++ /dev/null diff --git a/ajax-broker/images/error_box_lb.png b/ajax-broker/images/error_box_lb.png Binary files differdeleted file mode 100644 index f42daff..0000000 --- a/ajax-broker/images/error_box_lb.png +++ /dev/null diff --git a/ajax-broker/images/error_box_lt.png b/ajax-broker/images/error_box_lt.png Binary files differdeleted file mode 100644 index e456957..0000000 --- a/ajax-broker/images/error_box_lt.png +++ /dev/null diff --git a/ajax-broker/images/error_box_r.png b/ajax-broker/images/error_box_r.png Binary files differdeleted file mode 100644 index f753c4f..0000000 --- a/ajax-broker/images/error_box_r.png +++ /dev/null diff --git a/ajax-broker/images/error_box_rb.png b/ajax-broker/images/error_box_rb.png Binary files differdeleted file mode 100644 index b973384..0000000 --- a/ajax-broker/images/error_box_rb.png +++ /dev/null diff --git a/ajax-broker/images/error_box_rt.png b/ajax-broker/images/error_box_rt.png Binary files differdeleted file mode 100644 index 3c05e73..0000000 --- a/ajax-broker/images/error_box_rt.png +++ /dev/null diff --git a/ajax-broker/images/errorbox_backg.png b/ajax-broker/images/errorbox_backg.png Binary files differdeleted file mode 100644 index ce77d71..0000000 --- a/ajax-broker/images/errorbox_backg.png +++ /dev/null diff --git a/ajax-broker/images/errorbox_bottom.png b/ajax-broker/images/errorbox_bottom.png Binary files differdeleted file mode 100644 index 15e1aa6..0000000 --- a/ajax-broker/images/errorbox_bottom.png +++ /dev/null diff --git a/ajax-broker/images/errorbox_top.old.png b/ajax-broker/images/errorbox_top.old.png Binary files differdeleted file mode 100644 index 0fad969..0000000 --- a/ajax-broker/images/errorbox_top.old.png +++ /dev/null diff --git a/ajax-broker/images/errorbox_top.png b/ajax-broker/images/errorbox_top.png Binary files differdeleted file mode 100644 index c935a05..0000000 --- a/ajax-broker/images/errorbox_top.png +++ /dev/null diff --git a/ajax-broker/images/excel.cur b/ajax-broker/images/excel.cur Binary files differdeleted file mode 100644 index 78a94fd..0000000 --- a/ajax-broker/images/excel.cur +++ /dev/null diff --git a/ajax-broker/images/file.png b/ajax-broker/images/file.png Binary files differdeleted file mode 100644 index 915603e..0000000 --- a/ajax-broker/images/file.png +++ /dev/null diff --git a/ajax-broker/images/fullscreen.gif b/ajax-broker/images/fullscreen.gif Binary files differdeleted file mode 100644 index 130137c..0000000 --- a/ajax-broker/images/fullscreen.gif +++ /dev/null diff --git a/ajax-broker/images/fullscreen_restore.gif b/ajax-broker/images/fullscreen_restore.gif Binary files differdeleted file mode 100644 index e4f4e91..0000000 --- a/ajax-broker/images/fullscreen_restore.gif +++ /dev/null diff --git a/ajax-broker/images/girl.png b/ajax-broker/images/girl.png Binary files differdeleted file mode 100644 index fb3c173..0000000 --- a/ajax-broker/images/girl.png +++ /dev/null diff --git a/ajax-broker/images/growl_lb.gif b/ajax-broker/images/growl_lb.gif Binary files differdeleted file mode 100644 index 9c65355..0000000 --- a/ajax-broker/images/growl_lb.gif +++ /dev/null diff --git a/ajax-broker/images/growl_lt.gif b/ajax-broker/images/growl_lt.gif Binary files differdeleted file mode 100644 index 3fe8232..0000000 --- a/ajax-broker/images/growl_lt.gif +++ /dev/null diff --git a/ajax-broker/images/growl_rb.gif b/ajax-broker/images/growl_rb.gif Binary files differdeleted file mode 100644 index ef7ecac..0000000 --- a/ajax-broker/images/growl_rb.gif +++ /dev/null diff --git a/ajax-broker/images/growl_rt.gif b/ajax-broker/images/growl_rt.gif Binary files differdeleted file mode 100644 index e0bd7c0..0000000 --- a/ajax-broker/images/growl_rt.gif +++ /dev/null diff --git a/ajax-broker/images/icons/bullet_key.png b/ajax-broker/images/icons/bullet_key.png Binary files differdeleted file mode 100644 index 3d37f2e..0000000 --- a/ajax-broker/images/icons/bullet_key.png +++ /dev/null diff --git a/ajax-broker/images/input.png b/ajax-broker/images/input.png Binary files differdeleted file mode 100644 index 660bbd6..0000000 --- a/ajax-broker/images/input.png +++ /dev/null diff --git a/ajax-broker/images/input_background.png b/ajax-broker/images/input_background.png Binary files differdeleted file mode 100644 index bcc3eb0..0000000 --- a/ajax-broker/images/input_background.png +++ /dev/null diff --git a/ajax-broker/images/input_border.png b/ajax-broker/images/input_border.png Binary files differdeleted file mode 100644 index e3c9ab6..0000000 --- a/ajax-broker/images/input_border.png +++ /dev/null diff --git a/ajax-broker/images/input_border_lr.png b/ajax-broker/images/input_border_lr.png Binary files differdeleted file mode 100644 index e7830ae..0000000 --- a/ajax-broker/images/input_border_lr.png +++ /dev/null diff --git a/ajax-broker/images/input_border_tb.png b/ajax-broker/images/input_border_tb.png Binary files differdeleted file mode 100644 index d13b388..0000000 --- a/ajax-broker/images/input_border_tb.png +++ /dev/null diff --git a/ajax-broker/images/input_error_background.gif b/ajax-broker/images/input_error_background.gif Binary files differdeleted file mode 100644 index afc4561..0000000 --- a/ajax-broker/images/input_error_background.gif +++ /dev/null diff --git a/ajax-broker/images/input_error_background2.gif b/ajax-broker/images/input_error_background2.gif Binary files differdeleted file mode 100644 index f2165ac..0000000 --- a/ajax-broker/images/input_error_background2.gif +++ /dev/null diff --git a/ajax-broker/images/italic.png b/ajax-broker/images/italic.png Binary files differdeleted file mode 100644 index a225d08..0000000 --- a/ajax-broker/images/italic.png +++ /dev/null diff --git a/ajax-broker/images/label_hover.png b/ajax-broker/images/label_hover.png Binary files differdeleted file mode 100644 index 6beb124..0000000 --- a/ajax-broker/images/label_hover.png +++ /dev/null diff --git a/ajax-broker/images/label_hover_bb.png b/ajax-broker/images/label_hover_bb.png Binary files differdeleted file mode 100644 index 613d8b5..0000000 --- a/ajax-broker/images/label_hover_bb.png +++ /dev/null diff --git a/ajax-broker/images/label_hover_br.png b/ajax-broker/images/label_hover_br.png Binary files differdeleted file mode 100644 index 3823849..0000000 --- a/ajax-broker/images/label_hover_br.png +++ /dev/null diff --git a/ajax-broker/images/label_hover_lb.png b/ajax-broker/images/label_hover_lb.png Binary files differdeleted file mode 100644 index 8f88e01..0000000 --- a/ajax-broker/images/label_hover_lb.png +++ /dev/null diff --git a/ajax-broker/images/mediabtn.png b/ajax-broker/images/mediabtn.png Binary files differdeleted file mode 100644 index 55b5492..0000000 --- a/ajax-broker/images/mediabtn.png +++ /dev/null diff --git a/ajax-broker/images/mediabtn2.png b/ajax-broker/images/mediabtn2.png Binary files differdeleted file mode 100644 index 80373db..0000000 --- a/ajax-broker/images/mediabtn2.png +++ /dev/null diff --git a/ajax-broker/images/menu_context_left.gif b/ajax-broker/images/menu_context_left.gif Binary files differdeleted file mode 100644 index 74c8ff6..0000000 --- a/ajax-broker/images/menu_context_left.gif +++ /dev/null diff --git a/ajax-broker/images/menu_context_left_over.gif b/ajax-broker/images/menu_context_left_over.gif Binary files differdeleted file mode 100644 index 2590f3e..0000000 --- a/ajax-broker/images/menu_context_left_over.gif +++ /dev/null diff --git a/ajax-broker/images/menu_context_right.gif b/ajax-broker/images/menu_context_right.gif Binary files differdeleted file mode 100644 index 25d0625..0000000 --- a/ajax-broker/images/menu_context_right.gif +++ /dev/null diff --git a/ajax-broker/images/menu_context_right_over.gif b/ajax-broker/images/menu_context_right_over.gif Binary files differdeleted file mode 100644 index 85ec005..0000000 --- a/ajax-broker/images/menu_context_right_over.gif +++ /dev/null diff --git a/ajax-broker/images/menu_context_shadow_b.png b/ajax-broker/images/menu_context_shadow_b.png Binary files differdeleted file mode 100644 index a4a284a..0000000 --- a/ajax-broker/images/menu_context_shadow_b.png +++ /dev/null diff --git a/ajax-broker/images/menu_context_shadow_corner.png b/ajax-broker/images/menu_context_shadow_corner.png Binary files differdeleted file mode 100644 index f8afa70..0000000 --- a/ajax-broker/images/menu_context_shadow_corner.png +++ /dev/null diff --git a/ajax-broker/images/menu_context_shadow_lat.png b/ajax-broker/images/menu_context_shadow_lat.png Binary files differdeleted file mode 100644 index 5fe7e6a..0000000 --- a/ajax-broker/images/menu_context_shadow_lat.png +++ /dev/null diff --git a/ajax-broker/images/menu_context_shadow_lt.png b/ajax-broker/images/menu_context_shadow_lt.png Binary files differdeleted file mode 100644 index 878eacf..0000000 --- a/ajax-broker/images/menu_context_shadow_lt.png +++ /dev/null diff --git a/ajax-broker/images/menu_context_shadow_r.png b/ajax-broker/images/menu_context_shadow_r.png Binary files differdeleted file mode 100644 index 7865b93..0000000 --- a/ajax-broker/images/menu_context_shadow_r.png +++ /dev/null diff --git a/ajax-broker/images/menu_context_shb.png b/ajax-broker/images/menu_context_shb.png Binary files differdeleted file mode 100644 index 2a81f8c..0000000 --- a/ajax-broker/images/menu_context_shb.png +++ /dev/null diff --git a/ajax-broker/images/menu_context_shl.png b/ajax-broker/images/menu_context_shl.png Binary files differdeleted file mode 100644 index 6db4763..0000000 --- a/ajax-broker/images/menu_context_shl.png +++ /dev/null diff --git a/ajax-broker/images/menu_context_shlr.png b/ajax-broker/images/menu_context_shlr.png Binary files differdeleted file mode 100644 index a43a97e..0000000 --- a/ajax-broker/images/menu_context_shlr.png +++ /dev/null diff --git a/ajax-broker/images/menu_context_shr.png b/ajax-broker/images/menu_context_shr.png Binary files differdeleted file mode 100644 index 9cfcdb1..0000000 --- a/ajax-broker/images/menu_context_shr.png +++ /dev/null diff --git a/ajax-broker/images/menu_context_shtb.png b/ajax-broker/images/menu_context_shtb.png Binary files differdeleted file mode 100644 index d3df410..0000000 --- a/ajax-broker/images/menu_context_shtb.png +++ /dev/null diff --git a/ajax-broker/images/menu_down.gif b/ajax-broker/images/menu_down.gif Binary files differdeleted file mode 100644 index f6c42ad..0000000 --- a/ajax-broker/images/menu_down.gif +++ /dev/null diff --git a/ajax-broker/images/menu_over.gif b/ajax-broker/images/menu_over.gif Binary files differdeleted file mode 100644 index 204e7ee..0000000 --- a/ajax-broker/images/menu_over.gif +++ /dev/null diff --git a/ajax-broker/images/menu_tab_header.png b/ajax-broker/images/menu_tab_header.png Binary files differdeleted file mode 100644 index 508085b..0000000 --- a/ajax-broker/images/menu_tab_header.png +++ /dev/null diff --git a/ajax-broker/images/menu_tab_row.png b/ajax-broker/images/menu_tab_row.png Binary files differdeleted file mode 100644 index 65b5e90..0000000 --- a/ajax-broker/images/menu_tab_row.png +++ /dev/null diff --git a/ajax-broker/images/menu_win_background.png b/ajax-broker/images/menu_win_background.png Binary files differdeleted file mode 100644 index a401117..0000000 --- a/ajax-broker/images/menu_win_background.png +++ /dev/null diff --git a/ajax-broker/images/menu_win_bottom.png b/ajax-broker/images/menu_win_bottom.png Binary files differdeleted file mode 100644 index 1cff25c..0000000 --- a/ajax-broker/images/menu_win_bottom.png +++ /dev/null diff --git a/ajax-broker/images/menu_win_l.png b/ajax-broker/images/menu_win_l.png Binary files differdeleted file mode 100644 index 53579fb..0000000 --- a/ajax-broker/images/menu_win_l.png +++ /dev/null diff --git a/ajax-broker/images/menu_win_r.png b/ajax-broker/images/menu_win_r.png Binary files differdeleted file mode 100644 index 73ee80e..0000000 --- a/ajax-broker/images/menu_win_r.png +++ /dev/null diff --git a/ajax-broker/images/menubar_row.png b/ajax-broker/images/menubar_row.png Binary files differdeleted file mode 100644 index 7e7a0d4..0000000 --- a/ajax-broker/images/menubar_row.png +++ /dev/null diff --git a/ajax-broker/images/min.png b/ajax-broker/images/min.png Binary files differdeleted file mode 100644 index 149af84..0000000 --- a/ajax-broker/images/min.png +++ /dev/null diff --git a/ajax-broker/images/new_cal.jpg b/ajax-broker/images/new_cal.jpg Binary files differdeleted file mode 100644 index 5e8a663..0000000 --- a/ajax-broker/images/new_cal.jpg +++ /dev/null diff --git a/ajax-broker/images/new_cal_big.jpg b/ajax-broker/images/new_cal_big.jpg Binary files differdeleted file mode 100644 index 6bfdc8a..0000000 --- a/ajax-broker/images/new_cal_big.jpg +++ /dev/null diff --git a/ajax-broker/images/new_cal_hov.jpg b/ajax-broker/images/new_cal_hov.jpg Binary files differdeleted file mode 100644 index ce68537..0000000 --- a/ajax-broker/images/new_cal_hov.jpg +++ /dev/null diff --git a/ajax-broker/images/new_cal_hov_big.jpg b/ajax-broker/images/new_cal_hov_big.jpg Binary files differdeleted file mode 100644 index a312c5e..0000000 --- a/ajax-broker/images/new_cal_hov_big.jpg +++ /dev/null diff --git a/ajax-broker/images/new_cal_sel.jpg b/ajax-broker/images/new_cal_sel.jpg Binary files differdeleted file mode 100644 index da180d8..0000000 --- a/ajax-broker/images/new_cal_sel.jpg +++ /dev/null diff --git a/ajax-broker/images/new_cal_sel_big.jpg b/ajax-broker/images/new_cal_sel_big.jpg Binary files differdeleted file mode 100644 index 4dcca12..0000000 --- a/ajax-broker/images/new_cal_sel_big.jpg +++ /dev/null diff --git a/ajax-broker/images/page_bt.png b/ajax-broker/images/page_bt.png Binary files differdeleted file mode 100644 index 924577f..0000000 --- a/ajax-broker/images/page_bt.png +++ /dev/null diff --git a/ajax-broker/images/paste.png b/ajax-broker/images/paste.png Binary files differdeleted file mode 100644 index 6a14104..0000000 --- a/ajax-broker/images/paste.png +++ /dev/null diff --git a/ajax-broker/images/pause.gif b/ajax-broker/images/pause.gif Binary files differdeleted file mode 100644 index be0568b..0000000 --- a/ajax-broker/images/pause.gif +++ /dev/null diff --git a/ajax-broker/images/pause.png b/ajax-broker/images/pause.png Binary files differdeleted file mode 100644 index b35b8e2..0000000 --- a/ajax-broker/images/pause.png +++ /dev/null diff --git a/ajax-broker/images/pause2.png b/ajax-broker/images/pause2.png Binary files differdeleted file mode 100644 index 9252906..0000000 --- a/ajax-broker/images/pause2.png +++ /dev/null diff --git a/ajax-broker/images/play.gif b/ajax-broker/images/play.gif Binary files differdeleted file mode 100644 index e3dbc3b..0000000 --- a/ajax-broker/images/play.gif +++ /dev/null diff --git a/ajax-broker/images/play.png b/ajax-broker/images/play.png Binary files differdeleted file mode 100644 index 4b93b1b..0000000 --- a/ajax-broker/images/play.png +++ /dev/null diff --git a/ajax-broker/images/play2.png b/ajax-broker/images/play2.png Binary files differdeleted file mode 100644 index b396956..0000000 --- a/ajax-broker/images/play2.png +++ /dev/null diff --git a/ajax-broker/images/plus.png b/ajax-broker/images/plus.png Binary files differdeleted file mode 100644 index 679b819..0000000 --- a/ajax-broker/images/plus.png +++ /dev/null diff --git a/ajax-broker/images/plusplain.gif b/ajax-broker/images/plusplain.gif Binary files differdeleted file mode 100644 index 6b94ac5..0000000 --- a/ajax-broker/images/plusplain.gif +++ /dev/null diff --git a/ajax-broker/images/preloader_small.gif b/ajax-broker/images/preloader_small.gif Binary files differdeleted file mode 100644 index 9cd0af1..0000000 --- a/ajax-broker/images/preloader_small.gif +++ /dev/null diff --git a/ajax-broker/images/progressbar.old.png b/ajax-broker/images/progressbar.old.png Binary files differdeleted file mode 100644 index 71a5041..0000000 --- a/ajax-broker/images/progressbar.old.png +++ /dev/null diff --git a/ajax-broker/images/progressbar.png b/ajax-broker/images/progressbar.png Binary files differdeleted file mode 100644 index 0a41957..0000000 --- a/ajax-broker/images/progressbar.png +++ /dev/null diff --git a/ajax-broker/images/radio.gif b/ajax-broker/images/radio.gif Binary files differdeleted file mode 100644 index 96dd397..0000000 --- a/ajax-broker/images/radio.gif +++ /dev/null diff --git a/ajax-broker/images/radio.png b/ajax-broker/images/radio.png Binary files differdeleted file mode 100644 index 0c26736..0000000 --- a/ajax-broker/images/radio.png +++ /dev/null diff --git a/ajax-broker/images/redo.png b/ajax-broker/images/redo.png Binary files differdeleted file mode 100644 index ebe1447..0000000 --- a/ajax-broker/images/redo.png +++ /dev/null diff --git a/ajax-broker/images/resizehandle.gif b/ajax-broker/images/resizehandle.gif Binary files differdeleted file mode 100644 index d54fa78..0000000 --- a/ajax-broker/images/resizehandle.gif +++ /dev/null diff --git a/ajax-broker/images/rightclickmenu_background.png b/ajax-broker/images/rightclickmenu_background.png Binary files differdeleted file mode 100644 index 9a02e18..0000000 --- a/ajax-broker/images/rightclickmenu_background.png +++ /dev/null diff --git a/ajax-broker/images/rightclickmenu_bottom.png b/ajax-broker/images/rightclickmenu_bottom.png Binary files differdeleted file mode 100644 index 9585b87..0000000 --- a/ajax-broker/images/rightclickmenu_bottom.png +++ /dev/null diff --git a/ajax-broker/images/rightclickmenu_top.png b/ajax-broker/images/rightclickmenu_top.png Binary files differdeleted file mode 100644 index b51256c..0000000 --- a/ajax-broker/images/rightclickmenu_top.png +++ /dev/null diff --git a/ajax-broker/images/rslider16x.png b/ajax-broker/images/rslider16x.png Binary files differdeleted file mode 100644 index 4ddd394..0000000 --- a/ajax-broker/images/rslider16x.png +++ /dev/null diff --git a/ajax-broker/images/searchResultHover.png b/ajax-broker/images/searchResultHover.png Binary files differdeleted file mode 100644 index d64bb66..0000000 --- a/ajax-broker/images/searchResultHover.png +++ /dev/null diff --git a/ajax-broker/images/searchResultsBody.png b/ajax-broker/images/searchResultsBody.png Binary files differdeleted file mode 100644 index 4b2f5e5..0000000 --- a/ajax-broker/images/searchResultsBody.png +++ /dev/null diff --git a/ajax-broker/images/searchResultsFooter.png b/ajax-broker/images/searchResultsFooter.png Binary files differdeleted file mode 100644 index 0abe191..0000000 --- a/ajax-broker/images/searchResultsFooter.png +++ /dev/null diff --git a/ajax-broker/images/searchResultsHeader.png b/ajax-broker/images/searchResultsHeader.png Binary files differdeleted file mode 100644 index 3a176a5..0000000 --- a/ajax-broker/images/searchResultsHeader.png +++ /dev/null diff --git a/ajax-broker/images/searchResultsTitle.png b/ajax-broker/images/searchResultsTitle.png Binary files differdeleted file mode 100644 index 9e5c285..0000000 --- a/ajax-broker/images/searchResultsTitle.png +++ /dev/null diff --git a/ajax-broker/images/sectionhead.gif b/ajax-broker/images/sectionhead.gif Binary files differdeleted file mode 100644 index a716883..0000000 --- a/ajax-broker/images/sectionhead.gif +++ /dev/null diff --git a/ajax-broker/images/sectionheadactive.gif b/ajax-broker/images/sectionheadactive.gif Binary files differdeleted file mode 100644 index 6534552..0000000 --- a/ajax-broker/images/sectionheadactive.gif +++ /dev/null diff --git a/ajax-broker/images/segment.jpg b/ajax-broker/images/segment.jpg Binary files differdeleted file mode 100644 index dd9b2e3..0000000 --- a/ajax-broker/images/segment.jpg +++ /dev/null diff --git a/ajax-broker/images/segment_active.jpg b/ajax-broker/images/segment_active.jpg Binary files differdeleted file mode 100644 index 4f502e4..0000000 --- a/ajax-broker/images/segment_active.jpg +++ /dev/null diff --git a/ajax-broker/images/segment_hover.jpg b/ajax-broker/images/segment_hover.jpg Binary files differdeleted file mode 100644 index 6556b0a..0000000 --- a/ajax-broker/images/segment_hover.jpg +++ /dev/null diff --git a/ajax-broker/images/segment_weekend.jpg b/ajax-broker/images/segment_weekend.jpg Binary files differdeleted file mode 100644 index 87b9f9f..0000000 --- a/ajax-broker/images/segment_weekend.jpg +++ /dev/null diff --git a/ajax-broker/images/skin.jpg b/ajax-broker/images/skin.jpg Binary files differdeleted file mode 100644 index c2e5d35..0000000 --- a/ajax-broker/images/skin.jpg +++ /dev/null diff --git a/ajax-broker/images/slider.png b/ajax-broker/images/slider.png Binary files differdeleted file mode 100644 index 21826fb..0000000 --- a/ajax-broker/images/slider.png +++ /dev/null diff --git a/ajax-broker/images/slider11x.png b/ajax-broker/images/slider11x.png Binary files differdeleted file mode 100644 index 674bdce..0000000 --- a/ajax-broker/images/slider11x.png +++ /dev/null diff --git a/ajax-broker/images/slider11x_high.png b/ajax-broker/images/slider11x_high.png Binary files differdeleted file mode 100644 index e8f2ff9..0000000 --- a/ajax-broker/images/slider11x_high.png +++ /dev/null diff --git a/ajax-broker/images/slider16x.png b/ajax-broker/images/slider16x.png Binary files differdeleted file mode 100644 index dc96942..0000000 --- a/ajax-broker/images/slider16x.png +++ /dev/null diff --git a/ajax-broker/images/slider16x_high.png b/ajax-broker/images/slider16x_high.png Binary files differdeleted file mode 100644 index 88312ea..0000000 --- a/ajax-broker/images/slider16x_high.png +++ /dev/null diff --git a/ajax-broker/images/slider2.png b/ajax-broker/images/slider2.png Binary files differdeleted file mode 100644 index 85c1164..0000000 --- a/ajax-broker/images/slider2.png +++ /dev/null diff --git a/ajax-broker/images/slider3.png b/ajax-broker/images/slider3.png Binary files differdeleted file mode 100644 index 9da9eff..0000000 --- a/ajax-broker/images/slider3.png +++ /dev/null diff --git a/ajax-broker/images/slideshow_next.png b/ajax-broker/images/slideshow_next.png Binary files differdeleted file mode 100644 index a362fa8..0000000 --- a/ajax-broker/images/slideshow_next.png +++ /dev/null diff --git a/ajax-broker/images/slideshow_play.png b/ajax-broker/images/slideshow_play.png Binary files differdeleted file mode 100644 index 8f3bfb7..0000000 --- a/ajax-broker/images/slideshow_play.png +++ /dev/null diff --git a/ajax-broker/images/slideshow_previous.png b/ajax-broker/images/slideshow_previous.png Binary files differdeleted file mode 100644 index b7f71f9..0000000 --- a/ajax-broker/images/slideshow_previous.png +++ /dev/null diff --git a/ajax-broker/images/slideshow_stop.png b/ajax-broker/images/slideshow_stop.png Binary files differdeleted file mode 100644 index 4e95036..0000000 --- a/ajax-broker/images/slideshow_stop.png +++ /dev/null diff --git a/ajax-broker/images/smoke_lb.gif b/ajax-broker/images/smoke_lb.gif Binary files differdeleted file mode 100644 index 8fe0b1e..0000000 --- a/ajax-broker/images/smoke_lb.gif +++ /dev/null diff --git a/ajax-broker/images/smoke_lt.gif b/ajax-broker/images/smoke_lt.gif Binary files differdeleted file mode 100644 index 7bfeaa8..0000000 --- a/ajax-broker/images/smoke_lt.gif +++ /dev/null diff --git a/ajax-broker/images/smoke_rb.gif b/ajax-broker/images/smoke_rb.gif Binary files differdeleted file mode 100644 index 323dd4b..0000000 --- a/ajax-broker/images/smoke_rb.gif +++ /dev/null diff --git a/ajax-broker/images/smoke_rt.gif b/ajax-broker/images/smoke_rt.gif Binary files differdeleted file mode 100644 index 8fc4212..0000000 --- a/ajax-broker/images/smoke_rt.gif +++ /dev/null diff --git a/ajax-broker/images/sort_asc.gif b/ajax-broker/images/sort_asc.gif Binary files differdeleted file mode 100644 index 2d1e96f..0000000 --- a/ajax-broker/images/sort_asc.gif +++ /dev/null diff --git a/ajax-broker/images/sort_desc.gif b/ajax-broker/images/sort_desc.gif Binary files differdeleted file mode 100644 index 38bd59c..0000000 --- a/ajax-broker/images/sort_desc.gif +++ /dev/null diff --git a/ajax-broker/images/spinner_body.png b/ajax-broker/images/spinner_body.png Binary files differdeleted file mode 100644 index d85bc31..0000000 --- a/ajax-broker/images/spinner_body.png +++ /dev/null diff --git a/ajax-broker/images/spinner_body2.png b/ajax-broker/images/spinner_body2.png Binary files differdeleted file mode 100644 index 5410314..0000000 --- a/ajax-broker/images/spinner_body2.png +++ /dev/null diff --git a/ajax-broker/images/spinner_left.png b/ajax-broker/images/spinner_left.png Binary files differdeleted file mode 100644 index ce2bfb3..0000000 --- a/ajax-broker/images/spinner_left.png +++ /dev/null diff --git a/ajax-broker/images/spinner_minus.png b/ajax-broker/images/spinner_minus.png Binary files differdeleted file mode 100644 index d87f23f..0000000 --- a/ajax-broker/images/spinner_minus.png +++ /dev/null diff --git a/ajax-broker/images/spinner_plus.png b/ajax-broker/images/spinner_plus.png Binary files differdeleted file mode 100644 index 9dca346..0000000 --- a/ajax-broker/images/spinner_plus.png +++ /dev/null diff --git a/ajax-broker/images/splitter_docs.gif b/ajax-broker/images/splitter_docs.gif Binary files differdeleted file mode 100644 index 340a390..0000000 --- a/ajax-broker/images/splitter_docs.gif +++ /dev/null diff --git a/ajax-broker/images/splitter_handle_horizontal.gif b/ajax-broker/images/splitter_handle_horizontal.gif Binary files differdeleted file mode 100644 index 38bdcef..0000000 --- a/ajax-broker/images/splitter_handle_horizontal.gif +++ /dev/null diff --git a/ajax-broker/images/splitter_handle_vertical.gif b/ajax-broker/images/splitter_handle_vertical.gif Binary files differdeleted file mode 100644 index 8b1ee9d..0000000 --- a/ajax-broker/images/splitter_handle_vertical.gif +++ /dev/null diff --git a/ajax-broker/images/statusbar.gif b/ajax-broker/images/statusbar.gif Binary files differdeleted file mode 100644 index d81b142..0000000 --- a/ajax-broker/images/statusbar.gif +++ /dev/null diff --git a/ajax-broker/images/stop.png b/ajax-broker/images/stop.png Binary files differdeleted file mode 100644 index d1abe69..0000000 --- a/ajax-broker/images/stop.png +++ /dev/null diff --git a/ajax-broker/images/submenu_arrow.gif b/ajax-broker/images/submenu_arrow.gif Binary files differdeleted file mode 100644 index 7b086fb..0000000 --- a/ajax-broker/images/submenu_arrow.gif +++ /dev/null diff --git a/ajax-broker/images/tab_but_bottomleft.old.png b/ajax-broker/images/tab_but_bottomleft.old.png Binary files differdeleted file mode 100644 index 567fdba..0000000 --- a/ajax-broker/images/tab_but_bottomleft.old.png +++ /dev/null diff --git a/ajax-broker/images/tab_but_bottomleft.png b/ajax-broker/images/tab_but_bottomleft.png Binary files differdeleted file mode 100644 index 62e184a..0000000 --- a/ajax-broker/images/tab_but_bottomleft.png +++ /dev/null diff --git a/ajax-broker/images/tab_but_bottomright.old.png b/ajax-broker/images/tab_but_bottomright.old.png Binary files differdeleted file mode 100644 index 0def6be..0000000 --- a/ajax-broker/images/tab_but_bottomright.old.png +++ /dev/null diff --git a/ajax-broker/images/tab_but_bottomright.png b/ajax-broker/images/tab_but_bottomright.png Binary files differdeleted file mode 100644 index f0b6c04..0000000 --- a/ajax-broker/images/tab_but_bottomright.png +++ /dev/null diff --git a/ajax-broker/images/tab_but_l.png b/ajax-broker/images/tab_but_l.png Binary files differdeleted file mode 100644 index 68999fb..0000000 --- a/ajax-broker/images/tab_but_l.png +++ /dev/null diff --git a/ajax-broker/images/tab_but_lb.png b/ajax-broker/images/tab_but_lb.png Binary files differdeleted file mode 100644 index 582162f..0000000 --- a/ajax-broker/images/tab_but_lb.png +++ /dev/null diff --git a/ajax-broker/images/tab_but_lt.png b/ajax-broker/images/tab_but_lt.png Binary files differdeleted file mode 100644 index 8f33e47..0000000 --- a/ajax-broker/images/tab_but_lt.png +++ /dev/null diff --git a/ajax-broker/images/tab_but_m.png b/ajax-broker/images/tab_but_m.png Binary files differdeleted file mode 100644 index f91e16d..0000000 --- a/ajax-broker/images/tab_but_m.png +++ /dev/null diff --git a/ajax-broker/images/tab_but_mb.png b/ajax-broker/images/tab_but_mb.png Binary files differdeleted file mode 100644 index 1aad805..0000000 --- a/ajax-broker/images/tab_but_mb.png +++ /dev/null diff --git a/ajax-broker/images/tab_but_mt.png b/ajax-broker/images/tab_but_mt.png Binary files differdeleted file mode 100644 index 186c411..0000000 --- a/ajax-broker/images/tab_but_mt.png +++ /dev/null diff --git a/ajax-broker/images/tab_but_r.png b/ajax-broker/images/tab_but_r.png Binary files differdeleted file mode 100644 index 174621b..0000000 --- a/ajax-broker/images/tab_but_r.png +++ /dev/null diff --git a/ajax-broker/images/tab_but_rb.png b/ajax-broker/images/tab_but_rb.png Binary files differdeleted file mode 100644 index 0def6be..0000000 --- a/ajax-broker/images/tab_but_rb.png +++ /dev/null diff --git a/ajax-broker/images/tab_but_rt.png b/ajax-broker/images/tab_but_rt.png Binary files differdeleted file mode 100644 index 0b91026..0000000 --- a/ajax-broker/images/tab_but_rt.png +++ /dev/null diff --git a/ajax-broker/images/tab_but_top.png b/ajax-broker/images/tab_but_top.png Binary files differdeleted file mode 100644 index 7a62b3b..0000000 --- a/ajax-broker/images/tab_but_top.png +++ /dev/null diff --git a/ajax-broker/images/tab_but_topleft.old.png b/ajax-broker/images/tab_but_topleft.old.png Binary files differdeleted file mode 100644 index ff4a57b..0000000 --- a/ajax-broker/images/tab_but_topleft.old.png +++ /dev/null diff --git a/ajax-broker/images/tab_but_topleft.png b/ajax-broker/images/tab_but_topleft.png Binary files differdeleted file mode 100644 index 6718b38..0000000 --- a/ajax-broker/images/tab_but_topleft.png +++ /dev/null diff --git a/ajax-broker/images/tab_but_topright.old.png b/ajax-broker/images/tab_but_topright.old.png Binary files differdeleted file mode 100644 index 0b91026..0000000 --- a/ajax-broker/images/tab_but_topright.old.png +++ /dev/null diff --git a/ajax-broker/images/tab_but_topright.png b/ajax-broker/images/tab_but_topright.png Binary files differdeleted file mode 100644 index a179f9f..0000000 --- a/ajax-broker/images/tab_but_topright.png +++ /dev/null diff --git a/ajax-broker/images/tab_next.gif b/ajax-broker/images/tab_next.gif Binary files differdeleted file mode 100644 index c5453a9..0000000 --- a/ajax-broker/images/tab_next.gif +++ /dev/null diff --git a/ajax-broker/images/tab_next_blink.gif b/ajax-broker/images/tab_next_blink.gif Binary files differdeleted file mode 100644 index 43ed71c..0000000 --- a/ajax-broker/images/tab_next_blink.gif +++ /dev/null diff --git a/ajax-broker/images/tab_pag_lb.png b/ajax-broker/images/tab_pag_lb.png Binary files differdeleted file mode 100644 index 2c49fd9..0000000 --- a/ajax-broker/images/tab_pag_lb.png +++ /dev/null diff --git a/ajax-broker/images/tab_pag_rb.png b/ajax-broker/images/tab_pag_rb.png Binary files differdeleted file mode 100644 index cac2e12..0000000 --- a/ajax-broker/images/tab_pag_rb.png +++ /dev/null diff --git a/ajax-broker/images/tab_prev.gif b/ajax-broker/images/tab_prev.gif Binary files differdeleted file mode 100644 index 7f3a19b..0000000 --- a/ajax-broker/images/tab_prev.gif +++ /dev/null diff --git a/ajax-broker/images/tab_prev_blink.gif b/ajax-broker/images/tab_prev_blink.gif Binary files differdeleted file mode 100644 index fc390e4..0000000 --- a/ajax-broker/images/tab_prev_blink.gif +++ /dev/null diff --git a/ajax-broker/images/textarea_background.png b/ajax-broker/images/textarea_background.png Binary files differdeleted file mode 100644 index cc635d5..0000000 --- a/ajax-broker/images/textarea_background.png +++ /dev/null diff --git a/ajax-broker/images/textarea_background2.png b/ajax-broker/images/textarea_background2.png Binary files differdeleted file mode 100644 index 6053f4d..0000000 --- a/ajax-broker/images/textarea_background2.png +++ /dev/null diff --git a/ajax-broker/images/textarea_background_left.png b/ajax-broker/images/textarea_background_left.png Binary files differdeleted file mode 100644 index f63acc9..0000000 --- a/ajax-broker/images/textarea_background_left.png +++ /dev/null diff --git a/ajax-broker/images/textarea_background_top.png b/ajax-broker/images/textarea_background_top.png Binary files differdeleted file mode 100644 index 698f577..0000000 --- a/ajax-broker/images/textarea_background_top.png +++ /dev/null diff --git a/ajax-broker/images/toolbar.icons.gif b/ajax-broker/images/toolbar.icons.gif Binary files differdeleted file mode 100644 index ccac36f..0000000 --- a/ajax-broker/images/toolbar.icons.gif +++ /dev/null diff --git a/ajax-broker/images/toolbar_a_down.png b/ajax-broker/images/toolbar_a_down.png Binary files differdeleted file mode 100644 index ab368f6..0000000 --- a/ajax-broker/images/toolbar_a_down.png +++ /dev/null diff --git a/ajax-broker/images/toolbar_a_down_right.png b/ajax-broker/images/toolbar_a_down_right.png Binary files differdeleted file mode 100644 index 22d68ff..0000000 --- a/ajax-broker/images/toolbar_a_down_right.png +++ /dev/null diff --git a/ajax-broker/images/toolbar_a_hover.png b/ajax-broker/images/toolbar_a_hover.png Binary files differdeleted file mode 100644 index a24146a..0000000 --- a/ajax-broker/images/toolbar_a_hover.png +++ /dev/null diff --git a/ajax-broker/images/toolbar_a_hover_right.png b/ajax-broker/images/toolbar_a_hover_right.png Binary files differdeleted file mode 100644 index 1dfa5fb..0000000 --- a/ajax-broker/images/toolbar_a_hover_right.png +++ /dev/null diff --git a/ajax-broker/images/toolbar_a_small_hover.png b/ajax-broker/images/toolbar_a_small_hover.png Binary files differdeleted file mode 100644 index 7341fc5..0000000 --- a/ajax-broker/images/toolbar_a_small_hover.png +++ /dev/null diff --git a/ajax-broker/images/toolbar_a_small_sel.png b/ajax-broker/images/toolbar_a_small_sel.png Binary files differdeleted file mode 100644 index e5eea29..0000000 --- a/ajax-broker/images/toolbar_a_small_sel.png +++ /dev/null diff --git a/ajax-broker/images/toolbar_btn.gif b/ajax-broker/images/toolbar_btn.gif Binary files differdeleted file mode 100644 index 82b8114..0000000 --- a/ajax-broker/images/toolbar_btn.gif +++ /dev/null diff --git a/ajax-broker/images/toolbar_row.png b/ajax-broker/images/toolbar_row.png Binary files differdeleted file mode 100644 index 16fd060..0000000 --- a/ajax-broker/images/toolbar_row.png +++ /dev/null diff --git a/ajax-broker/images/tools.png b/ajax-broker/images/tools.png Binary files differdeleted file mode 100644 index 4e655d2..0000000 --- a/ajax-broker/images/tools.png +++ /dev/null diff --git a/ajax-broker/images/tooltip_arrow.png b/ajax-broker/images/tooltip_arrow.png Binary files differdeleted file mode 100644 index 339098a..0000000 --- a/ajax-broker/images/tooltip_arrow.png +++ /dev/null diff --git a/ajax-broker/images/treemin.gif b/ajax-broker/images/treemin.gif Binary files differdeleted file mode 100644 index 2899b27..0000000 --- a/ajax-broker/images/treemin.gif +++ /dev/null diff --git a/ajax-broker/images/treeplus.gif b/ajax-broker/images/treeplus.gif Binary files differdeleted file mode 100644 index ff43e4f..0000000 --- a/ajax-broker/images/treeplus.gif +++ /dev/null diff --git a/ajax-broker/images/underline.png b/ajax-broker/images/underline.png Binary files differdeleted file mode 100644 index 8b68572..0000000 --- a/ajax-broker/images/underline.png +++ /dev/null diff --git a/ajax-broker/images/undo.png b/ajax-broker/images/undo.png Binary files differdeleted file mode 100644 index 81eb4a0..0000000 --- a/ajax-broker/images/undo.png +++ /dev/null diff --git a/ajax-broker/images/volume.gif b/ajax-broker/images/volume.gif Binary files differdeleted file mode 100644 index c730a09..0000000 --- a/ajax-broker/images/volume.gif +++ /dev/null diff --git a/ajax-broker/images/win16x.png b/ajax-broker/images/win16x.png Binary files differdeleted file mode 100644 index c56998f..0000000 --- a/ajax-broker/images/win16x.png +++ /dev/null diff --git a/ajax-broker/images/win19x.png b/ajax-broker/images/win19x.png Binary files differdeleted file mode 100644 index 1698abf..0000000 --- a/ajax-broker/images/win19x.png +++ /dev/null diff --git a/ajax-broker/images/win28x.png b/ajax-broker/images/win28x.png Binary files differdeleted file mode 100644 index 757f8a3..0000000 --- a/ajax-broker/images/win28x.png +++ /dev/null diff --git a/ajax-broker/images/win32x.png b/ajax-broker/images/win32x.png Binary files differdeleted file mode 100644 index 33aea59..0000000 --- a/ajax-broker/images/win32x.png +++ /dev/null diff --git a/ajax-broker/images/win64x.png b/ajax-broker/images/win64x.png Binary files differdeleted file mode 100644 index 94bcfd9..0000000 --- a/ajax-broker/images/win64x.png +++ /dev/null diff --git a/ajax-broker/images/win_max.gif b/ajax-broker/images/win_max.gif Binary files differdeleted file mode 100644 index 47cd45d..0000000 --- a/ajax-broker/images/win_max.gif +++ /dev/null diff --git a/ajax-broker/images/win_min.gif b/ajax-broker/images/win_min.gif Binary files differdeleted file mode 100644 index 3874140..0000000 --- a/ajax-broker/images/win_min.gif +++ /dev/null diff --git a/ajax-broker/images/win_restore.gif b/ajax-broker/images/win_restore.gif Binary files differdeleted file mode 100644 index 66ae3c7..0000000 --- a/ajax-broker/images/win_restore.gif +++ /dev/null diff --git a/ajax-broker/images/win_x.gif b/ajax-broker/images/win_x.gif Binary files differdeleted file mode 100644 index 48d90d1..0000000 --- a/ajax-broker/images/win_x.gif +++ /dev/null diff --git a/ajax-broker/images/window_border.png b/ajax-broker/images/window_border.png Binary files differdeleted file mode 100644 index f595061..0000000 --- a/ajax-broker/images/window_border.png +++ /dev/null diff --git a/ajax-broker/images/window_lb.png b/ajax-broker/images/window_lb.png Binary files differdeleted file mode 100644 index 26f6e8b..0000000 --- a/ajax-broker/images/window_lb.png +++ /dev/null diff --git a/ajax-broker/images/window_lb_rounded.png b/ajax-broker/images/window_lb_rounded.png Binary files differdeleted file mode 100644 index c264e9a..0000000 --- a/ajax-broker/images/window_lb_rounded.png +++ /dev/null diff --git a/ajax-broker/images/window_lb_small.png b/ajax-broker/images/window_lb_small.png Binary files differdeleted file mode 100644 index 4fe1535..0000000 --- a/ajax-broker/images/window_lb_small.png +++ /dev/null diff --git a/ajax-broker/images/window_lt.png b/ajax-broker/images/window_lt.png Binary files differdeleted file mode 100644 index cdbaf6e..0000000 --- a/ajax-broker/images/window_lt.png +++ /dev/null diff --git a/ajax-broker/images/window_mb.png b/ajax-broker/images/window_mb.png Binary files differdeleted file mode 100644 index c61f511..0000000 --- a/ajax-broker/images/window_mb.png +++ /dev/null diff --git a/ajax-broker/images/window_mb_small.png b/ajax-broker/images/window_mb_small.png Binary files differdeleted file mode 100644 index d4f8d13..0000000 --- a/ajax-broker/images/window_mb_small.png +++ /dev/null diff --git a/ajax-broker/images/window_mt.png b/ajax-broker/images/window_mt.png Binary files differdeleted file mode 100644 index ee4b202..0000000 --- a/ajax-broker/images/window_mt.png +++ /dev/null diff --git a/ajax-broker/images/window_rb.png b/ajax-broker/images/window_rb.png Binary files differdeleted file mode 100644 index 5dcebb2..0000000 --- a/ajax-broker/images/window_rb.png +++ /dev/null diff --git a/ajax-broker/images/window_rb_rounded.png b/ajax-broker/images/window_rb_rounded.png Binary files differdeleted file mode 100644 index c8f1d8f..0000000 --- a/ajax-broker/images/window_rb_rounded.png +++ /dev/null diff --git a/ajax-broker/images/window_rb_small.png b/ajax-broker/images/window_rb_small.png Binary files differdeleted file mode 100644 index ec2cc43..0000000 --- a/ajax-broker/images/window_rb_small.png +++ /dev/null diff --git a/ajax-broker/images/window_rt.png b/ajax-broker/images/window_rt.png Binary files differdeleted file mode 100644 index ddc3a70..0000000 --- a/ajax-broker/images/window_rt.png +++ /dev/null diff --git a/ajax-broker/images/x.png b/ajax-broker/images/x.png Binary files differdeleted file mode 100644 index 49938f7..0000000 --- a/ajax-broker/images/x.png +++ /dev/null diff --git a/ajax-broker/index.html b/ajax-broker/index.html deleted file mode 100644 index 9212dfd..0000000 --- a/ajax-broker/index.html +++ /dev/null @@ -1,162 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns:j="http://www.javeline.com/2005/jml" xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <title>Single Sign-ON</title>
- <script src="jpf_debug.js"></script>
- <script src="alert_r.js"></script>
- <script src="code.js"></script>
- </head>
- <body>
- <j:skin src="skins.xml" icon-path=""></j:skin>
-
- <div style="width:300px;height:40px;background-image:url(logo.png); position:absolute;top:50p;xleft:50px;"></div>
-
- <j:appsettings
- debug = "false"
- outline = "false"
- skinset = "default"
- allow-blur = "true"
- undokeys = "true"
- >
- <j:auth
- login = "rpc:comm.login(username, password)"
- logout = "rpc:comm.logout()"
- fail-state = "stFail"
- error-state = "stError"
- login-state = "stIdle"
- logout-state = "stLoggedOut"
- waiting-state = "stLoggingIn"
- />
- </j:appsettings>
- <j:teleport>
- <j:rpc id="comm" protocol="cgi" http-method="post">
- <j:method name="login" url="sso.php?cmd=login&no-cache=3jj4dkjaf89">
- <j:variable name="username" />
- <j:variable name="password" />
- </j:method>
- <j:method name="attachurl" url="sso.php?cmd=getattachurl&no-cache=3jj4dkjaf89" receive="M_afterAttachURL" />
- <j:method name="info" url="sso.php?cmd=info&no-cache=3jj4dkjaf89" receive="M_afterInfo" />
- <j:method name="logout" url="sso.php?cmd=logout&no-cache=3jj4dkjaf89" />
- </j:rpc>
- </j:teleport>
-
- <j:loader>
- <div id="loadscreen">Loading...</div>
- </j:loader>
-
- <j:state-group id="stGr1" loginMsg.visible="false">
- <j:state id="stFail"
- loginMsg.value = "Username or password incorrect"
- loginMsg.visible = "true"
- log_email.disabled = "false"
- log_password.disabled = "false"
- />
- <j:state id="stError"
- loginMsg.value = "An error has occurred. Please check your network."
- loginMsg.visible = "true"
- />
- <j:state id="stLoggingIn"
- loginMsg.value = "Please wait whilst logging in..."
- loginMsg.visible = "true"
-
- />
- <j:state id="stLoggedOut"
- loginMsg.value = ""
- loginMsg.visible = "false"
- addons.visible = "true"
- log_email.disabled = "false"
- log_password.disabled = "false"
- />
- <j:state id="stIdle" />
- </j:state-group>
-
- <j:window
- skin = "modalwindow"
- id = "M_WINmain"
- resizable = "true"
- center = "true"
- buttons = "min|max"
- visible = "false"
- icon = "images/icons/bullet_key.png"
- width = "250"
- height = "160"
- title = "Log in"
- modal = "false"
- minwidth = "250"
- minheight = "160"
- >
-
- <j:grid columns="60,120" top="30" left="20" cellheight="22" margin="0 6 0 6">
- <j:label
- value="Login:"
- />
- <j:textbox
- value = ""
- id = "log_email"
- type = "username"
- required = "true"
- minlength = "1"
- invalidmsg = "Invalid Entry;Please enter a username" />
- <j:label
- value="Password:"
- />
- <j:textbox
- value = ""
- id = "log_password"
- type = "password"
- required = "true"
- minlength = "1"
- invalidmsg = "Invalid Entry;Please enter your password" />
- </j:grid>
- <j:button
- top = "85"
- left = "140"
- width = "70"
- margin = "0 0 0 20"
- style = "padding-left:4px;"
- action = "login"
- default = "true"
- >
- Login
- </j:button>
- <j:label
- top = "110"
- left = "10"
- id = "loginMsg"
- />
-
- </j:window>
- <j:window
- skin = "modalwindow"
- id = "M_WINinfo"
- resizable = "true"
- center = "true"
- buttons = "min|max"
- visible = "false"
- icon = "images/icons/bullet_key.png"
- width = "250"
- height = "130"
- title = "You are logged in"
- modal = "false"
- minwidth = "250"
- minheight = "130"
- >
- <j:label
- id = "lblLoggedIn"
- top = "25"
- left = "10"
- value = ""
- style = "color:green;font-weight:bold;"
- />
- <j:button
- top = "55"
- left = "140"
- width = "70"
- action = "logout"
- default = "true"
- >
- Logout
- </j:button>
- </j:window>
- </body>
-</html>
diff --git a/ajax-broker/jpf_debug.js b/ajax-broker/jpf_debug.js deleted file mode 100644 index 517c2dd..0000000 --- a/ajax-broker/jpf_debug.js +++ /dev/null @@ -1,90943 +0,0 @@ - -/*FILEHEAD(/var/lib/jpf/src/jpack_begin.js)SIZE(-1077090856)TIME(1224578767)*/ - - - -/*FILEHEAD(/var/lib/jpf/src/jpf.js)SIZE(-1077090856)TIME(1238933683)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - -/** - * Javeline Platform - * - * @author Ruben Daniels ruben@javeline.com - * @version 2.0 - * @url http://www.ajax.org - * - * @event domready Fires when the browsers' dom is ready to be manipulated. - * @event movefocus Fires when the focus moves from one element to another. - * object: - * {JMLElement} toElement the element that will receive the focus. - * @event exit Fires when the application wants to exit. - * cancellable: Prevents the application from exiting. The returnValue of the - * event object is displayed in a popup which asks the user for permission. - * @event keyup Fires when the user stops pressing a key. - * cancellable: Prevents the behaviour. - * object: - * {Number} keyCode the char code of the pressed key. - * {Boolean} ctrlKey whether the ctrl key was pressed. - * {Boolean} shiftKey whether the shift key was pressed. - * {Boolean} altKey whether the alt key was pressed. - * {Object} htmlEvent the html event object. - * @event mousescroll Fires when the user scrolls the mouse - * cancellable: Prevents the container to scroll - * object: - * {Number} delta the scroll impulse. - * @event hotkey Fires when the user presses a hotkey - * bubbles: yes - * cancellable: Prevents the default hotkey behaviour. - * object: - * {Number} keyCode the char code of the pressed key. - * {Boolean} ctrlKey whether the ctrl key was pressed. - * {Boolean} shiftKey whether the shift key was pressed. - * {Boolean} altKey whether the alt key was pressed. - * {Object} htmlEvent the html event object. - * @event keydown Fires when the user presses a key - * bubbles: yes - * cancellable: Prevents the behaviour. - * object: - * {Number} keyCode the char code of the pressed key. - * {Boolean} ctrlKey whether the ctrl key was pressed. - * {Boolean} shiftKey whether the shift key was pressed. - * {Boolean} altKey whether the alt key was pressed. - * {Object} htmlEvent the html event object. - * @event mousedown Fires when the user presses a mouse button - * object: - * {Event} htmlEvent the char code of the pressed key. - * {JMLElement} jmlNode the element on which is clicked. - * @event onbeforeprint Fires before the application will print. - * @event onafterprint Fires after the application has printed. - * @event load Fires after the application is loaded. - * @event error Fires when a communication error has occured while making a request for this element. - * cancellable: Prevents the error from being thrown. - * bubbles: - * object: - * {Error} error the error object that is thrown when the event callback doesn't return false. - * {Number} state the state of the call - * Possible values: - * jpf.SUCCESS the request was successfull - * jpf.TIMEOUT the request has timed out. - * jpf.ERROR an error has occurred while making the request. - * jpf.OFFLINE the request was made while the application was offline. - * {mixed} userdata data that the caller wanted to be available in the callback of the http request. - * {XMLHttpRequest} http the object that executed the actual http request. - * {String} url the url that was requested. - * {Http} tpModule the teleport module that is making the request. - * {Number} id the id of the request. - * {String} message the error message. - */ -var jpf = { -VERSION:'1.0rc1', - // Content Distribution Network URL: - CDN : "", - - READY : false, - - //JML nodeFunc constants - NODE_HIDDEN : 101, - NODE_VISIBLE : 102, - NODE_MEDIAFLOW : 103, - - //DOM nodeType constants - NODE_ELEMENT : 1, - NODE_ATTRIBUTE : 2, - NODE_TEXT : 3, - NODE_CDATA_SECTION : 4, - NODE_ENTITY_REFERENCE : 5, - NODE_ENTITY : 6, - NODE_PROCESSING_INSTRUCTION : 7, - NODE_COMMENT : 8, - NODE_DOCUMENT : 9, - NODE_DOCUMENT_TYPE : 10, - NODE_DOCUMENT_FRAGMENT : 11, - NODE_NOTATION : 12, - - KEYBOARD : 2, - KEYBOARD_MOUSE : true, - - SUCCESS : 1, - TIMEOUT : 2, - ERROR : 3, - OFFLINE : 4, - - debug : true, - debugType : "Memory", - debugFilter : "!teleport", - - includeStack : [], - initialized : false, - autoLoadSkin : false, - crypto : {}, //namespace - _GET : {}, - basePath : "./", - - /** - * {Object} contains several known and often used namespace URI's. - * @private - */ - ns : { - jpf : "http://www.javeline.com/2005/jml", - jml : "http://www.javeline.com/2005/jml", - xsd : "http://www.w3.org/2001/XMLSchema", - xhtml : "http://www.w3.org/1999/xhtml", - xslt : "http://www.w3.org/1999/XSL/Transform", - xforms : "http://www.w3.org/2002/xforms", - ev : "http://www.w3.org/2001/xml-events" - }, - - /** - * @private - */ - browserDetect : function(){ - if (this.$bdetect) - return; - this.$bdetect = true; - - var sAgent = navigator.userAgent.toLowerCase(); - - //Browser Detection - this.isOpera = sAgent.indexOf("opera") != -1; - - this.isKonqueror = sAgent.indexOf("konqueror") != -1; - this.isSafari = !this.isOpera && ((navigator.vendor - && navigator.vendor.match(/Apple/) ? true : false) - || sAgent.indexOf("safari") != -1 || this.isKonqueror); - this.isSafariOld = false; - - if (this.isSafari) { - var matches = sAgent.match(/applewebkit\/(\d+)/); - if (matches) - this.isSafariOld = parseInt(matches[1]) < 420; - } - - this.isChrome = sAgent.indexOf("chrome/") != -1; - this.isGecko = !this.isOpera && !this.isSafari && sAgent.indexOf("gecko") != -1; - this.isGecko3 = this.isGecko && sAgent.indexOf("firefox/3") != -1; - - var found; - this.isIE = document.all && !this.isOpera && !this.isSafari ? true : false; - this.isIE8 = this.isIE && sAgent.indexOf("msie 8.") != -1 && (found = true); - this.isIE7 = this.isIE && !found && sAgent.indexOf("msie 7.") != -1 && (found = true); - this.isIE6 = this.isIE && !found && sAgent.indexOf("msie 6.") != -1 && (found = true); - this.isIE55 = this.isIE && !found && sAgent.indexOf("msie 5.5") != -1 && (found = true); - this.isIE50 = this.isIE && !found && sAgent.indexOf("msie 5.0") != -1 && (found = true); - - this.isWin = sAgent.indexOf("win") != -1 || sAgent.indexOf("16bit") != -1; - this.isMac = sAgent.indexOf("mac") != -1; - - this.isAIR = sAgent.indexOf("adobeair") != -1; - - try { - //this.isDeskrun = window.external.shell.runtime == 2; - } - catch(e) { - this.isDeskrun = false; - } - }, - - /** - * @private - */ - setCompatFlags : function(){ - //Set Compatibility - this.TAGNAME = jpf.isIE ? "baseName" : "localName"; - this.supportVML = jpf.isIE; - this.supportCanvas = !jpf.isIE; - this.supportSVG = !jpf.isIE; - this.styleSheetRules = jpf.isIE ? "rules" : "cssRules"; - this.brokenHttpAbort = jpf.isIE6; - this.canUseHtmlAsXml = jpf.isIE; - this.supportNamespaces = !jpf.isIE; - this.cannotSizeIframe = jpf.isIE; - this.supportOverflowComponent = jpf.isIE; - this.hasEventSrcElement = jpf.isIE; - this.canHaveHtmlOverSelects = !jpf.isIE6 && !jpf.isIE5; - this.hasInnerText = jpf.isIE; - this.hasMsRangeObject = jpf.isIE; - this.hasContentEditable = jpf.isIE || jpf.isOpera; - this.descPropJs = jpf.isIE; - this.hasClickFastBug = jpf.isIE; - this.hasExecScript = window.execScript ? true : false; - this.canDisableKeyCodes = jpf.isIE; - this.hasTextNodeWhiteSpaceBug = jpf.isIE; - this.hasCssUpdateScrollbarBug = jpf.isIE; - this.canUseInnerHtmlWithTables = !jpf.isIE; - this.hasSingleResizeEvent = !jpf.isIE; - this.hasStyleFilters = jpf.isIE; - this.supportOpacity = !jpf.isIE; - this.supportPng24 = !jpf.isIE6 && !jpf.isIE5; - this.cantParseXmlDefinition = jpf.isIE50; - this.hasDynamicItemList = !jpf.isIE || jpf.isIE7; - this.canImportNode = jpf.isIE; - this.hasSingleRszEvent = !jpf.isIE; - this.hasXPathHtmlSupport = !jpf.isIE; - this.hasFocusBug = jpf.isIE; - this.hasReadyStateBug = jpf.isIE50; - this.dateSeparator = jpf.isIE ? "-" : "/"; - this.canCreateStyleNode = !jpf.isIE; - this.supportFixedPosition = !jpf.isIE || jpf.isIE7; - this.hasHtmlIdsInJs = jpf.isIE || jpf.isSafari; - this.needsCssPx = !jpf.isIE; - this.hasAutocompleteXulBug = jpf.isGecko; - this.mouseEventBuffer = jpf.isIE ? 20 : 6; - this.hasComputedStyle = typeof document.defaultView != "undefined" - && typeof document.defaultView.getComputedStyle != "undefined"; - this.locale = (this.isIE - ? navigator.userLanguage - : navigator.language).toLowerCase(); - - //Other settings - this.maxHttpRetries = this.isOpera ? 0 : 3; - - this.dynPropMatch = new RegExp(); - this.dynPropMatch.compile("^[{\\[].*[}\\]]$"); - - this.percentageMatch = new RegExp(); - this.percentageMatch.compile("([\\-\\d\\.]+)\\%", "g"); - - jpf.isGears = !!jpf.initGears() || 0; - }, - - /** - * Restarts the application. - */ - reboot : function(){ - jpf.console.info("Restarting application..."); - - location.href = location.href; - }, - - /** - * Extends an object with one or more other objects by copying all their - * properties. - * @param {Object} dest the destination object. - * @param {Object} src the object that is copies from. - * @return {Object} the destination object. - */ - extend : function(dest, src){ - var prop, i, x = !dest.notNull; - if (arguments.length == 2) { - for (prop in src) { - if (x || src[prop]) - dest[prop] = src[prop]; - } - return dest; - } - - for (i = 1; i < arguments.length; i++) { - src = arguments[i]; - for (prop in src) { - if (x || src[prop]) - dest[prop] = src[prop]; - } - } - return dest; - }, - - /** - * Starts the application. - */ - start : function(){ - this.started = true; - var sHref = location.href.split("#")[0].split("?")[0]; - - //Set Variables - this.host = location.hostname && sHref.replace(/(\/\/[^\/]*)\/.*$/, "$1"); - this.hostPath = sHref.replace(/\/[^\/]*$/, "") + "/"; - this.CWD = sHref.replace(/^(.*\/)[^\/]*$/, "$1") + "/"; - - jpf.console.info("Starting Javeline PlatForm Application..."); - jpf.console.warn("This is a debug build of Javeline PlatForm; \ - beware that execution speed of this build is \ - <strong>several times</strong> slower than a \ - release build of Javeline PlatForm."); - - //mozilla root detection - //try{ISROOT = !window.opener || !window.opener.jpf}catch(e){ISROOT = true} - - //Browser Specific Stuff - this.browserDetect(); - this.setCompatFlags(); - - jpf.debugwin.init(); - - //Load Browser Specific Code - if (this.isIE) jpf.runIE(); - //this.importClass(jpf.runIE, true, self); - if (this.isSafari) jpf.runSafari(); - //this.importClass(jpf.runSafari, true, self); - if (this.isOpera) jpf.runOpera(); - //this.importClass(jpf.runOpera, true, self); - if (this.isGecko || !this.isIE && !this.isSafari && !this.isOpera) - jpf.runGecko(); - //this.importClass(jpf.runGecko, true, self); - - for (var i, a, m, n, o, v, p = location.href.split(/[?&]/), l = p.length, k = 1; k < l; k++) - if (m = p[k].match(/(.*?)(\..*?|\[.*?\])?=([^#]*)/)) { - n = decodeURI(m[1]).toLowerCase(), o = this._GET; - if (m[2]) - for (a = decodeURI(m[2]).replace(/\[\s*\]/g, "[-1]").split(/[\.\[\]]/), i = 0; i < a.length; i++) - v = a[i], o = o[n] - ? o[n] - : o[n] = (parseInt(v) == v) - ? [] - : {}, n = v.replace(/^["\'](.*)["\']$/,"$1"); - n != '-1' - ? o[n] = decodeURI(m[3]) - : o[o.length] = decodeURI(m[3]); - } - - // Start HTTP object - this.oHttp = new this.http(); - - // Load user defined includes - this.Init.addConditional(this.loadIncludes, jpf, ['body', 'xmldb']); - //@todo, as an experiment I removed 'HTTP' and 'Teleport' - - //IE fix - try { - if (jpf.isIE) - document.execCommand("BackgroundImageCache", false, true); - } - catch(e) {}; - - //try{jpf.root = !window.opener || !window.opener.jpf;} - //catch(e){jpf.root = false} - this.root = true; - }, - - // # ifndef __PACKAGED - /** - * @private - */ - startDependencies : function(){ - if (location.protocol != "file:") { - jpf.console.warn("You are serving multiple files from a (local)\ - webserver - please consider using the file:// protocol to \ - load your files, because that will make your application \ - load several times faster.\ - On a webserver, we recommend using a release or debug build \ - of Javeline Platform."); - } - - jpf.console.info("Loading Dependencies..."); - - var i; - // Load Kernel Modules - for (i = 0; i < this.KernelModules.length; i++) - jpf.include("core/" + this.KernelModules[i], true); - - // Load TelePort Modules - for (i = 0; i < this.TelePortModules.length; i++) - jpf.include("elements/teleport/" + this.TelePortModules[i], true); - - // Load Elements - for (i = 0; i < this.Elements.length; i++) { - var c = this.Elements[i]; - jpf.include("elements/" + c + ".js", true); - } - - jpf.Init.interval = setInterval( - "if (jpf.checkLoadedDeps()) {\ - clearInterval(jpf.Init.interval);\ - jpf.start();\ - }", 100); - }, - - /** - * @private - */ - nsqueue : {}, - - /** - * Offers a way to load modules into a javascript namespace before the root - * of that namespace is loaded. - * @private - */ - namespace : function(name, oNamespace){ - try{ - eval("jpf." + name + " = oNamespace"); - delete this.nsqueue[name]; - - for (var ns in this.nsqueue) { - if (ns.indexOf(name) > -1) { - this.namespace(ns, this.nsqueue[ns]); - } - } - - return true; - }catch(e){ - this.nsqueue[name] = oNamespace; - - return false; - } - }, - //# endif - - /** - * @private - */ - findPrefix : function(xmlNode, xmlns){ - var docEl; - if (xmlNode.nodeType == 9) { - if (!xmlNode.documentElement) return false; - if (xmlNode.documentElement.namespaceURI == xmlns) - return xmlNode.prefix || xmlNode.scopeName; - docEl = xmlNode.documentElement; - } - else { - if (xmlNode.namespaceURI == xmlns) - return xmlNode.prefix || xmlNode.scopeName; - docEl = xmlNode.ownerDocument.documentElement; - if (docEl && docEl.namespaceURI == xmlns) - return xmlNode.prefix || xmlNode.scopeName; - - while (xmlNode.parentNode) { - xmlNode = xmlNode.parentNode; - if (xmlNode.namespaceURI == xmlns) - return xmlNode.prefix || xmlNode.scopeName; - } - } - - if (docEl) { - for (var i=0; i<docEl.attributes.length; i++) { - if (docEl.attributes[i].nodeValue == xmlns) - return docEl.attributes[i][jpf.TAGNAME] - } - } - - return false; - }, - - /** - * @private - */ - importClass : function(ref, strip, win){ - if (!ref) - throw new Error(jpf.formatErrorString(1018, null, - "importing class", - "Could not load reference. Reference is null")); - - //if (!jpf.hasExecScript) - //return ref();//.call(self); - - if (!strip) - return jpf.exec(ref.toString(), win); - - var q = ref.toString().replace(/^\s*function\s*\w*\s*\([^\)]*\)\s*\{/, ""); - q = q.replace(/\}\s*$/, ""); - - //var q = ref.toString().split("\n");q.shift();q.pop(); - //if(!win.execScript) q.shift();q.pop(); - - return jpf.exec(q, win); - }, - - /** - * This method returns a string representation of the object - * @return {String} Returns a string representing the object. - */ - toString : function(){ - return "[Javeline (jpf)]"; - }, - - all : [], - - /** - * This method inherit all properties and methods to this object from another class - * @param {Function} classRef Class reference - */ - inherit : function(classRef){ - for (var i=0; i<arguments.length; i++) { - if (!arguments[i]) { - throw new Error(jpf.formatErrorString(0, this, - "Inheriting class", - "Could not inherit from '" + classRef + "'", - this.$jml)); - } - - arguments[i].call(this);//classRef - } - - return this; - }, - - /** - * This method transforms an object into a jpf class based object. - * @param {Object} oBlank the object which will be transformed - */ - makeClass : function(oBlank){ - if (oBlank.inherit) return; - - oBlank.inherit = this.inherit; - oBlank.inherit(jpf.Class); - - oBlank.uniqueId = this.all.push(oBlank) - 1; - }, - - /** - * @private - */ - uniqueHtmlIds : 0, - - /** - * Adds a unique id attribute to an html element. - * @param {HTMLElement} oHtml the object getting the attribute. - */ - setUniqueHtmlId : function(oHtml){ - oHtml.setAttribute("id", "q" + this.uniqueHtmlIds++); - }, - - /** - * Retrieves a new unique id - */ - getUniqueId : function(oHtml){ - return this.uniqueHtmlIds++; - }, - - /** - * @private - * @todo deprecate this in favor of jpf.component - * @deprecated - */ - register : function(o, tagName, nodeFunc){ - o.tagName = tagName; - o.nodeFunc = nodeFunc || jpf.NODE_HIDDEN; - - o.$domHandlers = {"remove" : [], "insert" : [], "reparent" : [], "removechild" : []}; - o.$propHandlers = {}; //@todo fix this in each component - - if (nodeFunc != jpf.NODE_HIDDEN) { - o.$booleanProperties = { - "visible" : true, - "focussable" : true, - //"disabled" : true, - "disable-keyboard" : true - } - - o.$supportedProperties = [ - "draggable", "resizable", - "focussable", "zindex", "disabled", "tabindex", - "disable-keyboard", "contextmenu", "visible", "autosize", - "loadjml", "actiontracker", "alias"]; - } - else { - o.$booleanProperties = {}; //@todo fix this in each component - o.$supportedProperties = []; //@todo fix this in each component - } - - if (!o.inherit) { - o.inherit = this.inherit; - o.inherit(jpf.Class); - o.uniqueId = this.all.push(o) - 1; - } - - if(o.nodeFunc == jpf.NODE_MEDIAFLOW) - DeskRun.register(o); - }, - - /** - * Finds a jml element based on it's uniqueId - */ - lookup : function(uniqueId){ - return this.all[uniqueId]; - }, - - /** - * Searches in the html tree from a certain point to find the - * jml element that is responsible for rendering the specified html - * element. - * @param {HTMLElement} oHtml the html context to start the search from. - */ - findHost : function(o){ - while (o && !o.host && o.parentNode) - o = o.parentNode; - return (o && o.host && typeof o.host != "string") ? o.host : false; - }, - - /** - * Sets a reference to an object by name in the global javascript space. - * @param {String} name the name of the reference. - * @param {mixed} o the reference to the object subject to the reference. - */ - setReference : function(name, o){ - return self[name] && self[name].hasFeature - ? 0 - : (self[name] = o); - }, - - /** - * The console outputs to the debug screen and offers differents ways to do - * this. - */ - console : { - /** - * @private - */ - data : { - time : { - icon : "time.png", - color : "black", - messages : {} - }, - - info : { - icon : "bullet_green.png", - color : "black", - messages : {} - }, - - warn : { - icon : "error.png", - color : "green", - messages : {} - }, - - error : { - icon : "exclamation.png", - color : "red", - messages : {} - } - }, - - /** - * @private - */ - toggle : function(node, id){ - var sPath = jpf.debugwin ? jpf.debugwin.resPath : jpf.basePath + "core/debug/resources/"; - if (node.style.display == "block") { - node.style.display = "none"; - node.parentNode.style.backgroundImage = "url(" + sPath + "splus.gif)"; - node.innerHTML = ""; - } - else { - node.style.display = "block"; - node.parentNode.style.backgroundImage = "url(" + sPath + "smin.gif)"; - node.innerHTML = this.cache[id] - .replace(/\&/g, "&") - .replace(/\t/g," ") - .replace(/ /g," ") - .replace(/\</g, "<") - .replace(/\n/g, "<br />"); - - var p = node.parentNode.parentNode.parentNode; - var el = node.parentNode.parentNode; - if(p.scrollTop + p.offsetHeight < el.offsetTop + el.offsetHeight) - p.scrollTop = el.offsetTop + el.offsetHeight - p.offsetHeight; - } - }, - - /** - * @private - */ - cache : [], - - /** - * @private - * @event debug Fires when a message is sent to the console. - * object: - * {String} message the content of the message. - */ - write : function(msg, type, subtype, data, forceWin, nodate){ - //if (!jpf.debug) return; - if (!Number.prototype.toPrettyDigit) { - Number.prototype.toPrettyDigit = function() { - var n = this.toString(); - return (n.length == 1) ? "0" + n : n; - } - } - - var dt = new Date(); - var ms = String(dt.getMilliseconds()); - while (ms.length < 3) ms += "0"; - var date = dt.getHours().toPrettyDigit() + ":" - + dt.getMinutes().toPrettyDigit() + ":" - + dt.getSeconds().toPrettyDigit() + "." - + ms; - - msg = (!nodate ? "[" + date + "] " : "") - + String(msg).replace(/ +/g, " ").replace(/\n/g, "\n<br />") - .replace(/\t/g," "); - var sPath = jpf.debugwin - ? (jpf.debugwin.resPath || "{imgpath}") - : jpf.basePath + "core/debug/resources/"; - - if (data) { - msg += "<blockquote style='margin:2px 0 0 0;\ - background:url(" + sPath + "splus.gif) no-repeat 2px 3px'>\ - <strong style='width:120px;cursor:default;display:block;padding:0 0 0 17px' \ - onmousedown='(self.jpf || window.opener.jpf).console.toggle(this.nextSibling, " - + (this.cache.push(data) - 1) + ")'>More information\ - </strong><div style='display:none;background-color:#EEEEEE;\ - padding:3px 3px 20px 3px;overflow:auto;max-height:200px'>\ - </div></blockquote>"; - } - - msg = "<div style='min-height:15px;padding:2px 2px 2px 22px;\ - line-height:15px;border-bottom:1px solid #EEE;background:url(" - + sPath + this.data[type].icon + ") no-repeat 2px 2px;color:" - + this.data[type].color + "'>" + msg + "\n<br style='line-height:0'/></div>"; - - if (!subtype) - subtype = "default"; - - if (!this.data[type].messages[subtype]) - this.data[type].messages[subtype] = []; - - this.data[type].messages[subtype].push(msg); - - if (this.win && !this.win.closed) - this.showWindow(msg); - - //if (jpf.debugFilter.match(new RegExp("!" + subtype + "(\||$)", "i"))) - // return; - - this.debugInfo.push(msg); - - if (jpf.dispatchEvent) - jpf.dispatchEvent("debug", {message: msg}); - }, - - /** - * Writes a message to the console. - * @param {String} msg the message to display in the console. - * @param {String} subtype the category for this message. This is used for filtering the messages. - * @param {String} data extra data that might help in debugging. - */ - debug : function(msg, subtype, data){ - this.write(msg, "time", subtype, data); - }, - - /** - * Writes a message to the console with the time icon next to it. - * @param {String} msg the message to display in the console. - * @param {String} subtype the category for this message. This is used for filtering the messages. - * @param {String} data extra data that might help in debugging. - */ - time : function(msg, subtype, data){ - this.write(msg, "time", subtype, data); - }, - - /** - * Writes a message to the console. - * @param {String} msg the message to display in the console. - * @param {String} subtype the category for this message. This is used for filtering the messages. - * @param {String} data extra data that might help in debugging. - */ - log : function(msg, subtype, data){ - this.info(msg, subtype, data); - }, - - /** - * Writes a message to the console with the visual "info" icon and color - * coding. - * @param {String} msg the message to display in the console. - * @param {String} subtype the category for this message. This is used for filtering the messages. - * @param {String} data extra data that might help in debugging. - */ - info : function(msg, subtype, data){ - this.write(msg, "info", subtype, data); - }, - - /** - * Writes a message to the console with the visual "warning" icon and - * color coding. - * @param {String} msg the message to display in the console. - * @param {String} subtype the category for this message. This is used for filtering the messages. - * @param {String} data extra data that might help in debugging. - */ - warn : function(msg, subtype, data){ - this.write(msg, "warn", subtype, data); - }, - - /** - * Writes a message to the console with the visual "error" icon and - * color coding. - * @param {String} msg the message to display in the console. - * @param {String} subtype the category for this message. This is used for filtering the messages. - * @param {String} data extra data that might help in debugging. - */ - error : function(msg, subtype, data){ - this.write(msg, "error", subtype, data); - }, - - /** - * Prints a listing of all properties of the object. - * @param {mixed} obj the object for which the properties are displayed. - */ - dir : function(obj){ - this.info(jpf.vardump(obj, null, false).replace(/ /g, " ").replace(/</g, "<")); - } - - , - /** - * @private - */ - debugInfo : [], - - /** - * @private - */ - debugType : "", - - /** - * Shows a browser window with the contents of the console. - * @param {String} msg a new message to add to the new window. - */ - showWindow : function(msg){ - if (!this.win || this.win.closed) { - this.win = window.open("", "debug"); - this.win.document.write('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\ - <body style="margin:0;font-family:Verdana;font-size:8pt;"></body>'); - } - if (!this.win) { - if (!this.haspopupkiller) - alert("Could not open debug window, please check your popupkiller"); - this.haspopupkiller = true; - } - else { - this.win.document.write((msg || this.debugInfo.join("")) - .replace(/\{imgpath\}/g, jpf.debugwin - ? jpf.debugwin.resPath - : jpf.basePath + "core/debug/resources/")); - } - } - - }, - - /** - * Formats a Javeline PlatForm error message. - * @param {Number} number the number of the error. This can be used to look up more information about the error. - * @param {JMLElement} control the jml element that will throw the error. - * @param {String} process the action that was being executed. - * @param {String} message the actual error message. - * @param {XMLElement} jmlContext the xml relevant to the error. For instance a piece of javeline markup language xml. - */ - formatErrorString : function(number, control, process, message, jmlContext, outputname, output){ - var str = ["---- Javeline Error ----"]; - if (jmlContext) { - if (jmlContext.nodeType == 9) - jmlContext = jmlContext.documentElement; - - //Determine file context - var file = jmlContext.ownerDocument.documentElement.getAttribute("filename"); - if (!file && jmlContext.ownerDocument.documentElement.tagName == "html") - file = location.href; - file = file - ? jpf.removePathContext(jpf.hostPath, file) - : "Unkown filename"; - - //Get serialized version of context - var jmlStr = (jmlContext.outerHTML || jmlContext.xml || jmlContext.serialize()) - .replace(/\<\?xml\:namespace prefix = j ns = "http\:\/\/www.javeline.com\/2005\/jml" \/\>/g, "") - .replace(/xmlns:j="[^"]*"\s*/g, ""); - - //Determine line number - var diff, linenr = 0, w = jmlContext.previousSibling - || jmlContext.parentNode && jmlContext.parentNode.previousSibling; - while(w && w[jpf.TAGNAME] != "body"){ - diff = (w.outerHTML || w.xml || w.serialize()).split("\n").length; - linenr += diff - 1; - w = w.previousSibling || w.parentNode - && w.parentNode.previousSibling; - } - if (w && w[jpf.TAGNAME] != "body") - linenr = "unknown"; - else if(jmlContext.ownerDocument.documentElement.tagName == "html") - linenr += jpf.lineBodyStart; - - //Grmbl line numbers are wrong when \n's in attribute space - - //Set file and line number - str.push("jml file: [line: " + linenr + "] " + file); - } - if (control) - str.push("Control: '" - + (control.name - || (control.$jml ? control.$jml.getAttribute("id") : null) - || "{Anonymous}") - + "' [" + control.tagName + "]"); - if (process) - str.push("Process: " + process.replace(/ +/g, " ")); - if (message) - str.push("Message: [" + number + "] " + message.replace(/ +/g, " ")); - if (outputname) - str.push(outputname + ": " + output); - if (jmlContext) - str.push("\n===\n" + jmlStr); - - return (jpf.lastErrorMessage = str.join("\n")); - }, - - /* Init */ - - /** - * Loads javascript from a url. - * @param {String} sourceFile the url where the javascript is located. - */ - include : function(sourceFile, doBase, type){ - jpf.console.info("including js file: " + sourceFile); - - var sSrc = doBase ? (jpf.basePath || "") + sourceFile : sourceFile; - if (jpf.isSafariOld || jpf.isSafari && !jpf.started) { - document.write('<script type="text/javascript" src="' + sSrc + '"><\/script>'); - } - else { - var head = document.getElementsByTagName("head")[0];//$("head")[0] - var elScript = document.createElement("script"); - elScript.defer = true; - if (type) - elScript.setAttribute("_jpf_type", type); - elScript.src = sSrc; - head.appendChild(elScript); - } - }, - - /** - * @private - */ - Init : { - queue : [], - cond : { - combined : [] - }, - done : {}, - - add : function(func, o){ - if (this.inited) - func.call(o); - else if (func) - this.queue.push([func, o]); - }, - - addConditional : function(func, o, strObj){ - if (typeof strObj != "string") { - if (this.checkCombined(strObj)) - return func.call(o); - this.cond.combined.push([func, o, strObj]); - } - else if (self[strObj]) { - func.call(o); - } - else { - if (!this.cond[strObj]) - this.cond[strObj] = []; - this.cond[strObj].push([func, o]); - - this.checkAllCombined(); - } - }, - - checkAllCombined : function(){ - for (var i=0; i<this.cond.combined.length; i++) { - if (!this.cond.combined[i]) continue; - - if (this.checkCombined(this.cond.combined[i][2])) { - this.cond.combined[i][0].call(this.cond.combined[i][1]) - this.cond.combined[i] = null; - } - } - }, - - checkCombined : function(arr){ - for (var i=0; i<arr.length; i++) { - if (!this.done[arr[i]]) - return false; - } - - return true; - }, - - run : function(strObj){ - this.inited = this.done[strObj] = true; - - this.checkAllCombined(); - - var data = strObj ? this.cond[strObj] : this.queue; - if (!data) return; - for (var i = 0; i < data.length; i++) - data[i][0].call(data[i][1]); - } - }, - - - /** - * @todo Build this function into the compressor for faster execution - * @private - */ - getJmlDocFromString : function(xmlString){ - //replace(/&\w+;/, ""). replace this by something else - var str = xmlString.replace(/\<\!DOCTYPE[^>]*>/, "").replace(/ /g, " ") - .replace(/^[\r\n\s]*/, "").replace(/<\s*\/?\s*(?:\w+:\s*)[\w-]*[\s>\/]/g, - function(m){ return m.toLowerCase(); }); - - if (!this.supportNamespaces) - str = str.replace(/xmlns\=\"[^"]*\"/g, ""); - - var xmlNode = jpf.getXmlDom(str, null, jpf.debug); - - // Case insensitive support - var nodes = xmlNode.selectNodes("//@*[not(contains(local-name(), '.')) and not(translate(local-name(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz') = local-name())]"); - for (var i=0; i<nodes.length; i++) { - (nodes[i].ownerElement || nodes[i].selectSingleNode("..")) - .setAttribute(nodes[i].nodeName.toLowerCase(), nodes[i].nodeValue); - } - - return xmlNode; - }, - - /** - * @private - */ - jmlParts : [], - - /** - * {Number} parseStrategy - * Possible values: - * 0 auto - * 1 partial - * 11 partial from a comment - * 2 full from serialized document or file fallback - * 21 full from file - */ - parseStrategy : 0, - - parsePartialJml : function(docElement){ - jpf.console.warn("The jml namespace definition wasn't found \ - on the root node of this document. We're assuming \ - you want to load a partial piece of jml embedded\ - in this document. Starting to search for it now."); - - if (jpf.isIE) { - var findJml = function(htmlNode){ - if (htmlNode.outerHTML.match(/\/>$/)) { - throw new Error("Cannot have self closing elements!\n" - + htmlNode.outerHTML); - } - - try { - var tags = {"IMG":1,"LINK":1,"META":1,"INPUT":1,"BR":1,"HR":1,"AREA":1,"BASEFONT":1}; - var strXml = (htmlNode.parentNode.outerHTML.replace(/\n/g, "").match( - new RegExp(htmlNode.outerHTML.replace(/([\(\)\|\\\.\^\$\{\}\[\]])/g, "\\$1") - + ".*" + htmlNode.tagName))[0] + ">") - .replace(/(\w+)\s*=\s*([^\>="'\s ]+)( |\s|\>|\/\>)/g, "$1=\"$2\"$3") - .replace(/ disabled /g, " disabled='true' ") - .replace(/\]\]\>/g, "]]>") - .replace(/<(\w+)(\s[^>]*[^\/])?>/g, function(m, tag, c){ - if (tags[tag]) { - return "<" + tag + (c||"") + "/>"; - } - else { - return m; - } - }); - } - catch(e) { - throw new Error(jpf.formatErrorString(0, null, - "Parsing inline jml (without xmlns on root node)", - "Could not parse inline jml. This happens when the html\ - is mangled too much by Internet Explorer. Either you\ - are using a cdata section or javascript containing\ - symbols that throw off the browser. Please put this jml\ - in a seperate file and load it using a j:include.")); - - return; - } - - var p = prefix.toLowerCase(); - var xmlNode = jpf.getJmlDocFromString("<div jid='" - + (id++) + "' " + strXmlns + ">" - + strXml + "</div>").documentElement; - - while(xmlNode.childNodes.length > 1) { - xmlNode.removeChild(xmlNode.lastChild); - } - - jpf.AppNode.appendChild(xmlNode); - } - } - else { - var findJml = function(htmlNode){ - var strXml = htmlNode.outerHTML - .replace(/ _moz-userdefined=""/g, ""); - - var p = prefix.toLowerCase(); - var xmlNode = jpf.getJmlDocFromString("<div jid='" - + (id++) + "' " + strXmlns + ">" - + strXml + "</div>").documentElement; - - while(xmlNode.childNodes.length > 1) { - xmlNode.removeChild(xmlNode.lastChild); - } - - if (jpf.isSafari) - xmlNode = jpf.AppNode.ownerDocument.importNode(xmlNode, true); - - jpf.AppNode.appendChild(xmlNode); - } - } - - var strHtml = document.body.outerHTML; - var match = strHtml.match(/(\w+)\s*=\s*["']http:\/\/www\.javeline\.com\/2005\/jml["']/); - if (!match) - return false; - - var strXmlns = "xmlns:" + match[0]; - var prefix = (RegExp.$1 || "").toUpperCase(); - if (jpf.isOpera) - prefix = prefix.toLowerCase(); - if (!prefix) - return false; - - prefix += ":"; - - jpf.AppNode = jpf.getJmlDocFromString("<" + prefix.toLowerCase() - + "application " + strXmlns + " />").documentElement; - - var temp, loop; - var cnode, isPrefix = false, id = 0, str, x, node = document.body; - while (node) { - isPrefix = node.nodeType == 1 - && node.tagName.substr(0,2) == prefix; - - if (isPrefix) { - findJml(cnode = node); - - if (jpf.isIE) { - loop = node; - var count = 1, next = loop.nextSibling; - if (next) { - loop.parentNode.removeChild(loop); - - while (next && (next.nodeType != 1 || next.tagName.indexOf(prefix) > -1)){ - if (next.nodeType == 1) - count += next.tagName.charAt(0) == "/" ? -1 : 1; - - if (count == 0) { - if (temp) - temp.parentNode.removeChild(temp); - temp = next; - break; - } - - next = (loop = next).nextSibling; - if (!next) { - next = loop; - break; - } - if (loop.nodeType == 1) { - loop.parentNode.removeChild(loop); - if (temp) { - temp.parentNode.removeChild(temp); - temp = null; - } - } - else { - if (temp) - temp.parentNode.removeChild(temp); - - temp = loop; - } - } - - node = next; //@todo item should be deleted - //check here for one too far - } - else { - if (temp) - temp.parentNode.removeChild(temp); - temp = loop; - } - } - else { - if (temp) - temp.parentNode.removeChild(temp); - - temp = node; - //node = node.nextSibling; - } - - if (jpf.jmlParts.length - && jpf.jmlParts[jpf.jmlParts.length-1][1] == cnode) - jpf.jmlParts[jpf.jmlParts.length-1][1] = -1; - - jpf.jmlParts.push([node.parentNode, jpf.isIE - ? node.nextSibling : node.nextSibling]); - } - else if (node.tagName == "SCRIPT" && node.getAttribute("src") - && (node.getAttribute("src").indexOf("ajax.org") > -1 - || node.getAttribute("src").indexOf("javeline.com") > -1)) { - var strXml = node.outerHTML - .replace(/</g, "<") - .replace(/>/g, ">") - .replace(/&/g, "&") - .replace(/<SCRIPT[^>]*\>\s*<\!\[CDATA\[>?/i, "") - .replace(/<SCRIPT[^>]*\>(?:<\!\-\-)?/i, "") - .replace(/(\/\/)?\s*\&\#8211;>\s*<\/SCRIPT>/i, "") - .replace(/\-\->\s*<\/SCRIPT>/i, "") - .replace(/\]\](?:\>\;|>)\s*<\/SCRIPT>/i, "") - .replace(/<\/SCRIPT>$/mi, "") - .replace(/<\/?\s*(?:p|br)\s*\/?>/ig, "") - .replace(/<\!--\s*.*?\s*-->\s*<script.*/ig, "") - .replace(/\\+(['"])/g, "$1"); - - if (strXml.trim()) { - var xmlNode = jpf.getJmlDocFromString("<div jid='" - + (id++) + "' " + strXmlns + ">" - + strXml + "</div>").documentElement; - - if (jpf.isSafari) - xmlNode = jpf.AppNode.ownerDocument.importNode(xmlNode, true); - - jpf.AppNode.appendChild(xmlNode); - - jpf.jmlParts.push([node.parentNode, node.nextSibling]); - } - } - - //Walk entire html tree - if (!isPrefix && node.firstChild - || node.nextSibling) { - if (!isPrefix && node.firstChild) { - node = node.firstChild; - } - else { - node = node.nextSibling; - } - } - else { - do { - node = node.parentNode; - - if (node.tagName == "BODY") - node = null; - - } while (node && !node.nextSibling) - - if (node) { - node = node.nextSibling; - } - } - } - - if (temp) - temp.parentNode.removeChild(temp); - }, - - /** - * @private - */ - loadIncludes : function(docElement){ - var isEmptyDocument = false; - - if (this.parseStrategy == 1 || !this.parseStrategy && !docElement - && document.documentElement.outerHTML.split(">", 1)[0] - .indexOf(jpf.ns.jml) == -1) { - this.parsePartialJml(docElement); - - if (this.parseStrategy == 1 || jpf.jmlParts.length) { - if (jpf.jmlParts.length) - jpf.console.warn("Jml found, parsing..."); - - jpf.isParsingPartial = true; - - jpf.loadJmlIncludes(jpf.AppNode); - - if (!self.ERROR_HAS_OCCURRED) { - jpf.Init.interval = setInterval(function(){ - if (jpf.checkLoaded()) - jpf.initialize(); - }, 20); - } - - return; - } - else { - jpf.console.warn("No jml found."); - isEmptyDocument = true; - } - } - - - - if (isEmptyDocument && document.documentElement.outerHTML - .split(">", 1)[0] - .indexOf(jpf.ns.jml) == -1) { - jpf.console.warn("The jml namespace declaration wasn't found. \ - No jml elements were found in the body. Exiting"); - return false; - } - - //Load current HTML document as 'second DOM' - if (this.parseStrategy == 21 || !this.parseStrategy && !docElement) { - return jpf.oHttp.get((document.body.getAttribute("xmlurl") || location.href).split(/#/)[0], - function(xmlString, state, extra){ - if (state != jpf.SUCCESS) { - var oError; - oError = new Error(jpf.formatErrorString(0, null, - "Loading XML application data", "Could not load \ - XML from remote source: " + extra.message)); - - if (extra.tpModule.retryTimeout(extra, state, null, oError) === true) - return true; - - throw oError; - } - - jpf.lineBodyStart = (xmlString.replace(/\n/g, "\\n") - .match(/(.*)<body/) || [""])[0].split("\\n").length; - - var xmlNode = jpf.getJmlDocFromString(xmlString); - - //Clear Body - if (jpf.isIE) - document.body.innerHTML =""; - else { - var nodes = document.body.childNodes; - for (var i=nodes.length-1; i>=0; i--) - nodes[i].parentNode.removeChild(nodes[i]); - } - - return jpf.loadIncludes(xmlNode); - }, {ignoreOffline: true}); - } - - //Parse the second DOM (add includes) - var prefix = jpf.findPrefix(docElement, jpf.ns.jml); - if (jpf.isSafariOld || true) - prefix = "j"; - - if (!prefix) - throw new Error(jpf.formatErrorString(0, null, - "Parsing document", - "Unable to find Javeline PlatForm namespace definition. \ - (i.e. xmlns:j=\"" + jpf.ns.jml + "\")", docElement)); - - jpf.AppData = jpf.supportNamespaces - ? docElement.createElementNS(jpf.ns.jml, prefix + ":application") - : docElement.createElement(prefix + ":application"); - - var i, nodes; - //Head support - var head = $xmlns(docElement, "head", jpf.ns.xhtml)[0]; - if (head) { - nodes = head.childNodes; - for (i = nodes.length-1; i >= 0; i--) - if (nodes[i].namespaceURI && nodes[i].namespaceURI != jpf.ns.xhtml) - jpf.AppData.insertBefore(nodes[i], jpf.AppData.firstChild); - } - - //Body support - var body = (docElement.body - ? docElement.body - : $xmlns(docElement, "body", jpf.ns.xhtml)[0]); - for (i = 0; i < body.attributes.length; i++) - jpf.AppData.setAttribute(body.attributes[i].nodeName, - body.attributes[i].nodeValue); - - nodes = body.childNodes; - for (i = nodes.length - 1; i >= 0; i--) - jpf.AppData.insertBefore(nodes[i], jpf.AppData.firstChild); - docElement.documentElement.appendChild(jpf.AppData); //Firefox fix for selectNode insertion need... - - /* - jpf.AppData = docElement.body ? docElement.body : $xmlns(docElement.documentElement, "body", jpf.ns.xhtml)[0]; - */ - - jpf.loadJmlIncludes(jpf.AppData); - - if ($xmlns(jpf.AppData, "loader", jpf.ns.jml).length) { - jpf.loadScreen = { - show : function(){ - this.oExt.style.display = "block"; - //this.oExt.style.height = document.body.scrollHeight + "px"; - }, - - hide : function(){ - this.oExt.style.display = "none"; - } - } - - if (jpf.isGecko || jpf.isSafari) - document.body.innerHTML = ""; - - if (jpf.isSafariOld) { - var q = jpf.getFirstElement( - $xmlns(jpf.AppData, "loader", jpf.ns.jml)[0]).serialize(); - document.body.insertAdjacentHTML("beforeend", q); - jpf.loadScreen.oExt = document.body.lastChild; - } - else - { - var htmlNode = jpf.getFirstElement( - $xmlns(jpf.AppData, "loader", jpf.ns.jml)[0]); - - //if(jpf.isSafari) jpf.loadScreen = document.body.appendChild(document.importNode(htmlNode, true)); - if (htmlNode.ownerDocument == document) - jpf.loadScreen.oExt = document.body.appendChild( - htmlNode.cloneNode(true)); - else { - document.body.insertAdjacentHTML("beforeend", htmlNode.xml - || htmlNode.serialize()); - jpf.loadScreen.oExt = document.body.lastChild; - } - } - } - - document.body.style.display = "block"; //might wanna make this variable based on layout loading... - - if (!self.ERROR_HAS_OCCURRED) { - jpf.Init.interval = setInterval(function(){ - if (jpf.checkLoaded()) - jpf.initialize() - }, 20); - } - }, - - /** - * @private - */ - checkForJmlNamespace : function(xmlNode){ - if (!xmlNode.ownerDocument.documentElement) - return false; - - var nodes = xmlNode.ownerDocument.documentElement.attributes; - for (var found = false, i=0; i<nodes.length; i++) { - if (nodes[i].nodeValue == jpf.ns.jml) { - found = true; - break; - } - } - - if (!found) { - throw new Error(jpf.formatErrorString(0, null, - "Checking for the jml namespace", - "The Javeline PlatForm xml namespace was not found in " - + (xmlNode.getAttribute("filename") - ? "in '" + xmlNode.getAttribute("filename") + "'" - : ""))); - } - - return found; - }, - - /** - * @private - */ - loadJmlIncludes : function(xmlNode, doSync){ - - var i, nodes, path; - jpf.checkForJmlNamespace(xmlNode); - - var basePath = jpf.getDirname(xmlNode.getAttribute("filename")) || jpf.hostPath; - - nodes = $xmlns(xmlNode, "include", jpf.ns.jml); - if (nodes.length) { - xmlNode.setAttribute("loading", "loading"); - - for (i = nodes.length - 1; i >= 0; i--) { - if (!nodes[i].getAttribute("src")) - throw new Error(jpf.formatErrorString(0, null, "Loading includes", "Could not load Include file " + nodes[i].xml + ":\nCould not find the src attribute.")) - - path = jpf.getAbsolutePath(basePath, nodes[i].getAttribute("src")); - - jpf.loadJmlInclude(nodes[i], doSync, path); - } - } - else - xmlNode.setAttribute("loading", "done"); - - nodes = $xmlns(xmlNode, "skin", jpf.ns.jml); - for (i = 0; i < nodes.length; i++) { - if (!nodes[i].getAttribute("src") && !nodes[i].getAttribute("name") - || nodes[i].childNodes.length) - continue; - - path = nodes[i].getAttribute("src") - ? jpf.getAbsolutePath(basePath, nodes[i].getAttribute("src")) - : jpf.getAbsolutePath(basePath, nodes[i].getAttribute("name")) + "/index.xml"; - - jpf.loadJmlInclude(nodes[i], doSync, path, true); - - //nodes[i].parentNode.removeChild(nodes[i]); - nodes[i].setAttribute("j_preparsed", "9999") - } - - //XForms and lazy devs support - if (!nodes.length && !jpf.skins.skins["default"] && jpf.autoLoadSkin) { - jpf.console.warn("No skin file found, attempting to autoload the \ - default skin file: skins.xml"); - jpf.loadJmlInclude(null, doSync, "skins.xml", true); - } - - - return true; - }, - - /** - * @private - */ - loadJmlInclude : function(node, doSync, path, isSkin){ - - jpf.console.info("Loading include file: " + (path || node && node.getAttribute("src"))); - - this.oHttp.get(path || jpf.getAbsolutePath(jpf.hostPath, node.getAttribute("src")), - function(xmlString, state, extra){ - if (state != jpf.SUCCESS) { - var oError; - oError = new Error(jpf.formatErrorString(1007, - null, "Loading Includes", "Could not load Include file '" - + (path || extra.userdata[0].getAttribute("src")) - + "'\nReason: " + extra.message, node)); - - if (extra.tpModule.retryTimeout(extra, state, null, oError) === true) - return true; - - //Check if we are autoloading - if (!node) { - //Fail silently - jpf.console.warn("Could not autload skin."); - jpf.includeStack[extra.userdata[1]] = true; - return; - } - - throw oError; - } - - var xmlNode, isTeleport; - if (!isSkin) { - xmlNode = jpf.getJmlDocFromString(xmlString).documentElement; - var tagName = xmlNode[jpf.TAGNAME]; - - if (tagName == "skin") - isSkin = true; - else if (tagName == "teleport") - isTeleport = true; - else if(tagName != "application") { - throw new Error(jpf.formatErrorString(0, null, - "Loading Includes", - "Could not find handler to parse include file for '" - + xmlNode[jpf.TAGNAME] - + "' expected 'skin' or 'application'", node)); - } - } - - if (isSkin) { - if (xmlString.indexOf('xmlns="http://www.w3.org/1999/xhtml"') > -1){ - jpf.console.warn("Found xhtml namespace as global \ - namespace of skin file. This is not \ - allowed. Please remove this before \ - use in production environments.") - xmlString = xmlString.replace('xmlns="http://www.w3.org/1999/xhtml"', ''); - } - - xmlNode = jpf.getJmlDocFromString(xmlString).documentElement; - jpf.skins.Init(xmlNode, node, path); - jpf.includeStack[extra.userdata[1]] = true; - - if (jpf.isOpera && extra.userdata[0] && extra.userdata[0].parentNode) //for opera... - extra.userdata[0].parentNode.removeChild(extra.userdata[0]); - } - else if (isTeleport) { - jpf.teleport.loadJml(xmlNode); - jpf.includeStack[extra.userdata[1]] = true; - } - else { - jpf.includeStack[extra.userdata[1]] = xmlNode;//extra.userdata[0].parentNode.appendChild(xmlNode, extra.userdata[0]); - extra.userdata[0].setAttribute("iid", extra.userdata[1]); - } - - xmlNode.setAttribute("filename", extra.url); - - jpf.console.info("Loading of " + xmlNode[jpf.TAGNAME].toLowerCase() + " include done from file: " + extra.url); - - jpf.loadJmlIncludes(xmlNode); //check for includes in the include (NOT recursive save) - - }, { - async : !doSync, - userdata : [node, jpf.includeStack.push(false) - 1], - ignoreOffline : true - }); - - }, - - /** - * @private - */ - checkLoaded : function(){ - for (var i = 0; i < jpf.includeStack.length; i++) { - if (!jpf.includeStack[i]) { - jpf.console.info("Waiting for: [" + i + "] " + jpf.includeStack[i]); - return false; - } - } - - if (!document.body) return false; - - jpf.console.info("Dependencies loaded"); - - return true; - }, - - - /** - * @private - */ - initialize : function(){ - if (jpf.initialized) return; - jpf.initialized = true; - - jpf.console.info("Initializing..."); - clearInterval(jpf.Init.interval); - - // Run Init - jpf.Init.run(); //Process load dependencies - - - if (jpf.isParsingPartial) { - //Form jml parser - if (!jpf.window) { - jpf.window = new jpf.WindowImplementation(); - jpf.document = new jpf.DocumentImplementation(); - jpf.window.document = jpf.document; - jpf.window.$at = new jpf.actiontracker(); - jpf.nameserver.register("actiontracker", "default", jpf.window.$at); - } - - jpf.appsettings.init(); - jpf.hasSingleRszEvent = true; - - var pHtmlNode = document.body; - var lastChild = pHtmlNode.lastChild; - jpf.JmlParser.parseMoreJml(jpf.AppNode, pHtmlNode, null, - true, false); - - var pNode, firstNode, lastBefore = null, next, info, loop = pHtmlNode.lastChild; - while (loop && lastChild != loop) { - info = jpf.jmlParts[loop.getAttribute("jid")]; - next = loop.previousSibling; - if (info) { - pNode = info[0]; - if ("P".indexOf(pNode.tagName) > -1) { - lastBefore = pNode.parentNode.insertBefore(jpf.getNode(loop, [0]), - pNode); - } - else { - firstNode = jpf.getNode(loop, [0]); - while(firstNode){ - if (firstNode) { - lastBefore = pNode.insertBefore(firstNode, - typeof info[1] == "number" ? lastBefore : info[1]); - } - else { - lastBefore = typeof info[1] == "number" ? lastBefore : info[1]; - } - firstNode = jpf.getNode(loop, [0]); - } - } - - loop.parentNode.removeChild(loop); - } - loop = next; - } - - setTimeout("jpf.layout.forceResize();"); - } - else - { - // Start application - if (jpf.JmlParser && jpf.AppData) - jpf.JmlParser.parse(jpf.AppData); - - if (jpf.loadScreen && jpf.appsettings.autoHideLoading) - jpf.loadScreen.hide(); - } - }, - - addDomLoadEvent: function(func) { - if (!this.$bdetect) - this.browserDetect(); - - // create event function stack - var load_events = [], - load_timer, - done = arguments.callee.done, - exec, - init = function () { - if (done) return; - // kill the timer - clearInterval(load_timer); - load_timer = null; - done = true; - // execute each function in the stack in the order they were added - var len = load_events.length; - while (len--) { - (load_events.shift())(); - } - }; - - if (func && !load_events[0]) { - // for Mozilla/Opera9. - // Mozilla, Opera (see further below for it) and webkit nightlies currently support this event - if (document.addEventListener && !jpf.isOpera) { - // We're using "window" and not "document" here, because it results - // in a memory leak, especially in FF 1.5: - // https://bugzilla.mozilla.org/show_bug.cgi?id=241518 - // See also: - // http://bitstructures.com/2007/11/javascript-method-callbacks - // http://www-128.ibm.com/developerworks/web/library/wa-memleak/ - window.addEventListener("DOMContentLoaded", init, false); - } - // If IE is used and is not in a frame - else if (jpf.isIE && window == top) { - load_timer = setInterval(function() { - try { - // If IE is used, use the trick by Diego Perini - // http://javascript.nwbox.com/IEContentLoaded/ - document.documentElement.doScroll("left"); - } - catch(error) { - setTimeout(arguments.callee, 0); - return; - } - // no exceptions anymore, so we can call the init! - init(); - }, 10); - } - else if (jpf.isOpera) { - document.addEventListener( "DOMContentLoaded", function () { - load_timer = setInterval(function() { - for (var i = 0; i < document.styleSheets.length; i++) { - if (document.styleSheets[i].disabled) - return; - } - // all is fine, so we can call the init! - init(); - }, 10); - }, false); - } - else if (jpf.isSafari) { - var aSheets = documents.getElementsByTagName("link"); - for (var i = aSheets.length; i >= 0; i++) { - if (!aSheets[i] || aSheets[i].getAttribute("rel") != "stylesheet") - aSheets.splice(i, 0); - } - var iSheets = aSheets.length; - load_timer = setInterval(function() { - if (/loaded|complete/.test(document.readyState) - && document.styleSheets.length == iSheets) - init(); // call the onload handler - }, 10); - } - // for other browsers set the window.onload, but also execute the old window.onload - else { - var old_onload = window.onload; - window.onload = function () { - init(); - if (old_onload) - old_onload(); - }; - } - } - load_events.push(func); - }, - - /* Destroy */ - - /** - * Unloads the jml application. - */ - destroy : function(exclude){ - jpf.console.info("Initiating self destruct..."); - - this.isDestroying = true; - - - this.popup.destroy(); - - for (i = 0; i < this.all.length; i++) { - if (this.all[i] && this.all[i] != exclude && this.all[i].destroy) - this.all[i].destroy(false); - } - - for (i = this.$jmlDestroyers.length - 1; i >= 0; i--) - this.$jmlDestroyers[i].call(this); - this.$jmlDestroyers = undefined; - - jpf.teleport.destroy(); - - if (jpf.xmldb) - jpf.xmldb.unbind(jpf.window); - - this.isDestroying = false; - } -}; - -/* - * Replacement for getElementsByTagNameNS because some browsers don't support - * this call yet. - */ -var $xmlns = function(xmlNode, tag, xmlns, prefix){ - if (!jpf.supportNamespaces) { - if (!prefix) - prefix = jpf.findPrefix(xmlNode, xmlns); - - if (xmlNode.style || xmlNode == document) - return xmlNode.getElementsByTagName(tag) - else { - if (prefix) - (xmlNode.nodeType == 9 ? xmlNode : xmlNode.ownerDocument) - .setProperty("SelectionNamespaces", - "xmlns:" + prefix + "='" + xmlns + "'"); - - return xmlNode.selectNodes(".//" + (prefix ? prefix + ":" : "") + tag); - } - } - else - return xmlNode.getElementsByTagNameNS(xmlns, tag); -} - -jpf.Init.run('jpf'); - - -/*FILEHEAD(/var/lib/jpf/src/core/xmldatabase.js)SIZE(-1077090856)TIME(1238933677)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * The xml database object provides local storage for xml data. This object
- * routes all changes to the xml data to the data bound objects. It further
- * provides utility functions for xml handling.
- *
- * @constructor
- * @jpfclass
- *
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.8
- *
- * @default_private
- */
-jpf.XmlDatabase = function(){
- this.xmlDocTag = "j_doc";
- this.xmlIdTag = "j_id";
- this.xmlListenTag = "j_listen";
- this.htmlIdTag = "id";
-
- var xmlDocLut = [];
-
- /**
- * @private
- */
- this.getElementById = function(id, doc){
- if (!doc)
- doc = xmlDocLut[id.split("\|")[0]];
- if (!doc)
- return false;
-
- return doc.selectSingleNode("descendant-or-self::node()[@"
- + this.xmlIdTag + "='" + id + "']");
- };
-
- /**
- * @private
- */
- this.getNode = function(htmlNode){
- if (!htmlNode || !htmlNode.getAttribute(this.htmlIdTag))
- return false;
-
- return this.getElementById(htmlNode.getAttribute(this.htmlIdTag)
- .split("\|", 2).join("|"));
- };
-
- /**
- * @private
- */
- this.getNodeById = function(id, doc){
- var q = id.split("\|");
- q.pop();
- return this.getElementById(q.join("|"), doc);//id.split("\|", 2).join("|")
- };
-
- /**
- * @private
- */
- this.getDocumentById = function(id){
- return xmlDocLut[id];
- };
-
- /**
- * @private
- */
- this.getDocument = function(node){
- return xmlDocLut[node.getAttribute(this.xmlIdTag).split("\|")[0]];
- };
-
- /**
- * @private
- */
- this.getID = function(xmlNode, o){
- return xmlNode.getAttribute(this.xmlIdTag) + "|" + o.uniqueId;
- };
-
- /**
- * Gets the child position of a dom node.
- *
- * @param {DOMNode} node the node for which the child position is determined.
- * @return {Number} the child position of the node.
- */
- this.getChildNumber = function(node){
- var p = node.parentNode;
- for (var i = 0; i < p.childNodes.length; i++)
- if (p.childNodes[i] == node)
- return i;
- };
-
- /**
- * Determines whether a node is a child of another node.
- *
- * @param {DOMNode} pNode the potential parent element.
- * @param {DOMNode} childnode the potential child node.
- * @param {Boolean} [orItself] whether the method also returns true when pNode is the childnode.
- * @return {Number} the child position of the node. Or false if it's not a child.
- */
- this.isChildOf = function(pNode, childnode, orItself){
- if (!pNode || !childnode)
- return false;
-
- if (childnode.nodeType == 2)
- childnode = childnode.selectSingleNode("..");
-
- if (orItself && pNode == childnode)
- return true;
-
- var loopnode = childnode.parentNode;
- while(loopnode){
- if(loopnode == pNode)
- return true;
- loopnode = loopnode.parentNode;
- }
-
- return false;
- };
-
- /**
- * Determines whether a node is it's parent's only child.
- * @param {DOMNode} node the potential only child.
- * @param {Array} nodeType list of the node types that this child can be.
- * @returns {Boolean} whether the node is only child and optionally of one of the specified nodeTypes.
- */
- this.isOnlyChild = function(node, nodeType){
- if (!node || !node.parentNode || nodeType && nodeType.indexOf(node.nodeType) == -1)
- return false;
-
- var i, l, cnode, nodes = node.parentNode.childNodes;
- for (i = 0, l = nodes.length; i < l; i++) {
- cnode = nodes[i];
- if (cnode.nodeType == 1 && cnode != node)
- return false;
- if (cnode.nodeType == 3 && !cnode.nodeValue.trim())
- return false;
- }
-
- return true;
- };
-
- /**
- * Finds the html representation of an xml node for a certain element.
- *
- * @param {XMLNode} xmlNode the data element which is represented by the hml element.
- * @param {JMLNode} oComp the element that has created the representation.
- * @return {HTMLNode} the html node representing the xml node.
- */
- this.findHTMLNode = function(xmlNode, oComp){
- do {
- if (xmlNode.nodeType == 1 && xmlNode.getAttribute(this.xmlIdTag)) {
- return oComp.getNodeFromCache(xmlNode.getAttribute(this.xmlIdTag)
- + "|" + oComp.uniqueId);
- }
- if (xmlNode == oComp.xmlRoot)
- return null;
-
- xmlNode = xmlNode.parentNode;
- }
- while (xmlNode && xmlNode.nodeType != 9)
-
- return null;
- };
-
- /**
- * Finds the xml data node that is represented by the html node.
- *
- * @param {HTMLNode} htmlNode the html node representing the an xml node.
- * @return {XMLNode} the xml data element for which the html node is it's representation.
- */
- this.findXMLNode = function(htmlNode){
- if (!htmlNode)
- return false;
-
- while (htmlNode && htmlNode.nodeType == 1
- && htmlNode.tagName.toLowerCase() != "body"
- && !htmlNode.getAttribute("id")
- || htmlNode && htmlNode.nodeType == 1
- && htmlNode.getAttribute(this.htmlIdTag)
- && htmlNode.getAttribute(this.htmlIdTag).match(/^q/)) {
- if (htmlNode.host && htmlNode.host.oExt == htmlNode)
- return htmlNode.host.xmlRoot;
-
- htmlNode = htmlNode.parentNode;
- }
- if (!htmlNode || htmlNode.nodeType != 1)
- return false;
-
- if (htmlNode.tagName.toLowerCase() == "body")
- return false;
-
- return this.getNode(htmlNode);
- };
-
- /**
- * @private
- */
- this.getElement = function(parent, nr){
- var nodes = parent.childNodes;
- for (var j = 0, i = 0; i < nodes.length; i++) {
- if (nodes[i].nodeType != 1)
- continue;
- if (j++ == nr)
- return nodes[i];
- }
- };
-
- /**
- * @private
- */
- this.getModel = function(name){
- return jpf.nameserver.get("model", name);
- };
-
- /**
- * @private
- */
- this.setModel = function(model){
- jpf.nameserver.register("model", model.data.ownerDocument
- .documentElement.getAttribute(this.xmlDocTag), model);
- };
-
- /**
- * @private
- */
- this.findModel = function(xmlNode){
- return this.getModel(xmlNode.ownerDocument
- .documentElement.getAttribute(this.xmlDocTag));
- };
-
- /**
- * Creates an xml node from an xml string.
- *
- * @param {String} strXml the xml definition.
- * @param {Boolean} [noError] whether an exception is thrown the parser throws an error.
- * @return {XMLNode} the created xml node.
- */
- this.getXml = function(strXml, noError, preserveWhiteSpace){
- return jpf.getXmlDom(strXml, noError, preserveWhiteSpace).documentElement;
- };
-
- this.getXmlId = function(xmlNode){
- return xmlNode.getAttribute(this.xmlIdTag) ||
- this.nodeConnect(jpf.xmldb.getXmlDocId(xmlNode), xmlNode);
- }
-
- this.nodeCount = {};
- /**
- * @private
- */
- this.nodeConnect = function(documentId, xmlNode, htmlNode, o){
- if (!this.nodeCount[documentId])
- this.nodeCount[documentId] = 0;
-
- var xmlId;
- xmlId = xmlNode.getAttribute(this.xmlIdTag)
- || xmlNode.setAttribute(this.xmlIdTag, (xmlId = documentId
- + "|" + ++this.nodeCount[documentId])) || xmlId;
-
- if (!o)
- return xmlId;
-
- var htmlId = xmlId + "|" + o.uniqueId;
- if (htmlNode)
- htmlNode.setAttribute(this.htmlIdTag, htmlId);
-
- return htmlId;
- };
-
- /**
- * @private
- */
- this.addNodeListener = function(xmlNode, o){
- if (!o.$xmlUpdate)
- throw new Error(jpf.formatErrorString(1040, null,
- "Adding Node listener",
- "Cannot attach this listener because it doesn't support the \
- correct interface (this.$xmlUpdate)."));
-
- var listen = xmlNode.getAttribute(this.xmlListenTag);
- var nodes = (listen ? listen.split(";") : []);
- var id = String(o.uniqueId);
-
- if (!nodes.contains(id)) {
- nodes.push(id);
- xmlNode.setAttribute(this.xmlListenTag, nodes.join(";"));
- }
-
- return xmlNode;
- };
-
- /**
- * @todo Use this function when an element really unbinds from a
- * piece of data and does not uses it for caching
- * @private
- */
- this.removeNodeListener = function(xmlNode, o){
- var listen = xmlNode.getAttribute(this.xmlListenTag);
- var nodes = (listen ? listen.split(";") : []);
-
- for (var newnodes = [], i = 0; i < nodes.length; i++) {
- if (nodes[i] != o.uniqueId)
- newnodes.push(nodes[i]);
- }
-
- xmlNode.setAttribute(this.xmlListenTag, newnodes.join(";"));
-
- return xmlNode;
- };
-
- //Does this need to be a seperate function??
- /**
- * @private
- */
- this.clearVirtualDataset = function(parentNode){
- var nodes = parentNode.childNodes;
- for (var i = nodes.length - 1; i >= 0; i--)
- parentNode.removeChild(nodes[i]);
- };
-
- /**
- * @private
- */
- this.createVirtualDataset = function(xmlNode, length, docId) {
- var marker = xmlNode.selectSingleNode("j_marker") || xmlNode.appendChild(xmlNode.ownerDocument.createElement("j_marker"));
- marker.setAttribute("start", "0");
-
- if (length) {
- marker.setAttribute("end", length);
- marker.setAttribute("reserved", ++this.nodeCount[docId]);
- this.nodeCount[docId] += length;
- }
- };
-
- /**
- * Integrates nodes as children of a parent. Optionally attributes are
- * copied as well.
- *
- * @param {XMLNode} xmlNode the data to integrate.
- * @param {XMLNode} parent the point of integration.
- * @param {Object} options
- * Properties:
- * {Boolean} [copyAttributes] whether the attributes of xmlNode are copied as well.
- * {Boolean} [clearContents] whether the contents of parent is cleared.
- * {Boolean} [start] This feature is used for the virtual viewport. More information will follow.
- * {Boolean} [length] This feature is used for the virtual viewport. More information will follow.
- * {Boolean} [documentId] This feature is used for the virtual viewport. More information will follow.
- * {Boolean} [marker] This feature is used for the virtual viewport. More information will follow.
- * @return {XMLNode} the created xml node
- */
- this.integrate = function(XMLRoot, parentNode, options){
- if (typeof parentNode != "object")
- parentNode = getElementById(parentNode);
-
- if (options && options.clearContents) {
- //Signal listening elements
- var node, j, i, nodes = parentNode.selectNodes("descendant::node()[@" + this.xmlListenTag + "]");
- for (i = nodes.length - 1; i >= 0; i--) {
- var s = nodes[i].getAttribute(this.xmlListenTag).split(";");
- for (j = s.length - 1; j >= 0; j--) {
- node = jpf.all[s[j]];
- if (node.dataParent && node.dataParent.xpath)
- node.dataParent.parent.signalXmlUpdate[node.uniqueId] = true;
- else if (node.$model) {
- node.$listenRoot = jpf.xmldb.addNodeListener(parentNode, node);
- node.xmlRoot = null; //.load(null)
- }
- }
- }
-
- //clean parent
- var nodes = parentNode.childNodes;
- for (var i = nodes.length - 1; i >= 0; i--)
- parentNode.removeChild(nodes[i]);
- }
-
- if (options && options.start) { //Assuming each node is in count
- var reserved, beforeNode, nodes, doc, i, l, marker = options.marker;
- if (!marker){
- //optionally find marker
- }
-
- //This code assumes that the dataset fits inside this marker
-
- //Start of marker
- if (marker.getAttribute("start") - options.start == 0) {
- marker.setAttribute("start", options.start + options.length);
- reserved = parseInt(marker.getAttribute("reserved"));
- marker.setAttribute("reserved", reserved + options.length);
- beforeNode = marker;
- }
- //End of marker
- else if (options.start + options.length == marker.getAttribute("end")) {
- marker.setAttribute("end", options.start + options.length);
- beforeNode = marker.nextSibling;
- reserved = parseInt(marker.getAttribute("reserved")) + parseInt(marker.getAttribute("end")) - options.length;
- }
- //Middle of marker
- else {
- var m2 = marker.parentNode.insertBefore(marker.cloneNode(true), marker);
- m2.setAttribute("end", options.start - 1);
- marker.setAttribute("start", options.start + options.length);
- reserved = parseInt(marker.getAttribute("reserved"));
- marker.setAttribute("reserved", reserved + options.length);
- beforeNode = marker;
- }
-
- nodes = XMLRoot.childNodes;
-
- if (parentNode.ownerDocument.importNode) {
- doc = parentNode.ownerDocument;
- for (i = 0, l = nodes.length; i < l; i++) {
- parentNode.insertBefore(doc.importNode(nodes[i], true), beforeNode)
- .setAttribute(this.xmlIdTag, options.documentId + "|" + (reserved + i));
- }
- }
- else {
- for (i = nodes.length - 1; i >= 0; i--) {
- parentNode.insertBefore(nodes[0], beforeNode)
- .setAttribute(this.xmlIdTag, options.documentId + "|" + (reserved + i));
- }
- }
- }
- else
- {
- beforeNode = jpf.getNode(parentNode, [0]);
- nodes = XMLRoot.childNodes;
-
- if (parentNode.ownerDocument.importNode) {
- doc = parentNode.ownerDocument;
- for (i = 0, l = nodes.length; i < l; i++)
- parentNode.insertBefore(doc.importNode(nodes[i], true), beforeNode);
- }
- else
- for (i = nodes.length - 1; i >= 0; i--)
- parentNode.insertBefore(nodes[0], beforeNode);
- }
-
- if (options && options.copyAttributes) {
- var attr = XMLRoot.attributes;
- for (i = 0; i < attr.length; i++)
- if (attr[i].nodeName != this.xmlIdTag)
- parentNode.setAttribute(attr[i].nodeName, attr[i].nodeValue);
- }
-
- return parentNode;
- };
-
- /**
- * @private
- * @description Integrates current xmldb with parent xmldb
- *
- * - assuming transparency of XMLDOM elements cross windows
- * with no performence loss.
- */
- this.synchronize = function(){
- this.forkRoot.parentNode.replaceChild(this.root, this.forkRoot);
- this.parent.applyChanges("synchronize", this.root);
- };
-
- /**
- * Returns a cleaned copy of the passed xml data element.
- *
- * @param {XMLElement} xmlNode the xml element to copy.
- * @return {XMLElement} the copy of the xml element.
- */
- this.copyNode = function(xmlNode){
- return this.clearConnections(xmlNode.cloneNode(true));
- };
-
- /**
- * Sets the nodeValue of a dom node.
- *
- * @param {XMLElement} xmlNode the xml node that should receive the nodeValue. When an element node is passed the first text node is set.
- * @param {String} nodeValue the value to set.
- * @param {Boolean} applyChanges whether the changes are propagated to the databound elements.
- * @param {UndoObj} undoObj the undo object that is responsible for archiving the changes.
- */
- this.setNodeValue = function(xmlNode, nodeValue, applyChanges, options){
- var undoObj, xpath, newNodes;
- if (options) {
- undoObj = options.undoObj;
- xpath = options.xpath;
- newNodes = options.newNodes;
-
- undoObj.extra.oldValue = options.forceNew
- ? ""
- : jpf.getXmlValue(xmlNode, xpath);
-
- undoObj.xmlNode = xmlNode;
- if (xpath)
- xmlNode = jpf.xmldb.createNodeFromXpath(xmlNode, xpath, newNodes, options.forceNew);
-
- undoObj.extra.appliedNode = xmlNode;
- }
-
- if (xmlNode.nodeType == 1) {
- if (!xmlNode.firstChild)
- xmlNode.appendChild(xmlNode.ownerDocument.createTextNode("-"));
-
- xmlNode.firstChild.nodeValue = jpf.isNot(nodeValue) ? "" : nodeValue;
-
- if (applyChanges)
- jpf.xmldb.applyChanges("synchronize", xmlNode, undoObj);
- }
- else {
- xmlNode.nodeValue = jpf.isNot(nodeValue) ? "" : nodeValue;
-
- if (applyChanges)
- jpf.xmldb.applyChanges("synchronize", xmlNode.parentNode
- || xmlNode.ownerElement || xmlNode.selectSingleNode(".."),
- undoObj);
- }
- };
-
- /**
- * Retrieves the node value of an xml element. When an element node is passed
- * the value of the first text node is returned.
- * @returns {String} the node value found.
- */
- this.getNodeValue = function(xmlNode){
- if (!xmlNode)
- return "";
- return xmlNode.nodeType == 1
- ? (!xmlNode.firstChild ? "" : xmlNode.firstChild.nodeValue)
- : xmlNode.nodeValue;
- };
-
- /**
- * Retrieves the attribute of an xml node or the first parent node that has
- * that attribute set. If no attribute is set the value is looked for on
- * the appsettings element.
- *
- * @param {XMLElement} xml the xml node that is the starting point of the search.
- * @param {String} attr the name of the attribute.
- * @param {Function} [func] callback that is run for every node that is searched.
- * @return {String} the found value, or empty string if none was found.
- */
- this.getInheritedAttribute = function(xml, attr, func){
- var result;
-
- while (xml && xml.nodeType != 11 && xml.nodeType != 9
- && !(result = attr && xml.getAttribute(attr) || func && func(xml))) {
- xml = xml.parentNode;
- }
-
- return !result && attr && jpf.appsettings
- ? jpf.appsettings.tags[attr]
- : result;
- };
-
- /**
- * Sets the value of a text node. If the node doesn't exists it is created.
- * Changes are propagated to the databound elements listening for changes
- * on the data changed.
- *
- * @param {XMLElement} pNode the parent of the text node.
- * @param {String} value the value of the text node.
- * @param {String} [xpath] the xpath statement which selects the text node.
- * @param {UndoObj} [undoObj] the undo object that is responsible for archiving the changes.
- */
- this.setTextNode = function(pNode, value, xpath, undoObj){
- var tNode;
-
- if (xpath) {
- tNode = pNode.selectSingleNode(xpath);
- if (!tNode)
- return;
- pNode = tNode.nodeType == 1 ? tNode : null;
- }
- if (pNode || !tNode) {
- tNode = pNode.selectSingleNode("text()");
-
- if (!tNode)
- tNode = pNode.appendChild(pNode.ownerDocument.createTextNode(""));//createCDATASection
- }
-
- //Action Tracker Support
- if (undoObj)
- undoObj.extra.oldValue = tNode.nodeValue;
-
- //Apply Changes
- tNode.nodeValue = value;
-
- this.applyChanges("text", tNode.parentNode, undoObj);
-
- this.applyRSB(["setTextNode", pNode, value, xpath], undoObj);
- };
-
- /**
- * Sets an attribute on a node. Changes are propagated to the databound
- * elements listening for changes on the data changed.
- *
- * @param {XMLElement} xmlNode the xml node to set the attribute on.
- * @param {String} name the name of the attribute.
- * @param {String} value the value of the attribute.
- * @param {String} [xpath] the xpath statement to select the attribute.
- * @param {UndoObj} [undoObj] the undo object that is responsible for archiving the changes.
- */
- this.setAttribute = function(xmlNode, name, value, xpath, undoObj){
- //if(xmlNode.nodeType != 1) xmlNode.nodeValue = value;
- //Apply Changes
- (xpath ? xmlNode.selectSingleNode(xpath) : xmlNode).setAttribute(name, value);
- this.applyChanges("attribute", xmlNode, undoObj);
- this.applyRSB(["setAttribute", xmlNode, name, value, xpath], undoObj);
- };
-
- /**
- * Removes an attribute of an xml node. Changes are propagated to the
- * databound elements listening for changes on the data changed.
- *
- * @param {XMLElement} xmlNode the xml node to delete the attribute from
- * @param {String} name the name of the attribute.
- * @param {String} [xpath] the xpath statement to select the attribute.
- * @param {UndoObj} [undoObj] the undo object that is responsible for archiving the changes.
- */
- this.removeAttribute = function(xmlNode, name, xpath, undoObj){
- //if(xmlNode.nodeType != 1) xmlNode.nodeValue = value;
-
- //Action Tracker Support
- if (undoObj) undoObj.name = name;
-
- //Apply Changes
- (xpath ? xmlNode.selectSingleNode(xpath) : xmlNode).removeAttribute(name);
- this.applyChanges("attribute", xmlNode, undoObj);
-
- this.applyRSB(["removeAttribute", xmlNode, name, xpath], undoObj);
- };
-
- /**
- * Replace one node with another. Changes are propagated to the
- * databound elements listening for changes on the data changed.
- *
- * @param {XMLElement} oldNode the xml node to remove.
- * @param {XMLElement} newNode the xml node to set.
- * @param {String} [xpath] the xpath statement to select the attribute.
- * @param {UndoObj} [undoObj] the undo object that is responsible for archiving the changes.
- */
- this.replaceNode = function(oldNode, newNode, xpath, undoObj){
- //if(xmlNode.nodeType != 1) xmlNode.nodeValue = value;
-
- //Apply Changes
- if (xpath)
- oldNode = oldNode.selectSingleNode(xpath);
-
- //Action Tracker Support
- if (undoObj) {
- undoObj.oldNode = oldNode;
- undoObj.xmlNode = newNode;
- }
-
- oldNode.parentNode.replaceChild(newNode, oldNode);
- this.copyConnections(oldNode, newNode);
-
- this.applyChanges("replacechild", newNode, undoObj);
-
- this.applyRSB(["replaceChild", oldNode, newNode, xpath], undoObj);
- };
-
- /**
- * Creates a new element under a parent xml node. Changes are propagated
- * to the databound elements listening for changes on the data changed.
- *
- * @param {XMLElement} pNode the parent xml node to add the new element to.
- * @param {String} tagName the tagName of the xml element to add.
- * @param {Array} attr list of the attributes to set. Each item is another array with the name and value.
- * @param {XMLElement} beforeNode the xml node which indicates the insertion point.
- * @param {String} [xpath] the xpath statement to select the attribute.
- * @param {UndoObj} [undoObj] the undo object that is responsible for archiving the changes.
- */
- this.addChildNode = function(pNode, tagName, attr, beforeNode, undoObj){
- //Create New Node
- var xmlNode = pNode.insertBefore(pNode.ownerDocument
- .createElement(tagName), beforeNode);
-
- //Set Attributes
- for (var i = 0; i < attr.length; i++)
- xmlNode.setAttribute(attr[i][0], attr[i][1]);
-
- //Action Tracker Support
- if (undoObj)
- undoObj.extra.addedNode = xmlNode;
-
- this.applyChanges("add", xmlNode, undoObj);
-
- this.applyRSB(["addChildNode", pNode, tagName, attr, beforeNode], undoObj);
-
- return xmlNode;
- };
-
- /**
- * Appends an xml node to a parent. Changes are propagated
- * to the databound elements listening for changes on the data changed.
- *
- * @param {XMLElement} pNode the parent xml node to add the element to.
- * @param {XMLElement} xmlNode the xml node to insert.
- * @param {XMLElement} beforeNode the xml node which indicates the insertion point.
- * @param {Boolean} unique whether the parent can only contain one element with a certain tagName.
- * @param {String} [xpath] the xpath statement to select the parent node.
- * @param {UndoObj} [undoObj] the undo object that is responsible for archiving the changes.
- */
- this.appendChild = function(pNode, xmlNode, beforeNode, unique, xpath, undoObj){
- if (unique && pNode.selectSingleNode(xmlNode.tagName))
- return false;
-
- if (undoObj)
- this.clearConnections(xmlNode);
-
- if (jpf.isSafari && pNode.ownerDocument != xmlNode.ownerDocument)
- xmlNode = pNode.ownerDocument.importNode(xmlNode, true); //Safari issue not auto importing nodes
-
- //Add xmlNode to parent pNode or one selected by xpath statement
-
- if (xpath) {
- var addedNodes = [];
- var pNode = this.createNodeFromXpath(pNode, xpath, addedNodes);
- if (addedNodes.length) {
- pNode.appendChild(xmlNode);
- while(addedNodes.length) {
- if (pNode == addedNodes.pop() && addedNodes.length)
- pNode = pNode.parentNode;
- }
- }
- }
-
- pNode.insertBefore(xmlNode, beforeNode);
-
- //detect if xmlNode should be removed somewhere else
- //- [17-2-2004] changed pNode (2nd arg applychange) into xmlNode
-
- this.applyChanges("add", xmlNode, undoObj);
-
- this.applyRSB(["appendChild", pNode, xmlNode.xml, beforeNode, unique, xpath], undoObj);
-
- return xmlNode;
- };
-
- /**
- * Moves an xml node to a parent node. Changes are propagated
- * to the databound elements listening for changes on the data changed.
- *
- * @param {XMLElement} pNode the new parent xml node of the node.
- * @param {XMLElement} xmlNode the xml node to move.
- * @param {XMLElement} beforeNode the xml node which indicates the insertion point.
- * @param {String} [xpath] the xpath statement to select the parent node.
- * @param {UndoObj} [undoObj] the undo object that is responsible for archiving the changes.
- */
- this.moveNode = function(pNode, xmlNode, beforeNode, xpath, undoObj){
- //Action Tracker Support
- if (!undoObj)
- undoObj = {extra:{}};
-
- undoObj.extra.oldParent = xmlNode.parentNode;
- undoObj.extra.beforeNode = xmlNode.nextSibling;
- undoObj.extra.parent = (xpath ? pNode.selectSingleNode(xpath) : pNode);
-
- this.applyChanges("move-away", xmlNode, undoObj);
-
- this.applyRSB(["moveNode", pNode, xmlNode, beforeNode, xpath], undoObj); //note: important that transport of rsb is async
-
- //Set new id if the node change document (for safari this should be fixed)
- if (!jpf.isSafari
- && jpf.xmldb.getXmlDocId(xmlNode) != jpf.xmldb.getXmlDocId(pNode)) {
- xmlNode.removeAttributeNode(xmlNode.getAttributeNode(this.xmlIdTag));
- this.nodeConnect(jpf.xmldb.getXmlDocId(pNode), xmlNode);
- }
-
- if (jpf.isSafari && pNode.ownerDocument != xmlNode.ownerDocument)
- xmlNode = pNode.ownerDocument.importNode(xmlNode, true); //Safari issue not auto importing nodes
-
- undoObj.extra.parent.insertBefore(xmlNode, beforeNode);
- this.applyChanges("move", xmlNode, undoObj);
- };
-
- /**
- * Removes an xml node from it's parent. Changes are propagated
- * to the databound elements listening for changes on the data changed.
- *
- * @param {XMLElement} xmlNode the xml node to remove from the dom tree.
- * @param {String} [xpath] the xpath statement to select the parent node.
- * @param {UndoObj} [undoObj] the undo object that is responsible for archiving the changes.
- */
- this.removeNode = function(xmlNode, xpath, undoObj){
- if (xpath)
- xmlNode = xmlNode.selectSingleNode(xpath);
-
- //ActionTracker Support
- if (undoObj) {
- undoObj.extra.parent = xmlNode.parentNode;
- undoObj.extra.removedNode = xmlNode;
- undoObj.extra.beforeNode = xmlNode.nextSibling;
- }
-
- this.applyRSB(["removeNode", xmlNode, xpath], undoObj); //note: important that transport of rsb is async
-
- //Apply Changes
- this.applyChanges("remove", xmlNode, undoObj);
- var p = xmlNode.parentNode;
- p.removeChild(xmlNode);
- this.applyChanges("redo-remove", xmlNode, null, p);//undoObj
- };
-
- /**
- * Removes a list of xml nodes from their parent. Changes are propagated
- * to the databound elements listening for changes on the data changed.
- *
- * @param {Array} xmlNodeList list of xml nodes to remove.
- * @param {UndoObj} [undoObj] the undo object that is responsible for archiving the changes.
- */
- this.removeNodeList = function(xmlNodeList, undoObj){
- //if(xpath) xmlNode = xmlNode.selectSingleNode(xpath);
- for (var rData = [], i = 0; i < xmlNodeList.length; i++) { //This can be optimized by looping nearer to xmlUpdate
- //ActionTracker Support
- if (undoObj) {
- rData.push({
- pNode : xmlNodeList[i].parentNode,
- removedNode: xmlNodeList[i],
- beforeNode : xmlNodeList[i].nextSibling
- });
- }
-
- //Apply Changes
- this.applyChanges("remove", xmlNodeList[i], undoObj);
- var p = xmlNodeList[i].parentNode;
- p.removeChild(xmlNodeList[i]);
- this.applyChanges("redo-remove", xmlNodeList[i], null, p);//undoObj
- }
-
- if (undoObj)
- undoObj.extra.removeList = rData;
-
- this.applyRSB(["removeNodeList", xmlNodeList, null], undoObj);
- };
-
- /**
- * Looks for listeners and executes their __xmlUpdate methods.
- * @private
- */
- var notifyQueue = {}, notifyTimer;
- this.applyChanges = function(action, xmlNode, undoObj, nextloop){
- if (typeof jpf.offline != "undefined" && jpf.offline.models.enabled
- && jpf.offline.models.realtime) {
- var model = jpf.nameserver.get("model", jpf.xmldb.getXmlDocId(xmlNode));
- if (model) jpf.offline.models.markForUpdate(model);
- }
-
- if (undoObj && !undoObj.xmlNode) //@todo are we sure about this?
- undoObj.xmlNode = xmlNode;
-
- //Set Variables
- var oParent = nextloop;
- var loopNode = (xmlNode.nodeType == 1 ? xmlNode : xmlNode.parentNode);
-
- var xmlId = xmlNode.getAttribute(this.xmlIdTag);
-
- if (!this.delayUpdate && "|remove|move-away|".indexOf("|" + action + "|") > -1)
- this.notifyQueued(); //empty queue
-
- var listen, uIds, i, j, hash, info, jmlNode, runTimer, found;
- while (loopNode && loopNode.nodeType != 9) {
- //Get List of Node listeners ID's
- listen = loopNode.getAttribute(this.xmlListenTag);
-
- if (listen) {
- uIds = listen.split(";");
-
- for (i = 0; i < uIds.length; i++) {
- hash = notifyQueue[uIds[i]];
- if (!hash)
- notifyQueue[uIds[i]] = hash = [];
-
- // Filtering
- if ("|update|attribute|text|".indexOf("|"
- + action + "|") > -1) {
- found = false;
- for (j = 0; j < hash.length; j++) {
- if (hash[j] && xmlNode == hash[j][1]
- && "|update|attribute|text|"
- .indexOf("|" + hash[j][0] + "|") > -1) {
- hash[j] = null;
- found = true;
- continue;
- }
- }
-
- hash.push(["update", xmlNode, loopNode, undoObj, oParent]);
- runTimer = true;
- continue;
- }
-
- if (!this.delayUpdate && "|remove|move-away|add|".indexOf("|" + action + "|") > -1) {
- jmlNode = jpf.lookup(uIds[i]);
- if (jmlNode)
- jmlNode.$xmlUpdate(action, xmlNode,
- loopNode, undoObj, oParent);
- }
- else {
- hash.push([action, xmlNode, loopNode, undoObj, oParent]);
- runTimer = true;
- }
- }
- }
-
- //Go one level up
- loopNode = loopNode.parentNode || nextloop;
- if (loopNode == nextloop)
- nextloop = null;
- }
-
- if (undoObj && !this.delayUpdate) {
- //Ok this was an action let's not delay execution
- jpf.xmldb.notifyQueued();
- }
- else if (runTimer) {
- clearTimeout(notifyTimer);
- notifyTimer = setTimeout(function(){
- jpf.xmldb.notifyQueued();
- });
- }
- };
-
- /**
- * @todo in actiontracker - add stack auto purging
- * - when undo item is purged which was a removed, remove cache item
- * @todo shouldn't the removeNode method remove all listeners?
- * @todo rename to processQueue
- * @private
- */
- this.notifyQueued = function(){
- clearTimeout(notifyTimer);
-
- for (var uId in notifyQueue) {
- var q = notifyQueue[uId];
- jmlNode = jpf.lookup(uId);
- if (!jmlNode || !q)
- continue;
-
- //Check if component is just waiting for data to become available
- if (jmlNode.$listenRoot) {
- var model = jmlNode.getModel();
-
- if (!model)
- throw new Error(jpf.formatErrorString(this,
- "Notifying Component of data change",
- "Component without a model is listening for changes",
- jmlNode.$jml));
-
- var xpath = model.getXpathByJmlNode(jmlNode);
- var xmlRoot = xpath
- ? model.data.selectSingleNode(xpath)
- : model.data;
- if (xmlRoot) {
- jpf.xmldb.removeNodeListener(jmlNode.$listenRoot, jmlNode);
- jmlNode.$listenRoot = null;
- jmlNode.load(xmlRoot);
- }
-
- continue;
- }
-
- //Run queue items
- for (var i = 0; i < q.length; i++) {
- if (!q[i])
- continue;
-
- //Update xml data
- jmlNode.$xmlUpdate.apply(jmlNode, q[i]);
- }
- }
-
- notifyQueue = {}; // update shouldn't add anything to the queue
- }
-
- /**
- * @private
- */
- this.notifyListeners = function(xmlNode){
- //This should be done recursive
- var listen = xmlNode.getAttribute(jpf.xmldb.xmlListenTag);
- if (listen) {
- listen = listen.split(";");
- for (var j = 0; j < listen.length; j++) {
- jpf.lookup(listen[j]).$xmlUpdate("synchronize", xmlNode, xmlNode);
- //load(xmlNode);
- }
- }
- };
-
- /**
- * Sents Message through transport to tell remote databound listeners
- * that data has been changed
- * @private
- */
- this.applyRSB = function(args, undoObj){
- if (this.disableRSB)
- return;
-
- var xmlNode = args[1] && args[1].length && args[1][0] || args[1];
- var model = jpf.nameserver.get("model", jpf.xmldb.getXmlDocId(xmlNode));
- if (!model) {
- if (!jpf.nameserver.getAll("remove").length)
- return;
-
- jpf.console.warn("Could not find model for Remote SmartBinding connection, not sending change");
- return;
- }
-
- if (!model.rsb) return;
-
- // Add the messages to the undo object
- if (undoObj)
- model.rsb.queueMessage(args, model, undoObj);
- // Or sent message now
- else
- model.rsb.sendChange(args, model);
-
- };
-
- /**
- * @private
- */
- this.copyConnections = function(fromNode, toNode){
- //This should copy recursive
- try {
- toNode.setAttribute(this.xmlListenTag, fromNode.getAttribute(this.xmlListenTag));
- toNode.setAttribute(this.xmlIdTag, fromNode.getAttribute(this.xmlIdTag));
- }
- catch (e) {}
- };
-
- /**
- * @private
- */
- this.clearConnections = function(xmlNode){
- try {
- var i, nodes = xmlNode.selectNodes("descendant-or-self::node()[@" + this.xmlListenTag + "]");
- for (i = nodes.length - 1; i >= 0; i--)
- nodes[i].removeAttribute(this.xmlListenTag);
- nodes = xmlNode.selectNodes("descendant-or-self::node()[@" + this.xmlIdTag + "]");
- for (i = nodes.length - 1; i >= 0; i--)
- nodes[i].removeAttribute(this.xmlIdTag);
- nodes = xmlNode.selectNodes("descendant-or-self::node()[@" + this.xmlDocTag + "]");
- for (i = nodes.length - 1; i >= 0; i--)
- nodes[i].removeAttribute(this.xmlDocTag);
- nodes = xmlNode.selectNodes("descendant-or-self::node()[@j_loaded]");
- for (i = nodes.length - 1; i >= 0; i--)
- nodes[i].removeAttribute("j_loaded");
- // var nodes = xmlNode.selectNodes("descendant-or-self::node()[@j_selection]");
- // for (var i = nodes.length - 1; i >= 0; i--)
- // nodes[i].removeAttributeNode(nodes[i].getAttributeNode("j_selection"));
- }
- catch (e) {}
-
- return xmlNode;
- };
-
- /**
- * Returns a string version of the xml data element.
- *
- * @param {XMLElement} xmlNode the xml element to serialize.
- * @return {String} the serilized version of the xml element.
- */
- this.serializeNode = function(xmlNode){
- var xml = this.clearConnections(xmlNode.cloneNode(true));
- return xml.xml || xml.serialize();
- };
-
- /**
- * Unbind all Javeline Elements from a certain Form
- * @private
- */
- this.unbind = function(frm){
- //Loop through objects of all jpf
- for (var lookup = {}, i = 0; i < frm.jpf.all.length; i++)
- if (frm.jpf.all[i] && frm.jpf.all[i].unloadBindings)
- lookup[frm.jpf.all[i].unloadBindings()] = true;
-
- //Remove Listen Nodes
- for (var k = 0; k < xmlDocLut.length; k++) {
- if (!xmlDocLut[k]) continue;
-
- var Nodes = xmlDocLut[k].selectNodes("//self::node()[@"
- + this.xmlListenTag + "]");
-
- //Loop through Nodes and rebuild listen array
- for (var i = 0; i < Nodes.length; i++) {
- var listen = Nodes[i].getAttribute(this.xmlListenTag).split(";");
- for (var nListen = [], j = 0; j < listen.length; j++)
- if (!lookup[listen[j]])
- nListen.push(listen[j]);
-
- //Optimization??
- if (nListen.length != listen.length)
- Nodes[i].setAttribute(this.xmlListenTag, nListen.join(";"));
- }
- }
- };
-
- /**
- * Executes an xpath expression on any dom node. This is especially useful
- * for dom nodes that don't have a good native xpath processor such as html
- * in some versions of internet explorer and xml in webkit.
- *
- * @param {String} sExpr the xpath expression.
- * @param {DOMNode} contextNode the xml node that is subject to the query.
- * @returns {Array} list of xml nodes found. The list can be empty.
- */
- this.selectNodes = function(sExpr, contextNode){
- if (contextNode && (jpf.hasXPathHtmlSupport && contextNode.selectSingleNode || !contextNode.style))
- return contextNode.selectNodes(sExpr); //IE55
- //if (contextNode.ownerDocument != document)
- // return contextNode.selectNodes(sExpr);
-
- return jpf.XPath.selectNodes(sExpr, contextNode)
- };
-
- /**
- * Executes an xpath expression on any dom node. This is especially useful
- * for dom nodes that don't have a good native xpath processor such as html
- * in some versions of internet explorer and xml in webkit. This function
- * Only returns the first node found.
- *
- * @param {String} sExpr the xpath expression.
- * @param {DOMNode} contextNode the dom node that is subject to the query.
- * @returns {XMLNode} the dom node found or null if none was found.
- */
- this.selectSingleNode = function(sExpr, contextNode){
- if (contextNode && (jpf.hasXPathHtmlSupport && contextNode.selectSingleNode || !contextNode.style))
- return contextNode.selectSingleNode(sExpr); //IE55
- //if (contextNode.ownerDocument != document)
- // return contextNode.selectSingleNode(sExpr);
-
- var nodeList = this.selectNodes(sExpr + (jpf.isIE ? "" : "[1]"),
- contextNode ? contextNode : null);
- return nodeList.length > 0 ? nodeList[0] : null;
- };
-
- /**** General XML Handling ****/
-
- /**
- * Creates an xml node based on an xpath statement.
- *
- * @param {DOMNode} contextNode the dom node that is subject to the query.
- * @param {String} xPath the xpath query.
- * @param {Array} [addedNodes] this array is filled with the nodes added.
- * @param (Boolean) [forceNew] wether a new node is always created.
- * @return {DOMNode} the last element found.
- * @todo generalize this to include attributes in if format []
- */
- this.createNodeFromXpath = function(contextNode, xPath, addedNodes, forceNew){
- var xmlNode, foundpath = "", paths = xPath.split("\|")[0].split("/");
- if (!forceNew && (xmlNode = contextNode.selectSingleNode(xPath)))
- return xmlNode;
-
- var len = paths.length -1;
- if (forceNew) {
- if (paths[len].trim().match(/^\@(.*)$|^text\(\)$/))
- len--;
- }
-
- for (var addedNode, isAdding = false, i = 0; i < len; i++) {
- if (!isAdding && contextNode.selectSingleNode(foundpath
- + (i != 0 ? "/" : "") + paths[i])) {
- foundpath += (i != 0 ? "/" : "") + paths[i];// + "/";
- continue;
- }
-
- //Temp hack
- var isAddId = paths[i].match(/(\w+)\[@([\w-]+)=(\w+)\]/);
- if (!isAddId && paths[i].match(/\@|\[.*\]|\(.*\)/)) {
- throw new Error(jpf.formatErrorString(1041, this,
- "Select via xPath",
- "Could not use xPath to create xmlNode: " + xPath));
- }
- if (!isAddId && paths[i].match(/\/\//)) {
- throw new Error(jpf.formatErrorString(1041, this,
- "Select via xPath",
- "Could not use xPath to create xmlNode: " + xPath));
- }
-
- if (isAddId)
- paths[i] = isAddId[1];
-
- isAdding = true;
- addedNode = contextNode.selectSingleNode(foundpath || ".")
- .appendChild(contextNode.ownerDocument.createElement(paths[i]));
-
- if (isAddId) {
- addedNode.setAttribute(isAddId[2], isAddId[3]);
- foundpath += (foundpath ? "/" : "") + isAddId[0];// + "/";
- }
- else
- foundpath += (foundpath ? "/" : "") + paths[i];// + "/";
-
- if (addedNodes)
- addedNodes.push(addedNode);
- }
-
- if (!foundpath)
- foundpath = ".";
-
- var newNode, lastpath = paths[len];
- do {
- if (lastpath.match(/^\@(.*)$/)) {
- (newNode || contextNode.selectSingleNode(foundpath))
- .setAttributeNode(newNode = contextNode.ownerDocument.createAttribute(RegExp.$1));
- }
- else if (lastpath.trim() == "text()") {
- newNode = (newNode || contextNode.selectSingleNode(foundpath))
- .appendChild(contextNode.ownerDocument.createTextNode(""));
- }
- else {
- var hasId = lastpath.match(/(\w+)\[@([\w-]+)=(\w+)\]/);
- if (hasId) lastpath = hasId[1];
- newNode = (newNode || contextNode.selectSingleNode(foundpath))
- .appendChild(contextNode.ownerDocument.createElement(lastpath));
- if (hasId)
- newNode.setAttribute(hasId[2], hasId[3]);
-
- if (addedNodes)
- addedNodes.push(newNode);
- }
-
- foundpath += (foundpath ? "/" : "") + paths[len];
- } while((lastpath = paths[++len]));
-
- return newNode;
- };
-
- /**
- * @private
- * @todo xml doc leakage
- */
- this.getXmlDocId = function(xmlNode, model){
- var docEl = xmlNode.ownerDocument.documentElement;
- if (!this.isChildOf(docEl, xmlNode))
- docEl = xmlNode;
-
- var docId = (docEl || xmlNode).getAttribute(this.xmlDocTag)
- || xmlDocLut.indexOf(docEl || xmlNode.ownerDocument || xmlNode);
-
- if (docId && docId > -1)
- return docId;
-
- docId = xmlDocLut.push(docEl || xmlNode.ownerDocument || xmlNode) - 1;
- if (docEl)
- docEl.setAttribute(this.xmlDocTag, docId);
-
- if (model)
- jpf.nameserver.register("model", docId, model);
-
- return xmlDocLut.length - 1;
- };
-
- /**
- * @private
- */
- this.getBindXmlNode = function(xmlRootNode){
- if (typeof xmlRootNode != "object")
- xmlRootNode = jpf.getXmlDom(xmlRootNode);
- if (xmlRootNode.nodeType == 9)
- xmlRootNode = xmlRootNode.documentElement;
- if (xmlRootNode.nodeType == 3 || xmlRootNode.nodeType == 4)
- xmlRootNode = xmlRootNode.parentNode;
- if (xmlRootNode.nodeType == 2)
- xmlRootNode = xmlRootNode.ownerElement
- || xmlRootNode.parentNode
- || xmlRootNode.selectSingleNode("..");
-
- return xmlRootNode;
- };
-
- /**
- * @private
- */
- this.convertMethods = {
- /**
- * Gets a JSON object containing all the name/value pairs of the elements
- * using this element as it's validation group.
- *
- * @return {Object} the created JSON object
- */
- "json": function(xml){
- var result = {}, filled = false, nodes = xml.childNodes;
- for (var i = 0; i < nodes.length; i++) {
- if (nodes[i].nodeType != 1)
- continue;
- var name = nodes[i].tagName;
- filled = true;
-
- //array
- var sameNodes = xml.selectNodes(x);
- if (sameNodes.length > 1) {
- var z = [];
- for (var j = 0; j < sameNodes.length; j++) {
- z.push(this.json(sameNodes[j], result));
- }
- result[name] = z;
- }
- else //single value
- result[name] = this.json(sameNodes[j], result);
- }
-
- return filled ? result : jpf.getXmlValue(xml, "text()");
- },
-
- "cgivars": function(xml, basename){
- if (!basename)
- basename = "";
-
- var str = [], value, nodes = xml.childNodes, done = {};
- for (var i = 0; i < nodes.length; i++) {
- if (nodes[i].nodeType != 1)
- continue;
- var name = nodes[i].tagName;
- if (done[name])
- continue;
-
- //array
- var sameNodes = xml.selectNodes(name);
- if (sameNodes.length > 1) {
- done[name] = true;
- for (var j = 0; j < sameNodes.length; j++) {
- value = this.cgivars(sameNodes[j],
- basename + name + "[" + j + "]");
- if (value)
- str.push(value);
- }
- }
- else { //single value
- value = this.cgivars(nodes[i], basename + name);
- if (value)
- str.push(value);
- }
- }
-
- var attr = xml.attributes;
- for (i = 0; i < attr.length; i++) {
- if (attr[i].nodeValue) {
- if (basename)
- str.push(basename + "[" + attr[i].nodeName + "]="
- + encodeURIComponent(attr[i].nodeValue));
- else
- str.push(attr[i].nodeName + "="
- + encodeURIComponent(attr[i].nodeValue));
- }
- }
-
- if (str.length)
- return str.join("&");
-
- value = jpf.getXmlValue(xml, "text()");
- if (basename && value)
- return basename + "=" + encodeURIComponent(value);
- },
-
- "cgiobjects": function(xml, basename, isSub){
- if (!basename)
- basename = "";
-
- var str = [], value, nodes = xml.childNodes, done = {};
- for (var i = 0; i < nodes.length; i++) {
- var node = nodes[i];
- if (node.nodeType != 1)
- continue;
-
- var name = node.tagName; //@hack
- if (name == "revision")
- continue;
-
- var isOnlyChild = jpf.xmldb.isOnlyChild(node.firstChild, [3,4]);
- var count = 0;
-
- //array
- if (!node.attributes.length && !isOnlyChild) {
- var lnodes = node.childNodes;
- for (var nm, j = 0, l = lnodes.length; j < l; j++) {
- if (lnodes[j].nodeType != 1)
- continue;
-
- nm = basename + (isSub ? "[" : "") + name + (isSub ? "]" : "") + "[" + count++ + "]";
- value = this.cgiobjects(lnodes[j], nm, true);
- if (value)
- str.push(value);
-
- if (jpf.xmldb.isOnlyChild(lnodes[j].firstChild, [3,4]))
- str.push(nm + "[" + lnodes[j].tagName + "]" + "="
- + encodeURIComponent(lnodes[j].firstChild.nodeValue));
-
- var a, attr = lnodes[j].attributes;
- for (k = 0; k < attr.length; k++) {
- if (!(a = attr[k]).nodeValue)
- continue;
-
- str.push(nm + "[" + a.nodeName + "]="
- + encodeURIComponent(a.nodeValue));
- }
- }
- }
- //single value
- else {
- if (isOnlyChild)
- str.push(basename + (isSub ? "[" : "") + name + (isSub ? "]" : "") + "="
- + encodeURIComponent(node.firstChild.nodeValue));
-
- var a, attr = node.attributes;
- for (j = 0; j < attr.length; j++) {
- if (!(a = attr[j]).nodeValue)
- continue;
-
- str.push(basename + (isSub ? "[" : "") + name + "_" + a.nodeName + (isSub ? "]" : "") + "="
- + encodeURIComponent(a.nodeValue));
- }
- }
- }
-
- if (!isSub && xml.getAttribute("id"))
- str.push("id=" + encodeURIComponent(xml.getAttribute("id")));
-
- if (str.length)
- return str.join("&");
- }
- };
-
- /**
- * Converts xml to another format.
- *
- * @param {XMLElement} xml the xml element to convert.
- * @param {String} to the format to convert the xml to.
- * Possible values:
- * json converts to a json string
- * cgivars converts to cgi string.
- * cgiobjects converts to cgi objects
- * @return {String} the result of the conversion.
- */
- this.convertXml = function(xml, to){
- return this.convertMethods[to](xml);
- };
-
- /**
- * Returns the first text or cdata child of an xml element.
- *
- * @param {XMLElement} x the xml node to search.
- * @return {XMLNode} the found xml node, or null.
- */
- this.getTextNode = function(x){
- for (var i = 0; i < x.childNodes.length; i++) {
- if (x.childNodes[i].nodeType == 3 || x.childNodes[i].nodeType == 4)
- return x.childNodes[i];
- }
- return false;
- };
-
-
- /**
- * @private
- */
- this.getBoundValue = function(jmlNode, xmlRoot, applyChanges){
- if (!xmlRoot && !jmlNode.xmlRoot)
- return "";
-
- var xmlNode = !jmlNode.nodeFunc
- ? xmlRoot.selectSingleNode(jmlNode.getAttribute("ref"))
- : jmlNode.getNodeFromRule("value", jmlNode.xmlRoot);
-
- return xmlNode ? this.getNodeValue(xmlNode) : "";
- };
-
- /**
- * @private
- */
- this.getArrayFromNodelist = function(nodelist){
- for (var nodes = [], j = 0; j < nodelist.length; j++)
- nodes.push(nodelist[j]);
- return nodes;
- };
-};
-
-/**
- * @alias XmlDatabase#getXml
- */
-jpf.getXml = function(){
- return jpf.xmldb.getXml.apply(jpf.xmldb, arguments);
-};
-
-jpf.Init.run('XmlDatabase');
-
- - -/*FILEHEAD(/var/lib/jpf/src/core/datainstructions.js)SIZE(-1077090856)TIME(1238944816)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * @term datainstruction Data instructions offer a single and consistent way for
- * storing and retrieving
- * data from different data sources. For instance from a webserver using REST
- * or RPC, or from local data sources such as gears, air, o3, html5, as well as
- * from in memory sources from javascript or cookies. There is often an xml
- * element which is relevant to storing information. This element can be
- * accessed using xpath statements in the data instruction using curly braces.
- *
- * Syntax:
- * Using data instructions to retrieve data
- * <code>
- * get="name_of_model"
- * get="name_of_model:xpath"
- * get="#element"
- * get="#element:select"
- * get="#element:select:xpath"
- * get="#element"
- * get="#element:choose"
- * get="#element:choose:xpath"
- * get="#element::xpath"
- * get="url:example.jsp"
- * get="url:http://www.bla.nl?blah=10&foo={@bar}&example=[10+5]"
- * get="rpc:comm.submit('abc', {@bar})"
- * get="call:submit('abc', {@bar})"
- * get="xmpp:login(username, password)"
- * get="webdav:getRoot()"
- * get="eval:10+5"
- * </code>
- *
- * Syntax:
- * Using data instructions to store data
- * <code>
- * set="url:http://www.bla.nl?blah=10&foo={/bar}&example=[10+5]"
- * set="url.post:http://www.bla.nl?blah=10&foo={/bar}&example=[10+5]"
- * set="rpc:comm.submit('abc', {/bar})"
- * set="call:submit('abc', {/bar})"
- * set="eval:example=5"
- * set="cookie:name.subname = {.}"
- * </code>
- */
-
-/**
- * @private
- */
-jpf.namespace("datainstr", {
- "call" : function(xmlContext, options, callback){
- var parsed = options.parsed || this.parseInstructionPart(
- options.instrData.join(":"), xmlContext, options.args, options);
-
- if (!self[parsed.name])
- throw new Error(jpf.formatErrorString(0, null,
- "Saving/Loading data", "Could not find Method '" + q[0] + "' \
- in process instruction '" + instruction + "'"));
-
- if (options.preparse) {
- options.parsed = parsed;
- options.preparse = -1;
- return;
- }
-
- //Call method
- var retvalue = self[parsed.name].apply(null, parsed.arguments);
-
- //Call callback
- if (callback)
- callback(retvalue, jpf.SUCCESS, options);
- },
-
- "eval" : function(xmlContext, options, callback){
- var parsed = options.parsed
- || this.parseInstructionPart(
- "(" + options.instrData.join(":") + ")", xmlContext,
- options.args, options);
-
- if (options.preparse) {
- options.parsed = parsed;
- options.preparse = -1;
- return;
- }
-
- try {
- var retvalue = eval(parsed.arguments[0]);
- }
- catch(e) {
- throw new Error(jpf.formatErrorString(0, null, "Saving data",
- "Could not execute javascript code in process instruction \
- '" + instruction + "' with error " + e.message));
- }
-
- if (callback)
- callback(retvalue, jpf.SUCCESS, options);
- }
-
- ,cookie: function(xmlContext, options, callback){
- var query = options.instrData.join(":");
- var parsed = options.parsed || query.indexOf("=") > -1
- ? this.parseInstructionPart(query.replace(/\s*=\s*/, "(") + ")",
- xmlContext, options.args, options)
- : {name: query, args: options.args || [xmlContext]};
-
- if (options.preparse) {
- options.parsed = parsed;
- options.preparse = -1;
- return;
- }
-
- var value;
- if (options.isGetRequest) {
- value = jpf.getcookie(parsed.name);
- value = value ? jpf.unserialize(value) || "" : "";
- }
- else {
- value = jpf.setcookie(parsed.name,
- jpf.serialize(parsed.args[0]));
- }
-
- if (callback)
- callback(value || parsed.args[0], jpf.SUCCESS, options);
- }
-
-});
-
-
-/**
- * Stores data using a {@link term.datainstruction data instruction}.
- *
- * @param {String} instruction the {@link term.datainstruction data instruction} to be used to store the data.
- * @param {XMLElement} [xmlContext] the subject of the xpath queries
- * @param {Object} [options] the options for this instruction
- * Properties:
- * {Boolean} multicall whether this call should not be executed immediately but saved for later sending using the purge() command.
- * {mixed} userdata any data that is useful to access in the callback function.
- * {Array} args the arguments of the call, overriding any specified in the data instruction.
- * @param {Function} [callback] the code that is executed when the call returns, either successfully or not.
- */
-jpf.saveData = function(instruction, xmlContext, options, callback){
- if (!instruction) return false;
-
- if (!options) options = {};
- options.instrData = instruction.split(":");
- options.instrType = options.instrData.shift();
-
- var instrType = options.instrType.indexOf("url.") == 0
- ? "url"
- : options.instrType;
-
- options.instruction = instruction;
-
- if (!this.datainstr[instrType])
- throw new Error(jpf.formatErrorString(0, null,
- "Processing a data instruction",
- "Unknown data instruction format: " + instrType));
-
- this.datainstr[instrType].call(this, xmlContext, options, callback);
-};
-
-/**
- * Retrieves data using a {@link term.datainstruction data instruction}.
- * Example:
- * Several uses for a data instruction
- * <code>
- * <!-- loading jml from an xml file -->
- * <j:bar jml="url:morejml.xml" />
- *
- * <j:bindings>
- * <!-- loads data using an remote procedure protocol -->
- * <j:load get = "rpc:comm.getData()" />
- *
- * <!-- inserts data using an remote procedure protocol -->
- * <j:insert get = "rpc:comm.getSubData({@id})" />
- * </j:bindings>
- *
- * <j:actions>
- * <!-- notifies the server that a file is renamed -->
- * <j:rename set = "url:update_file.jsp?id={@id}&name={@name}" />
- *
- * <!-- adds a node by retrieving it's xml from the server. -->
- * <j:add get = "url:new_user.xml" />
- * </j:actions>
- *
- * <!-- creates a model which is loaded into a list -->
- * <j:list model="webdav:getRoot()" />
- *
- * <!-- loads data into a model and when submitted sends the altered data back -->
- * <j:model load="url:load_contact.jsp" submission="save_contact.jsp" />
- * </code>
- *
- * @param {String} instruction the {@link term.datainstruction data instruction} to be used to retrieve the data.
- * @param {XMLElement} [xmlContext] the subject of the xpath queries
- * @param {Object} [options] the options for this instruction
- * Properties:
- * {Boolean} multicall whether this call should not be executed immediately but saved for later sending using the purge() command.
- * {mixed} userdata any data that is useful to access in the callback function.
- * {mixed} data data to use in the call
- * {Array} args the arguments of the call, overriding any specified in the data instruction.
- * @param {Function} [callback] the code that is executed when the call returns, either successfully or not.
- */
-//instrType, data, xmlContext, callback, multicall, userdata, arg, isGetRequest
-jpf.getData = function(instruction, xmlContext, options, callback){
- var instrParts = instruction.match(/^(.*?)(?:\!\{(.*)$|$)/);//\[([^\]\[]*)\]
- var operators = instrParts[2] ? instrParts[2].splitSafe("\}\s*,|,") : "";//\{|
-
- var gCallback = function(data, state, extra){
- if (state != jpf.SUCCESS)
- return callback(data, state, extra);
-
- operators[2] = data;
- if (operators[0] && data) {
- if (typeof data == "string")
- data = jpf.xmldb.getXml(data);
-
- extra.data = data;
- data = data.selectSingleNode(operators[0]);
-
- //Change this to warning?
- if (!data) {
- throw new Error(jpf.formatErrorString(0, null,
- "Loading new data", "Could not load data by doing \
- selection on it using xPath: '" + operators[0] + "'."));
- }
- }
-
- extra.userdata = operators;
- return callback(data, state, extra);
- }
-
- if (!options) options = {};
- options.isGetRequest = true;
- options.userdata = operators;
-
- //Get data operates exactly the same as saveData...
- if (this.saveData(instrParts[1], xmlContext, options, gCallback) !== false)
- return;
-
- //...and then some
- var data = instruction.split(":");
- var instrType = data.shift();
-
- if (instrType.substr(0, 1) == "#") {
- instrType = instrType.substr(1);
- var retvalue, oJmlNode = self[instrType];
-
- if (!oJmlNode)
- throw new Error(jpf.formatErrorString(0, null, "Loading data",
- "Could not find object '" + instrType + "' referenced in \
- process instruction '" + instruction + "' with error "
- + e.message));
-
- if (!oJmlNode.value)
- retvalue = null;
- else
- retvalue = data[2]
- ? oJmlNode.value.selectSingleNode(data[2])
- : oJmlNode.value;
- }
- else {
- var model = jpf.nameserver.get("model", instrType);
-
- if (!model) {
- throw new Error(jpf.formatErrorString(1068, jmlNode,
- "Loading data", "Could not find model by name: "
- + instrType, x));
- }
-
- if (!model.data)
- retvalue = null;
- else
- retvalue = data[1]
- ? model.data.selectSingleNode(data[1])
- : model.data;
- }
-
- if (callback)
- gCallback(retvalue, jpf.SUCCESS, {userdata:operators});
- else {
- jpf.console.warn("Returning data directly in jpf.getData(). \
- This means that all callback communication ends in void!");
- return retvalue;
- }
-};
-
-/**
- * Creates a model object based on a {@link term.datainstruction data instruction}.
- *
- * @param {String} instruction the {@link term.datainstruction data instruction} to be used to retrieve the data for the model.
- * @param {JmlNode} jmlNode the element the model is added to.
- * @param {Boolean} isSelection whether the model provides data that determines the selection of the element.
- */
-jpf.setModel = function(instruction, jmlNode, isSelection){
- if (!instruction) return;
-
- var data = instruction.split(":");
- var instrType = data[0];
-
- //So are we sure we shouldn't also check .dataParent here?
- var model = isSelection
- ? jmlNode.$getMultiBind().getModel()
- : jmlNode.getModel && jmlNode.getModel();
- if(model)
- model.unregister(jmlNode);
-
- if (jpf.datainstr[instrType]) {
- jmlNode.setModel(new jpf.model().loadFrom(instruction));
- }
- else if (instrType.substr(0,1) == "#") {
- instrType = instrType.substr(1);
-
- if (isSelection) {
- var sb2 = jpf.isParsing
- ? jpf.JmlParser.getFromSbStack(jmlNode.uniqueId, 1)
- : jmlNode.$getMultiBind().smartBinding;
- if (sb2)
- sb2.$model = new jpf.model().loadFrom(instruction);
- }
- else if (!self[instrType] || !jpf.JmlParser.inited) {
- jpf.JmlParser.addToModelStack(jmlNode, data)
- }
- else {
- var oConnect = eval(instrType);
- if (oConnect.connect)
- oConnect.connect(jmlNode, null, data[2], data[1] || "select");
- else
- jmlNode.setModel(new jpf.model().loadFrom(instruction));
- }
-
- jmlNode.connectId = instrType;
- }
- else {
- var instrType = data.shift();
- model = instrType == "@default"
- ? jpf.globalModel
- : jpf.nameserver.get("model", instrType);
-
- if (!model) {
- throw new Error(jpf.formatErrorString(1068, jmlNode,
- "Finding model", "Could not find model by name: " + instrType));
- }
-
- if (isSelection) {
- var sb2 = jpf.isParsing
- ? jpf.JmlParser.getFromSbStack(jmlNode.uniqueId, 1)
- : jmlNode.$getMultiBind().smartBinding;
- if (sb2) {
- sb2.$model = model;
- sb2.$modelXpath[jmlNode.uniqueId] = data.join(":");
- }
- }
- else
- jmlNode.setModel(model, data.join(":"));
- }
-};
-
-/**
- * Parses argument list
- * Example:
- * Javascript
- * <code>
- * jpf.parseInstructionPart('type(12+5,"test",{@value}.toLowerCase(),[0+2, "test"])', xmlNode);
- * </code>
- * Jml
- * <code>
- * <j:rename set="rpc:comm.setFolder({@id}, {@name}, myObject.someProp);" />
- * </code>
- * @private
- */
-jpf.parseInstructionPart = function(instrPart, xmlNode, arg, options){
- var parsed = {}, s = instrPart.split("(");
- parsed.name = s.shift();
-
- //Get arguments for call
- if (!arg) {
- arg = s.join("(");
-
- if (arg.slice(-1) != ")") {
- throw new Error(jpf.formatErrorString(0, null, "Saving data",
- "Syntax error in instruction. Missing ) in " + instrPart));
- }
-
- function getXmlValue(xpath){
- var o = xmlNode ? xmlNode.selectSingleNode(xpath) : null;
-
- if (!o)
- return null;
- else if (o.nodeType >= 2 && o.nodeType <= 4)
- return o.nodeValue;
- else if (jpf.xmldb.isOnlyChild(o.firstChild, [3, 4]))
- return o.firstChild.nodeValue;
- else
- return o.xml || o.serialize();
- }
-
- arg = arg.slice(0, -1);
- var depth, lastpos = 0, result = ["["];
- arg.replace(/\\[\{\}\'\"]|(["'])|([\{\}])/g,
- function(m, chr, cb, pos){
- chr && (!depth && (depth = chr)
- || depth == chr && (depth = null));
-
- if (!depth && cb) {
- if (cb == "{") {
- result.push(arg.substr(lastpos, pos - lastpos));
- lastpos = pos + 1;
- }
- else {
- result.push("getXmlValue('", arg
- .substr(lastpos, pos - lastpos)
- .replace(/([\\'])/g, "\\$1"), "')");
- lastpos = pos + 1;
- }
- }
- });
-
- result.push(arg.substr(lastpos), "]");
-
- //Safely set options
- (function(){
- try{
- with (options) {
- arg = eval(result.join(""));
- }
- }
- catch(e) {
- throw new Error(jpf.formatErrorString(0, null, "Saving data",
- "Error executing data instruction: " + arg
- + "\nreason:" + e.message
- + "\nAvailable properties:" + jpf.vardump(options)));
-
- arg = [];
- }
- })();
- }
-
- parsed.arguments = arg;
-
- return parsed;
-};
-
- - -/*FILEHEAD(/var/lib/jpf/src/core/class.js)SIZE(-1077090856)TIME(1239018216)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * BaseClass for any object offering property binding,
- * event handling, constructor and destructor hooks.
- *
- * @constructor
- * @baseclass
- *
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.8
- *
- * @event propertychange Fires when a property changes.
- * object:
- * {String} name the name of the changed property
- * {Mixed} originalvalue the value it had before the change
- * {Mixed} value the value it has after the change
- *
- */
-jpf.Class = function(){
- this.$jmlLoaders = [];
- this.$addJmlLoader = function(func){
- if (!this.$jmlLoaders)
- func.call(this, this.$jml);
- else
- this.$jmlLoaders.push(func);
- };
-
- this.$jmlDestroyers = [];
-
- this.$regbase = 0;
- this.hasFeature = function(test){
- return this.$regbase&test;
- };
-
- /* ***********************
- PROPERTY BINDING
- ************************/
-
-
-
- var boundObjects = {};
- var myBoundPlaces = {};
-
- if (!this.$handlePropSet) {
- this.$handlePropSet = function(prop, value){
- this[prop] = value;
- };
- }
-
- /*
- for (var i = 0; i < this.$supportedProperties.length;i++) {
- var p = uCaseFirst(this.$supportedProperties[i]);
- this["set" + p] = function(prop){return function(value){
- this.setProperty(prop, value);
- }}(this.$supportedProperties[i]);
-
- this["get" + p] = function(prop){return function(){
- return this.getProperty(prop);
- }}(this.$supportedProperties[i]);
- }
- */
-
- /**
- * Bind a property of another compontent to a property of this element.
- *
- * @param {String} myProp the name of the property of this element of which the value is communicated to <code>bObject</code>.
- * @param {Class} bObject the object which will receive the property change message.
- * @param {String} bProp the property of <code>bObject</code> which will be set using the value of <code>myProp</code> optionally processed using <code>strDynamicProp</code>.
- * @param {String} [strDynamicProp] a javascript statement which contains the value of <code>myProp</code>. The string is used to calculate a new value.
- */
- this.bindProperty = function(myProp, bObject, bProp, strDynamicProp){
- //#--ifdef __DEBUG
- if (!boundObjects[myProp])
- boundObjects[myProp] = {};
- if (!boundObjects[myProp][bObject.uniqueId])
- boundObjects[myProp][bObject.uniqueId] = [];
-
- if (boundObjects[myProp][bObject.uniqueId].contains(bProp)) {
- throw new Error(jpf.formatErrorString(0, this,
- "Property-binding",
- "Already bound " + bObject.name + "." + bProp + " to " + myProp));
- return;
- }
-
- if (strDynamicProp)
- boundObjects[myProp][bObject.uniqueId].push([bProp, strDynamicProp]);
- else
- boundObjects[myProp][bObject.uniqueId].pushUnique([bProp]); //The new array is always unique... right?
- /* #--else
-
- if(!boundObjects[myProp]) boundObjects[myProp] = [];
- boundObjects[myProp].push([bObject, bProp, strDynamicProp]);
-
- #--endif */
-
- bObject.$handlePropSet(bProp, strDynamicProp ? eval(strDynamicProp) : this[myProp]);
- };
-
- /**
- * Remove the binding of a property of another compontent to a property of this element.
- *
- * @param {String} myProp the name of the property of this element for which the property bind was registered.
- * @param {Class} bObject the object receiving the property change message.
- * @param {String} bProp the property of <code>bObject</code>.
- */
- this.unbindProperty = function(myProp, bObject, bProp){
- //#--ifdef __DEBUG
- boundObjects[myProp][bObject.uniqueId].remove(bProp);
- /* #--else
-
- if(!boundObjects[myProp]) return;
- for(var i=0;i<boundObjects[myProp].length;i++){
- if(boundObjects[myProp][0] == bObject && boundObjects[myProp][1] == bProp){
- return boundObjects[myProp].removeIndex(i);
- }
- }
-
- #--endif */
- };
-
-
- /**
- * Unbinds all bound properties for this componet.
- */
- this.unbindAllProperties = function(){
- var prop;
- for (prop in myBoundPlaces) {
- //Remove any bounds if relevant
- if (myBoundPlaces[prop] && typeof myBoundPlaces[prop] != "function") {
- for (var i = 0; i < myBoundPlaces[prop].length; i++) {
- if (!self[myBoundPlaces[prop][i][0]]) continue;
-
- self[myBoundPlaces[prop][i][0]]
- .unbindProperty(myBoundPlaces[prop][i][1], this, prop);
- }
- }
- }
- };
-
- /**
- * Gets an array of properties for this element which can be bound.
- */
- this.getAvailableProperties = function(){
- return this.$supportedProperties.slice();
- };
-
- /**
- * Sets a dynamic property from a string.
- * The string used for this function is the same as used in JML to set a dynamic property:
- * <j:button visible="{rbTest.value == 'up'}" />
- *
- * @param {String} prop the name of the property of this element to set using a dynamic rule.
- * @param {String} pValue the dynamic property binding rule.
- */
- this.setDynamicProperty = function(prop, pValue){
- //pValue.match(/^([{\[])(.*)[}\]]$/); // Find dynamic or calculated property
- var pStart = pValue.substr(0,1);
-
- var pEnd = pValue.substr(pValue.length-1, 1);
- if (pStart == "[" && pEnd != "]" || pStart == "{" && pEnd != "}" ) {
- throw new Error(jpf.formatErrorString(0, this,
- "Dynamic Property Binding",
- "Invalid binding found: " + pValue));
- }
-
- //Remove any bounds if relevant
- if (myBoundPlaces[prop]) {
- for (var i = 0; i < myBoundPlaces[prop].length; i++) {
- self[myBoundPlaces[prop][i][0]].unbindProperty(myBoundPlaces[prop][i][1], this, prop);
- }
- }
-
- //Two Way property binds
- if (pStart == "[") {
- var p = pValue.substr(1,pValue.length-2).split(".");
- if (!self[p[0]]) return;
-
- if (!p[1])
- p[1] = self[p[0]].$supportedProperties[0]; // Default state property
-
- //Two way property binding
- self[p[0]].bindProperty(p[1], this, prop);
- myBoundPlaces[prop] = [p];
- this.bindProperty(prop, self[p[0]], p[1]);
- }
- else if (pStart == "{") { //One Way Dynamic Properties
- var o, node, bProp, p, matches = {};
- pValue = pValue.substr(1, pValue.length - 2);
- pValue.replace(/["'](?:\\.|[^"']+)*["']|\\(?:\\.|[^\\]+)*\/|(?:\W|^)([a-z]\w*\.\w+(?:\.\w+)*)(?!\()(?:\W|$)/gi,
- function(m, m1){
- if(m1) matches[m1] = true;
- });
-
- pValue = pValue.replace(/\Wand\W/g, "&&").replace(/\Wor\W/g, "||"); //.replace(/\!\=|(\=)/g, function(m, m1){if(!m1) return m; return m1+"="})
- myBoundPlaces[prop] = [];
-
- var found = false;
- for (p in matches) {
- if (typeof matches[p] == "function")
- continue;
-
- o = p.split(".");
- if (o.length > 2) { //jpf.offline.syncing
- bProp = o.pop();
- try{
- node = eval(o.join("."));
- }
- catch(e){
- throw new Error(jpf.formatErrorString(0, this,
- "Creating a dynamic property bind",
- "invalid bind statement '" + pValue + "'"));
- }
-
- if (typeof node != "object" || !node.$regbase) {
- bProp = o[1];
- node = self[o[0]];
- }
- else
- o.push(bProp);
- }
- else {
- bProp = o[1];
- node = self[o[0]];
- }
-
- if (!node || !node.bindProperty)
- continue; //return
-
- node.bindProperty(bProp, this, prop, pValue);
- myBoundPlaces[prop].push(o);
- found = true;
- }
-
- //if (!found)
- //this.$handlePropSet(prop, eval(pValue));
- var value = eval(pValue);
- this[prop] = !value;
- this.setProperty(prop, value);
- }
- else {
- //this.$handlePropSet(prop, pValue);
- var value = eval(pValue);
- this[prop] = !value;
- this.setProperty(prop, eval(pValue));
- }
- }
-
-
- /**
- * Sets the value of a property of this element.
- * Note: Only the value is set, dynamic properties will remain bound and the value will be overridden.
- *
- * @param {String} prop the name of the property of this element to set using a dynamic rule.
- * @param {String} value the value of the property to set.
- * @param {Boolean} [reqValue] Wether the method should return when value is null.
- * @param {Boolean} [forceOnMe] Wether the property should be set even when its the same value.
- */
- this.setProperty = function(prop, value, reqValue, forceOnMe){
- if (reqValue && !value || !jpf || this.$ignoreSignals)
- return;
-
- var oldvalue = this[prop];
- if (String(this[prop]) !== String(value) || typeof value == "object") {
- if (typeof jpf.offline != "undefined") {
- if (jpf.loaded && jpf.offline.state.enabled
- && (!this.bindingRules || !this.bindingRules[prop]
- || this.traverse)) {
- jpf.offline.state.set(this, prop, typeof value == "object"
- ? value.name
- : value);
- }
- else if (jpf.offline.enabled) {
-
- }
- }
- if (this.$handlePropSet(prop, value, forceOnMe) === false) {
- this[prop] = oldvalue;
- return false;
- }
- }
-
-
- if (this["onpropertychange"] || events_stack["propertychange"]) {
- this.dispatchEvent("propertychange", {
- name : prop,
- value : value,
- originalvalue : oldvalue
- });
- }
-
- var nodes = boundObjects[prop];
- if (!nodes) return;
-
- //#--ifdef __DEBUG
- var id, ovalue = this[prop];//value;
- for (id in nodes) {
- if (jpf.isSafari && (typeof nodes[id] != "object" || !nodes[id]))
- continue;
-
- for (var o = jpf.lookup(id), i = nodes[id].length - 1; i >= 0; --i) {
- try {
- value = nodes[id][i][1] ? eval(nodes[id][i][1]) : ovalue;
- }
- catch(e) {
- throw new Error(jpf.formatErrorString(0, this,
- "Property-binding",
- "Could not execute binding test: " + nodes[id][i][1]));
- }
-
- if (typeof o != "undefined" && o[nodes[id][i][0]] != value)
- o.setProperty(nodes[id][i][0], value);//__handlePropSet
- }
- }
- /* #--else
-
- for(var i=0;i<nodes.length;i++){
- try{
- nodes[i][0].$handlePropSet(nodes[i][1],
- nodes[i][2] ? eval(nodes[i][2]) : value);
- }catch(e){}
- }
- #--endif */
-
-
- return value;
- };
-
- /**
- * Gets the value of a property of this element.
- *
- * @param {String} prop the name of the property of this element for which to get the value.
- */
- this.getProperty = function(prop){
- return this[prop];
- };
-
- /* ***********************
- EVENT HANDLING
- ************************/
-
- var capture_stack = {}, events_stack = {};
- /**
- * Calls all functions associated with the event.
- *
- * @param {String} eventName the name of the event to dispatch.
- * @param {Object} [options] the properties of the event object that will be created and passed through.
- * Properties:
- * {Boolean} bubbles whether the event should bubble up to it's parent
- * @return {mixed} return value of the event
- */
- this.dispatchEvent = function(eventName, options, e){
- var arr, result, rValue;
-
-
- if (options && options.name)
- e = options;
- else if (!e)
- e = new jpf.Event(eventName, options);
-
- if (this.disabled)
- result = false;
- else {
- if (!e.originalElement) {
- e.originalElement = this;
-
- //Capture support
- if (arr = capture_stack[eventName]) {
- for (var i = 0; i < arr.length; i++) {
- rValue = arr[i].call(this, e);
- if (rValue != undefined)
- result = rValue;
- }
- }
- }
-
- if (options && options.captureOnly)
- return e.returnValue || rValue;
- else {
- if (this["on" + eventName])
- result = this["on" + eventName].call(this, e); //Backwards compatibility
-
- if (arr = events_stack[eventName]) {
- for (var i = 0; i < arr.length; i++) {
- rValue = arr[i].call(this, e);
- if (rValue != undefined)
- result = rValue;
- }
- }
- }
- }
-
- if (e.bubbles && !e.cancelBubble && this != jpf) {
- rValue = (this.parentNode || jpf).dispatchEvent(eventName, null, e);
-
- if (rValue != undefined)
- result = rValue;
- }
-
- return e.returnValue !== undefined ? e.returnValue : result;
- };
-
- /**
- * Add a function to be called when a event is called.
- *
- * @param {String} eventName the name of the event for which to register a function.
- * @param {function} callback the code to be called when event is dispatched.
- */
- this.addEventListener = function(eventName, callback, useCapture){
-
- if (eventName.indexOf("on") == 0)
- eventName = eventName.substr(2);
-
- var stack = useCapture ? capture_stack : events_stack;
- if (!stack[eventName])
- stack[eventName] = [];
- stack[eventName].pushUnique(callback);
- }
-
- /**
- * Remove a function registered for an event.
- *
- * @param {String} eventName the name of the event for which to unregister a function.
- * @param {function} callback the function to be removed from the event stack.
- */
- this.removeEventListener = function(eventName, callback, useCapture){
- var stack = useCapture ? capture_stack : events_stack;
- if (stack[eventName])
- stack[eventName].remove(callback);
- };
-
- /**
- * Checks if there is an event listener specified for the event.
- *
- * @param {String} eventName the name of the event to check.
- * @return {Boolean} whether the event has listeners
- */
- this.hasEventListener = function(eventName){
- return (events_stack[eventName] && events_stack[eventName].length > 0);
- };
-
- /**
- * Destructor of a Class.
- * Calls all destructor functions and removes all mem leaking references.
- * This function is called when exiting the application or closing the window.
- * @param {Boolean} deep whether the children of this element should be destroyed.
- * @method
- */
- this.destroy = this.destroy || function(deep){
- if (!this.$jmlDestroyers) //@todo check why this happens
- return;
-
- if (this.$destroy)
- this.$destroy();
-
- for (var i = this.$jmlDestroyers.length - 1; i >= 0; i--)
- this.$jmlDestroyers[i].call(this);
- this.$jmlDestroyers = undefined;
-
- //Remove from jpf.all
- if (typeof this.uniqueId == "undefined")
- return;
-
- jpf.all[this.uniqueId] = undefined;
-
- if (!this.nodeFunc) { //If this is not a JmlNode, we're done.
- //Remove id from global js space
- if (this.name)
- self[this.name] = null;
- return;
- }
-
- if (this.oExt && !this.oExt.isNative && this.oExt.nodeType == 1) {
- this.oExt.oncontextmenu = this.oExt.host = null;
- }
- if (this.oInt && !this.oExt.isNative && this.oInt.nodeType == 1)
- this.oInt.host = null;
-
- this.$jml = null;
-
- //Remove from DOM tree if we are still connected
- if (this.parentNode)
- this.removeNode();
-
- //Remove from focus list - Should be in JmlNode
- if (this.$focussable && this.focussable)
- jpf.window.$removeFocus(this);
-
- //Remove dynamic properties
- this.unbindAllProperties();
-
- //Clear all children too
- if (deep && this.childNodes) {
- var i, nodes = this.childNodes;
- for (i = nodes.length - 1; i >= 0; i--) {
- if (nodes[i].destroy)
- nodes[i].destroy(true);
- }
- this.childNodes = null;
- }
-
- if (deep !== false && this.childNodes) {
- jpf.console.warn("You have destroyed a Jml Node without destroying\
- it's children. Please be aware that if you don't\
- maintain a reference, memory might leak");
- }
-
- //Remove id from global js space
- if (this.name)
- self[this.name] = null;
- };
-};
-
-/**
- * @constructor
- */
-jpf.Event = function(name, data){
- this.name = name;
-
- this.bubbles = false;
- this.cancelBubble = false;
-
- this.preventDefault = function(){
- this.returnValue = false;
- }
-
- this.stopPropagation = function(){
- this.cancelBubble = true;
- }
-
- //@todo should be implemented;
- this.isCharacter = function(){
- return (this.keyCode < 112 || this.keyCode > 122)
- && (this.keyCode < 33 && this.keyCode > 31 || this.keyCode > 42 || this.keyCode == 8);
-
- }
-
- jpf.extend(this, data);
- //this.returnValue = undefined;
-};
-
-jpf.inherit(jpf.Class);
-jpf.Init.run('class');
-
- - -/*FILEHEAD(/var/lib/jpf/src/core/component.js)SIZE(-1077090856)TIME(1238944816)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -/** - * This function tries to simplify the development of new JML elements. - * Creating a new element for JPF may now be as easy as: - * Example: - * <code language="javascript"> - * // create a new JML component: <j:foo /> - * jpf.foo = jpf.component(jpf.NODE_VISIBLE, { - * // component body (method and property declaration) - * }).implement(jpf.barInterface); - * </code> - * - * @classDescription This class serves as a baseclass for new elements - * @param {Number} nodeFunc A number constant, defining the type of element - * @param {mixed} oBase May be a function (will be instantiated) or object to populate the elements' prototype - * @return {Element} Returns a Function that will serve as the elements' constructor - * @type {Element} - * @constructor - * - * Note: we REALLY don't care about execution speed for this one! It will be - * optimized by reformatting it using Jaw (compile-time), like C-style macros. - * *sigh* don't worry, this implementation is still blazing fast and has been - * profiled and optimized in all major browsers. - * - * @author Mike de Boer - * @version %I%, %G% - * @since 1.0 - */ - -jpf.component = function(nodeFunc, oBase) { - // the actual constructor for the new comp (see '__init()' below). - var fC = function() { - this.$init.apply(this, arguments); - }; - - // if oBase is provided, apply it as a prototype of the new comp. - if (oBase) { - // a function will be deferred to instantiation of the comp. to be inherited - if (typeof oBase == "function") - fC.prototype.base = oBase; - else - fC.prototype = oBase; - } - - // the 'nodeFunc' flag specifies the function that a node/ component represents - // within JPF. - fC.prototype.nodeFunc = nodeFunc || jpf.NODE_HIDDEN; - - // deprecated Deskrun feature - if (nodeFunc == jpf.NODE_MEDIAFLOW) - DeskRun.register(fC.prototype); - - // The inherit function is copied from 'jpf.inherit' - fC.prototype.inherit = jpf.inherit; - - // If the '$init' function is not present yet, we shall define it - the - // starting engine of a JPF component - if (typeof fC.prototype['$init'] != "function") { - var aImpl = []; - /** - * The developer may supply interfaces that will inherited upon element - * instantiation with implement() below. Calls to 'implement()' may be - * chained. - * Note: duplicate interfaces will not be filtered out! This means that - * only the interface that was provided with implement() will be - * actually implemented. - * - * @private - */ - fC.implement = function() { - aImpl = aImpl.concat(Array.prototype.slice.call(arguments)); - return fC; - } - - /** - * Even though '$init()' COULD be overridden, it is still the engine - * for every new element. It takes care of the basic inheritance - * difficulties and created the necessary hooks with the Javeline Platform. - * Note: a developer can still use 'init()' as the function to execute - * upon instantiation, while '$init()' is used by JPF. - * - * @param {Object} pHtmlNode - * @param {Object} sName - * @type void - */ - fC.prototype.$init = function(pHtmlNode, sName){ - if (typeof sName != "string") - throw new Error(jpf.formatErrorString(0, this, - "Error creating component", - "Dependencies not met, please provide a component name when \ - instantiating it (ex.: new jpf.tree(oParent, 'tree') )")); - - this.tagName = sName; - this.pHtmlNode = pHtmlNode || document.body; - this.pHtmlDoc = this.pHtmlNode.ownerDocument; - - this.uniqueId = jpf.all.push(this) - 1; - - //Oops duplicate code.... (also in jpf.register) - this.$propHandlers = {}; //@todo fix this in each component - this.$domHandlers = { - "remove" : [], - "insert" : [], - "reparent" : [], - "removechild" : [] - }; - - if (nodeFunc != jpf.NODE_HIDDEN) { - if (typeof this.$focussable == "undefined") - this.$focussable = jpf.KEYBOARD_MOUSE; // Each GUINODE can get the focus by default - - this.$booleanProperties = { - "disable-keyboard" : true, - "visible" : true, - "focussable" : true - //"disabled" : true - }; - - this.$supportedProperties = [ - "draggable", "resizable", - "focussable", "zindex", "disabled", "tabindex", - "disable-keyboard", "contextmenu", "visible", "autosize", - "loadjml", "actiontracker", "alias"]; - } - else { - this.$booleanProperties = {}; //@todo fix this in each component - this.$supportedProperties = []; //@todo fix this in each component - } - - /** - * @inherits jpf.Class - * @inherits jpf.JmlElement - */ - // the ORDER is crucial here. - this.inherit(jpf.Class); - this.inherit.apply(this, aImpl); - this.inherit(jpf.JmlElement, this.base || jpf.K); - - if (typeof this['init'] == "function") - this.init(); - } - } - - return fC; -}; - -/** - * This is code to construct a subnode, these are simpler and almost - * have no inheritance - */ -jpf.subnode = function(nodeFunc, oBase) { - // the actual constructor for the new comp (see '__init()' below). - var fC = function() { - this.$init.apply(this, arguments); - }; - - // if oBase is provided, apply it as a prototype of the new comp. - if (oBase) { - // a function will be deferred to instantiation of the comp. to be inherited - if (typeof oBase == "function") - fC.prototype.base = oBase; - else - fC.prototype = oBase; - } - - fC.prototype.nodeFunc = nodeFunc || jpf.NODE_HIDDEN; - - fC.prototype.inherit = jpf.inherit; - - if (typeof fC.prototype['$init'] != "function") { - var aImpl = []; - /** - * The developer may supply interfaces that will inherited upon element - * instantiation with implement() below. Calls to 'implement()' may be - * chained. - * - * @private - */ - fC.implement = function() { - aImpl = aImpl.concat(Array.prototype.slice.call(arguments)); - return fC; - } - - /** - * Even though '__init()' COULD be overridden, it is still the engine - * for every new element. It takes care of the basic inheritance - * difficulties and created the necessary hooks with the Javeline Platform. - * Note: a developer can still use 'init()' as the function to execute - * upon instantiation, while '__init()' is used by JPF. - * - * @param {Object} pHtmlNode - * @param {Object} sName - * @param {Object} parentNode - * @type void - */ - fC.prototype.$init = function(pHtmlNode, sName, parentNode){ - if (typeof sName != "string") - throw new Error(jpf.formatErrorString(0, this, - "Error creating component", - "Dependencies not met, please provide a component name when \ - instantiating it (ex.: new jpf.tree(oParent, 'tree') )")); - - this.tagName = sName; - this.pHtmlNode = pHtmlNode || document.body; - this.pHtmlDoc = this.pHtmlNode.ownerDocument; - this.parentNode = parentNode; - this.$domHandlers = { - "remove" : [], - "insert" : [], - "reparent" : [], - "removechild" : [] - }; - - this.uniqueId = jpf.all.push(this) - 1; - - /** - * @inherits jpf.Class - */ - // the ORDER is crucial here. - this.inherit(jpf.Class); - this.inherit.apply(this, aImpl); - this.inherit(jpf.JmlDom, this.base || jpf.K); - - if (typeof this['init'] == "function") - this.init(); - } - } - - return fC; -}; - - - -/*FILEHEAD(/var/lib/jpf/src/core/window.js)SIZE(-1077090856)TIME(1239027646)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * @private
- */
-jpf.windowManager = {
- destroy: function(frm){
- //Remove All Cross Window References Created on Init by jpf.windowManager
- // for (var i = 0; i < this.globals.length; i++)
- // frm.win[this.globals[i]] = null;
- },
-
- //root : self,
- userdata: [],
-
- /* ********************************************************************
- FORMS
- *********************************************************************/
- forms : new Array(),
-
- addForm: function(xmlFormNode){
- var x = {
- jml: xmlFormNode,
- show: function(){
- alert("not implemented");
- }
- };
- this.forms.push(jpf.setReference(x.name, x, true));
- return x;
- },
-
- getForm: function(value){
- for (var i = 0; i < this.forms.length; i++)
- if (this.forms[i].name == value)
- return this.forms[i];
-
- return this.forms.length ? this.forms[0] : false;
- },
-
- closeAll: function(){
- for (var i = 0; i < this.forms.length; i++)
- if (this.forms[i].name != "main" && this.forms[i].type != "modal")
- this.forms[i].hide();
- }
-};
-
-/**
- * Object representing the window of the jml application. The semantic is
- * similar to that of a window in the browser, except that this window is not
- * the same as the javascript global object. It handles the focussing within
- * the document and several other events such as exit and the keyboard events.
- *
- * @event blur Fires when the browser window looses focus.
- * @event focus Fires when the browser window receives focus.
- *
- * @constructor
- * @jpfclass
- *
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.8
- */
-jpf.WindowImplementation = function(){
- jpf.register(this, "window", jpf.NODE_HIDDEN);/** @inherits jpf.Class */
- this.jpf = jpf;
-
- /**
- * Returns a string representation of this object.
- */
- this.toString = function(){
- return "[Javeline Component : " + (this.name || "") + " (jpf.window)]";
- };
-
- /**
- * Retrieves the root action tracker of the application.
- */
- this.getActionTracker = function(){
- return this.$at
- };
-
- /**
- * @private
- */
- this.loadCodeFile = function(url){
- //if(jpf.isSafari) return;
- if (self[url])
- jpf.importClass(self[url], true, this.win);
- else
- jpf.include(url);//, this.document);
- };
-
- /**
- * Flashes the task bar. This can be useful to signal the user that an
- * important event has occured. Only works in internet explorer under
- * certain conditions.
- */
- this.flash = function(){
- if (jpf.window.hasFocus())
- return;
-
- if (jpf.isDeskrun)
- jdwin.Flash();
- else if (jpf.isIE) {
- if (!this.popup)
- this.popup = window.createPopup();
-
- if (jpf.window.stopFlash)
- return;
-
- state += "x"
-
- function doFlash(nopopup) {
- if (jpf.window.hasFocus())
- return;
-
- window.focus();
-
- function doPopup() {
- if (jpf.window.hasFocus())
- return;
-
- this.popup.hide();
- this.popup.show(0, 0, 0, 0, document.body);
- this.popup.document.write("<body><script>\
- document.p = window.createPopup();\
- document.p.show(0, 0, 0, 0, document.body);\
- </script></body>");
- this.popup.document.focus();
-
- clearInterval(this.flashTimer);
- this.flashTimer = setInterval(function(){
- if (!jpf.window.popup.isOpen
- || !jpf.window.popup.document.p.isOpen) {
- clearInterval(jpf.window.flashTimer);
-
- if (!jpf.window.hasFocus()) {
- jpf.window.popup.hide();
- document.body.focus();
- state = "d";
- determineAction();
- }
- //when faster might have timing error
- }
- }, 10);
- }
-
- if (nopopup)
- setTimeout(function(){
- doPopup.call(jpf.window)
- }, 10);
- else
- doPopup.call(jpf.window);
- }
-
- if ("TEXTAREA|INPUT|SELECT".indexOf(document.activeElement.tagName) > -1) {
- document.activeElement.blur();
- document.body.focus();
- jpf.window.stopFlash = true;
- setTimeout(function(){
- doFlash.call(jpf.window, true);
- jpf.window.stopFlash = false;
- }, 10);
- }
- else {
- doFlash.call(jpf.window);
- }
- }
- };
-
- /**
- * Show the browser window.
- */
- this.show = function(){
- if (jpf.isDeskrun)
- jdwin.Show();
- };
-
- /**
- * Hide the browser window.
- */
- this.hide = function(){
- if (jpf.isDeskrun)
- jdwin.Hide();
- else {
- this.loaded = false;
- if (this.win)
- this.win.close();
- }
- };
-
- /**
- * Focus the browser window.
- */
- this.focus = function(){
- if (jpf.isDeskrun)
- jdwin.SetFocus();
- else
- window.focus();
- };
-
- /**
- * Set the icon of the browser window.
- * @param {String} url the location of the .ico file.
- */
- this.setIcon = function(url){
- if (jpf.isDeskrun)
- jdwin.icon = parseInt(url) == url ? parseInt(url) : url;
- };
-
- /**
- * Set the title of the browser window.
- * @param {String} value the new title of the window.
- */
- this.setTitle = function(value){
- this.title = value || "";
-
- if (jpf.isDeskrun)
- jdwin.caption = value;
- else
- document.title = (value || "");
- };
-
- /**
- * @private
- */
- this.loadJml = function(x){
- if (x[jpf.TAGNAME] == "deskrun")
- this.loadDeskRun(x);
- else {
-
- }
- };
-
- var jdwin = jpf.isDeskrun ? window.external : null;
- var jdshell = jpf.isDeskrun ? jdwin.shell : null;
-
- /**
- * @private
- */
- this.loadDeskRun = function(q){
- jdwin.style = q.getAttribute("style") || "ismain|taskbar|btn-close|btn-max|btn-min|resizable";
-
- jpf.appsettings.drRegName = q.getAttribute("record");
- if (q.getAttribute("minwidth"))
- jdwin.setMin(q.getAttribute("minwidth"), q.getAttribute("minheight"));
- if (q.getAttribute("record")
- && jdshell.RegGet(jpf.appsettings.drRegName + "/window")) {
- var winpos = jdshell.RegGet(jpf.appsettings.drRegName + "/window");
- if (winpos) {
- winpos = winpos.split(",");
- window.external.width = Math.max(q.getAttribute("minwidth"),
- Math.min(parseInt(winpos[2]),
- window.external.shell.GetSysValue("deskwidth")));
- window.external.height = Math.max(q.getAttribute("minheight"),
- Math.min(parseInt(winpos[3]),
- window.external.shell.GetSysValue("deskheight")));
- window.external.left = Math.max(0, Math.min(parseInt(winpos[0]),
- screen.width - window.external.width));
- window.external.top = Math.max(0, Math.min(parseInt(winpos[1]),
- screen.height - window.external.height));
- }
- }
- else {
- jdwin.left = q.getAttribute("left") || 200;
- jdwin.top = q.getAttribute("top") || 200;
- jdwin.width = q.getAttribute("width") || 800;
- jdwin.height = q.getAttribute("height") || 600;
- }
-
- jdwin.caption = q.getAttribute("caption") || "Javeline DeskRun";
- jdwin.icon = q.getAttribute("icon") || 100;
-
- var ct = $xmlns(q, "context", jpf.ns.jml);
- if (ct.length) {
- ct = ct[0];
- if (!jpf.appsettings.tray)
- jpf.appsettings.tray = window.external.CreateWidget("trayicon")
- var tray = jpf.appsettings.tray;
-
- tray.icon = q.getAttribute("tray") || 100;
- tray.tip = q.getAttribute("tooltip") || "Javeline DeskRun";
- tray.PopupClear();
- tray.PopupItemAdd("Exit", 3);
- tray.PopupItemAdd("SEP", function(){});
-
- var nodes = ct.childNodes;
- for (var i = nodes.length - 1; i >= 0; i--) {
- if (nodes[i].nodeType != 1)
- continue;
-
- if (nodes[i][jpf.TAGNAME] == "divider") {
- tray.PopupItemAdd("SEP", function(){});
- }
- else {
- tray.PopupItemAdd(jpf.getXmlValue(nodes[i], "."),
- nodes[i].getAttribute("href")
- ? new Function("window.open('" + nodes[i].getAttribute("href") + "')")
- : new Function(nodes[i].getAttribute("onclick")));
- }
- }
- }
-
- jdwin.shell.debug = jpf.debug ? 7 : 0;
- jdwin.Show();
- jdwin.SetFocus();
- };
-
- /**** Focus Internals ****/
-
-
- this.$tabList = [];
-
- this.$addFocus = function(jmlNode, tabindex, isAdmin){
- if (!isAdmin) {
- if (jmlNode.$domHandlers) {
- jmlNode.$domHandlers.reparent.push(moveFocus);
- jmlNode.$domHandlers.remove.push(removeFocus);
- }
-
- if (jmlNode.isWindowContainer > -1) {
- jmlNode.addEventListener("focus", trackChildFocus);
-
- if (!jmlNode.$tabList) {
- jmlNode.$tabList = [jmlNode];
- }
-
- jmlNode.$focusParent = jmlNode;
- this.$tabList.push(jmlNode);
-
- return;
- }
- }
-
- var fParent = findFocusParent(jmlNode);
- var list = fParent.$tabList;
-
- if (list[tabindex]) {
- jpf.console.warn("Jml node already exist for tabindex " + tabindex
- + ". Will insert " + jmlNode.tagName + " ["
- + (jmlNode.name || "") + "] before existing one");
- }
-
- jmlNode.$focusParent = fParent;
-
- if (list[tabindex])
- list.insertIndex(jmlNode, tabindex);
- else
- list.push(jmlNode);
- };
-
- this.$removeFocus = function(jmlNode){
- if (!jmlNode.$focusParent)
- return;
-
- jmlNode.$focusParent.$tabList.remove(jmlNode);
-
- if (!jmlNode.isWindowContainer && jmlNode.$domHandlers) {
- jmlNode.$domHandlers.reparent.remove(moveFocus);
- jmlNode.$domHandlers.remove.remove(removeFocus);
- }
-
- if (jmlNode.isWindowContainer > -1)
- jmlNode.removeEventListener("focus", trackChildFocus);
- };
-
- this.$focus = function(jmlNode, e, force){
- if (this.focussed == jmlNode && !force)
- return; //or maybe when force do $focus
-
- var hadAlreadyFocus = this.focussed == jmlNode;
-
- this.$settingFocus = jmlNode;
-
- if (this.focussed && this.focussed != jmlNode) {
- this.focussed.blur(true, e);
-
- }
-
- (this.focussed = jmlNode).focus(true, e);
-
- this.$settingFocus = null;
-
- jpf.dispatchEvent("movefocus", {
- toElement : this.focussed
- });
-
-
- if (!hadAlreadyFocus)
- jpf.console.info("Focus given to " + this.focussed.tagName +
- " [" + (this.focussed.name || "") + "]");
-
- if (typeof jpf.offline != "undefined" && jpf.offline.state.enabled
- && jpf.offline.state.realtime)
- jpf.offline.state.set(this, "focus", jmlNode.name || jmlNode.uniqueId);
- };
-
- this.$blur = function(jmlNode){
- if (this.focussed != jmlNode)
- return false;
-
- jpf.console.info(this.focussed.tagName + " ["
- + (this.focussed.name || "") + "] was blurred.");
-
- jpf.window.focussed.$focusParent.$lastFocussed = null;
- this.focussed = null;
-
- jpf.dispatchEvent("movefocus", {
- fromElement : jmlNode
- });
-
- };
-
- var lastFocusParent;
- this.addEventListener("focus", function(e){
- if (!jpf.window.focussed && lastFocusParent) {
- jpf.window.$focusLast(lastFocusParent);
- }
- });
- this.addEventListener("blur", function(e){
- if (!jpf.window.focussed)
- return;
-
- jpf.window.focussed.blur(true, {srcElement: this});//, {cancelBubble: true}
- lastFocusParent = jpf.window.focussed.$focusParent;
- jpf.window.focussed = null;
- });
-
- this.$focusDefault = function(jmlNode, e){
- var fParent = findFocusParent(jmlNode);
- this.$focusLast(fParent, e);
- }
-
- this.$focusRoot = function(e){
- var docEl = jpf.document.documentElement;
- if (this.$focusLast(docEl, e) === false) {
- //docEl.$lastFocussed = null;
- //this.moveNext(null, jpf.document.documentElement, true, e);
- }
- };
-
- this.$focusLast = function(jmlNode, e, ignoreVisible){
- var lf = jmlNode.$lastFocussed;
- if (lf && lf.parentNode && lf.$focussable === true
- && (ignoreVisible || lf.oExt.offsetHeight)) {
- this.$focus(lf, e, true);
- }
- else { //Let's find the object to focus first
- var str, x, node = jmlNode;
- while (node) {
- if (node.focussable !== false && node.$focussable === true
- && (ignoreVisible || node.oExt.offsetHeight)) {
- this.$focus(node, e, true);
- break;
- }
-
- //Walk sub tree
- if (node.firstChild || node.nextSibling) {
- node = node.firstChild || node.nextSibling;
- }
- else {
- do {
- node = node.parentNode;
- } while (node && !node.nextSibling && node != jmlNode)
-
- if (node == jmlNode)
- return; //do nothing
-
- if (node)
- node = node.nextSibling;
- }
- }
-
- if (!node)
- this.$focus(jpf.document.documentElement);//return false;//
-
- /*@todo get this back from SVN
- var node, list = jmlNode.$tabList;
- for (var i = 0; i < list.length; i++) {
- node = list[i];
- if (node.focussable !== false && node.$focussable === true
- && (ignoreVisible || node.oExt.offsetHeight)) {
- this.$focus(node, e, true);
- return;
- }
- }
-
- this.$focus(jpf.document.documentElement);*/
- }
- };
-
- function trackChildFocus(e){
- if (e.srcElement == this || e.trackedChild) {
- e.trackedChild = true;
- return;
- }
-
- this.$lastFocussed = e.srcElement;
-
- if (this.tagName.indexOf("window") > -1)
- e.trackedChild = true;
- }
-
- function findFocusParent(jmlNode){
- var node = jmlNode;
- do {
- node = node.parentNode;
- } while(node && !node.isWindowContainer);
- //(!node.$focussable || node.focussable === false)
-
- return node || jpf.document.documentElement;
- }
-
- //Dom handler
- //@todo make this look at the dom tree insertion point to determine tabindex
- function moveFocus(){
- if (this.isWindowContainer)
- jpf.window.$tabIndex.push(this);
- else
- jpf.window.$addFocus(this, this.tabindex, true)
- }
-
- //Dom handler
- function removeFocus(doOnlyAdmin){
- if (this.isWindowContainer) {
- jpf.window.$tabList.remove(this);
- return;
- }
-
- if (!this.$focusParent)
- return;
-
- this.$focusParent.$tabList.remove(this);
- //this.$focusParent = null; //@experimental to not execute this
- }
-
- /**** Focus API ****/
-
- /**
- * Determines whether a given jml element has the focus.
- * @param {JMLElement} the element to check
- * @returns {Boolean} whether the element has focus.
- */
- this.hasFocus = function(jmlNode){
- return this.focussed == jmlNode;
- };
-
- /**
- * @private
- */
- this.moveNext = function(shiftKey, relObject, switchWindows, e){
- var dir, start, next;
-
- if (switchWindows && jpf.window.focussed) {
- var p = jpf.window.focussed.$focusParent;
- if (p.visible && p.modal)
- return false;
- }
-
- var jmlNode = relObject || jpf.window.focussed;
- var fParent = jmlNode
- ? (switchWindows && jmlNode.isWindowContainer
- ? jpf.window
- : jmlNode.$focusParent)
- : jpf.document.documentElement;
- var list = fParent.$tabList;
-
- if (jmlNode && (switchWindows || jmlNode != jpf.document.documentElement)) {
- start = (list || []).indexOf(jmlNode);
- if (start == -1) {
- jpf.console.warn("Moving focus from element which isn't in the list\
- of it's parent. This should never happen.");
-
- return;
- }
- }
- else
- start = -1;
-
- if (this.focussed && this.focussed == jmlNode
- && list.length == 1 || list.length == 0)
- return false;
-
- dir = (shiftKey ? -1 : 1);
- next = start;
- if (start < 0)
- start = 0;
- do {
- next += dir;
-
- if (next >= list.length)
- next = 0;
- else if (next < 0)
- next = list.length - 1;
-
- if (start == next && jmlNode)
- return false; //No visible enabled element was found
-
- jmlNode = list[next];
- }
- while (!jmlNode
- || jmlNode.disabled
- || jmlNode == jpf.window.focussed
- || (switchWindows ? !jmlNode.visible : jmlNode.oExt && !jmlNode.oExt.offsetHeight)
- || jmlNode.focussable === false
- || switchWindows && !jmlNode.$tabList.length);
-
- if (fParent == jpf.window)
- this.$focusLast(jmlNode, {mouse:true}, switchWindows);
- else
- this.$focus(jmlNode, e);
-
- };
-
- /**
- * @private
- */
- this.focusDefault = function(){
- if (typeof jpf.offline != "undefined" && jpf.offline.state.enabled) {
- var node, id = jpf.offline.state.get(this, "focus");
-
- if (id == -1)
- return this.$focusRoot();
-
- if (id)
- node = self[id] || jpf.lookup(id);
-
- if (node) {
- if (!node.$focussable) {
- jpf.console.warn("Invalid offline state detected. The \
- application was probably changed in \
- between sessions. Resetting offline state\
- and rebooting.");
-
- jpf.offline.clear();
- jpf.offline.reboot();
- }
- else {
- this.$focus(node);
- return;
- }
- }
- }
-
- if (this.moveNext() === false) {
- this.moveNext(null, jpf.document.documentElement, true)
- }
- };
-
-
- /** Set Window Events **/
-
- window.onbeforeunload = function(){
- return jpf.dispatchEvent("exit");
- };
-
- if (jpf.isDeskrun)
- window.external.onbeforeunload = window.onbeforeunload;
-
- window.onunload = function(){
- jpf.window.isExiting = true;
- jpf.window.destroy();
- };
-
-
- var timer, state = "", last = "";
- this.$focusfix = function(){
- state += "a";
- clearTimeout(timer);
- setTimeout("window.focus();");
- timer = setTimeout(determineAction);
- }
-
- this.$focusfix2 = function(){
- state += "b";
- clearTimeout(timer);
- timer = setTimeout(determineAction);
- }
-
- this.$blurfix = function(){
- state += "c";
- clearTimeout(timer);
- timer = setTimeout(determineAction);
- }
-
- function determineAction(){
- clearTimeout(timer);
-
- //jpf.console.info(state);
- if (state == "e" || state == "c"
- || state.charAt(0) == "x" && !state.match(/eb$/)
- || state == "ce" || state == "de") { //|| state == "ae"
- if (last != "blur") {
- last = "blur";
- jpf.window.dispatchEvent("blur");
- //jpf.console.warn("blur");
- }
- }
- else {
- if (last != "focus") {
- last = "focus";
- jpf.window.dispatchEvent("focus");
- //jpf.console.warn("focus");
- }
- }
-
- state = "";
- timer = null;
- }
-
- window.onfocus = function(){
- if (jpf.hasFocusBug) {
- state += "d";
- clearTimeout(timer);
- timer = setTimeout(determineAction);
- }
- else {
- clearTimeout(iframeFixTimer)
- iframeFix.newState = "focus";
- //jpf.console.warn("win-focus");
- iframeFixTimer = setTimeout(iframeFix, 10);
- }
- };
-
- window.onblur = function(){
- if (jpf.hasFocusBug) {
- state += "e";
- clearTimeout(timer);
- timer = setTimeout(determineAction);
- }
- else {
- clearTimeout(iframeFixTimer)
- iframeFix.newState = "blur";
- //jpf.console.warn("win-blur");
- iframeFixTimer = setTimeout(iframeFix, 10);
- }
- };
-
- var iframeFixTimer;
- function iframeFix(){
- clearTimeout(iframeFixTimer);
-
- var newState = iframeFix.newState;
- if (last == newState)
- return;
-
- last = newState;
-
- jpf.window.dispatchEvent(last);
- //jpf.console.warn(last);
- }
-
- this.hasFocus = function(){
- return last == "focus";
- }
-
-
- /**** Keyboard and Focus Handling ****/
-
- document.oncontextmenu = function(e){
- if (!e)
- e = event;
-
- var jmlNode = jpf.findHost(e.srcElement || e.target)
- || jpf.window.focussed
- || jpf.document && jpf.document.documentElement;
-
- if (jmlNode.tagName == "menu") //The menu is already visible
- return false;
-
- var pos, ev;
-
- if (jmlNode && jmlNode.tagName == "menu")
- jmlNode = jmlNode.parentNode;
-
- if (jpf.contextMenuKeyboard) {
- if (jmlNode) {
- pos = jmlNode.selected
- ? jpf.getAbsolutePosition(jmlNode.$selected)
- : jpf.getAbsolutePosition(jmlNode.oExt || jmlNode.pHtmlNode);
- }
- else
- pos = [0, 0];
-
- var ev = {
- x : pos[0] + 10 - document.documentElement.scrollLeft,
- y : pos[1] + 10 - document.documentElement.scrollTop,
- htmlEvent : e
- }
- }
- else {
- if (e.htmlEvent)
- ev = e;
- else
- ev = { //@todo probably have to deduct the border of the window
- x : e.clientX - document.documentElement.scrollLeft,
- y : e.clientY - document.documentElement.scrollTop,
- htmlEvent : e
- }
- }
-
- ev.bubbles = true; //@todo discuss this, are we ok with bubbling?
-
- jpf.contextMenuKeyboard = null;
-
- if ((jmlNode || jpf).dispatchEvent("contextmenu", ev) === false
- || ev.returnValue === false)
- return false;
-
- if (jpf.appsettings.disableRightClick)
- return false;
- };
-
- var ta = {"INPUT":1, "TEXTAREA":1, "SELECT":1};
- document.onmousedown = function(e){
- if (!e) e = event;
- var jmlNode = jpf.findHost(e.srcElement || e.target);
-
- if (jpf.popup.last && jpf.popup.last != jmlNode.uniqueId)
- jpf.popup.forceHide();
-
- var p;
- //Make sure modal windows cannot be left
- if ((!jmlNode || !jmlNode.$focussable || jmlNode.focussable === false)
- && jpf.appsettings.allowBlur) {
- lastFocusParent = null;
- if (jpf.window.focussed)
- jpf.window.focussed.blur();
- }
- else if ((p = jpf.window.focussed && jpf.window.focussed.$focusParent || lastFocusParent)
- && p.visible && p.modal && jmlNode.$focusParent != p) {
- jpf.window.$focusLast(p, {mouse: true});
- }
- else if (!jmlNode && jpf.window.focussed) {
- jpf.window.$focusRoot();
- }
- else if (!jmlNode.disabled && jmlNode.focussable !== false) {
- if (jmlNode.$focussable === jpf.KEYBOARD_MOUSE)
- jpf.window.$focus(jmlNode, {mouse: true});
- else if (jmlNode.canHaveChildren == 2) {
- if (!jpf.appsettings.allowBlur || !jpf.window.focussed
- || jpf.window.focussed.$focusParent != jmlNode)
- jpf.window.$focusLast(jmlNode, {mouse: true});
- }
- else
- jpf.window.$focusDefault(jmlNode, {mouse: true});
- }
- else
- jpf.window.$focusDefault(jmlNode, {mouse: true});
-
- if (jpf.hasFocusBug) {
- var isContentEditable = ta[(e.srcElement || e.target).tagName]
- && !(e.srcElement || e.target).disabled || jmlNode.$isContentEditable
- && jmlNode.$isContentEditable(e) && !jmlNode.disabled;
-
- if (!jmlNode || !isContentEditable)
- jpf.window.$focusfix();
- }
- else if (!last) {
- window.onfocus();
- }
-
- jpf.dispatchEvent("mousedown", {
- htmlEvent : e,
- jmlNode : jmlNode
- });
-
- //Non IE selection handling
- if (!jpf.isIE && (jpf.JmlParser && !jpf.appsettings.allowSelect
- && (!jpf.isParsingPartial || jmlNode)
- || jpf.dragmode.mode
- ) && !ta[e.target.tagName])
- return false;
- };
-
- document.onselectstart = function(e){
- if (!e) e = event;
-
- //IE selection handling
- if (jpf.JmlParser && !jpf.appsettings.allowSelect
- || jpf.dragmode.mode
- || jpf.dragmode.isDragging
- )
- return false;
- };
-
- // Keyboard forwarding to focussed object
- document.onkeyup = function(e){
- if (!e) e = event;
-
- if (jpf.window.focussed
- && !jpf.window.focussed.disableKeyboard
- && jpf.window.focussed.dispatchEvent("keyup", {
- keyCode : e.keyCode,
- ctrlKey : e.ctrlKey,
- shiftKey : e.shiftKey,
- altKey : e.altkey,
- htmlEvent: e
- }) === false) {
- return false;
- }
-
- jpf.dispatchEvent("keyup", null, e);
- };
-
- function wheel(e) {
- if (!e)
- e = event;
-
- var delta = null;
- if (e.wheelDelta) {
- delta = e.wheelDelta / 120;
- if (jpf.isOpera)
- delta *= -1;
- }
- else if (e.detail)
- delta = -e.detail / 3;
-
- if (delta !== null) {
- var ev = {delta: delta};
- var res = jpf.dispatchEvent("mousescroll", ev);
- if (res === false || ev.returnValue === false) {
- if (e.preventDefault)
- e.preventDefault();
-
- e.returnValue = false;
- }
- }
- }
-
- if (document.addEventListener)
- document.addEventListener('DOMMouseScroll', wheel, false);
-
- window.onmousewheel =
- document.onmousewheel = wheel; //@todo 2 keer events??
-
- var keyNames = {
- "32" : "Spacebar",
- "13" : "Enter",
- "9" : "Tab",
- "27" : "Esc",
- "46" : "Del",
- "36" : "Home",
- "35" : "End",
- "107": "+",
- "37" : "Left Arrow",
- "38" : "Up Arrow",
- "39" : "Right Arrow",
- "40" : "Down Arrow",
- "33" : "Page Up",
- "34" : "Page Down",
- "112": "F1",
- "113": "F2",
- "114": "F3",
- "115": "F4",
- "116": "F5",
- "117": "F6",
- "118": "F7",
- "119": "F8",
- "120": "F9",
- "121": "F10",
- "122": "F11",
- "123": "F12"
- };
-
- document.onkeydown = function(e){
- if (!e)
- e = event;
-
- if (e.keyCode == 93)
- jpf.contextMenuKeyboard = true;
-
- //@todo move this to appsettings and use with_hotkey
- if (jpf.appsettings.useUndoKeys && e.ctrlKey) {
- //Ctrl-Z - Undo
- if (e.keyCode == 90) {
- var o = jpf.window.focussed;
- if (!o || !o.getActionTracker)
- o = jpf.window;
- o.getActionTracker().undo();
- }
- //Ctrl-Y - Redo
- else if (e.keyCode == 89) {
- var o = jpf.window.focussed;
- if (!o || !o.getActionTracker)
- o = jpf.window;
- o.getActionTracker().redo();
- }
- }
-
- var eInfo = {
- ctrlKey : e.ctrlKey,
- shiftKey : e.shiftKey,
- altKey : e.altKey,
- keyCode : e.keyCode,
- htmlEvent : e,
- bubbles : true
- };
-
- //Hotkey
- if (jpf.dispatchEvent("hotkey", eInfo) === false || eInfo.returnValue === false) {
- e.returnValue = false;
- e.cancelBubble = true;
- if (jpf.canDisableKeyCodes) {
- try {
- e.keyCode = 0;
- }
- catch(e) {}
- }
- return false;
- }
-
- var keys = []; //@todo put this in a lut
- if (e.altKey)
- keys.push("Alt");
- if (e.ctrlKey)
- keys.push("Ctrl");
- if (e.shiftKey)
- keys.push("Shift");
- if (e.metaKey)
- keys.push("Meta");
-
- if (keyNames[e.keyCode])
- keys.push(keyNames[e.keyCode]);
-
- if (keys.length) {
- if (e.keyCode > 46)
- keys.push(String.fromCharCode(e.keyCode));
- jpf.setProperty("hotkey", keys.join("-"));
- }
-
-
- //Keyboard forwarding to focussed object
- if (jpf.window.focussed && !jpf.window.focussed.disableKeyboard
- && jpf.window.focussed.dispatchEvent("keydown", eInfo) === false) {
- e.returnValue = false;
- e.cancelBubble = true;
- if (jpf.canDisableKeyCodes) {
- try {
- e.keyCode = 0;
- }
- catch(e) {}
- }
- return false;
- }
-
- //Focus handling
- else if ((!jpf.appsettings.disableTabbing || jpf.window.focussed) && e.keyCode == 9) {
- //Window focus handling
- if (e.ctrlKey && jpf.window.focussed) {
- var w = jpf.window.focussed.$focusParent;
- if (w.modal) {
- e.returnValue = false;
- return false;
- }
-
- jpf.window.moveNext(e.shiftKey,
- jpf.window.focussed.$focusParent, true);
-
- var w = jpf.window.focussed.$focusParent;
- if (w && w.bringToFront)
- w.bringToFront();
- }
- //Element focus handling
- else if(!jpf.window.focussed || jpf.window.focussed.tagName != "menu")
- jpf.window.moveNext(e.shiftKey);
-
- e.returnValue = false;
- return false;
- }
-
- //Disable backspace behaviour triggering the backbutton behaviour
- if (jpf.appsettings.disableBackspace
- && (e.keyCode == 8 || e.altKey && (e.keyCode == 37 || e.keyCode == 39))
- && !ta[(e.srcElement || e.target).tagName]) {
- if (jpf.canDisableKeyCodes) {
- try {
- e.keyCode = 0;
- }
- catch(e) {}
- }
- e.returnValue = false;
- }
-
- //Disable space behaviour of scrolling down the page
- /*if(Application.disableSpace && e.keyCode == 32 && e.srcElement.tagName.toLowerCase() != "input"){
- e.keyCode = 0;
- e.returnValue = false;
- }*/
-
- //Disable F5 refresh behaviour
- if (jpf.appsettings.disableF5 && (e.keyCode == 116 || e.keyCode == 117)) {
- if (jpf.canDisableKeyCodes) {
- try {
- e.keyCode = 0;
- }
- catch(e) {}
- }
- else {
- e.preventDefault();
- e.stopPropagation();
- }
- //return false;
- }
-
- if (e.keyCode == 27) { //or up down right left pageup pagedown home end unless body is selected
- e.returnValue = false;
- }
-
- if (!jpf.appsettings.allowSelect
- && e.shiftKey && (e.keyCode > 32 && e.keyCode < 41)
- && !ta[(e.explicitOriginalTarget || e.srcElement || e.target).tagName]
- && (!e.srcElement || e.srcElement.contentEditable != "true")) {
- e.returnValue = false;
- }
-
- //jpf.dispatchEvent("keydown", null, eInfo);
-
- return e.returnValue;
- };
-
- //@todo maybe generalize this to pub/sub event system??
- var hotkeys = {}, keyMods = {"ctrl": 1, "alt": 2, "shift": 4, "meta": 8};
-
- /**
- * Registers a hotkey handler to a key combination.
- * Example:
- * <code>
- * jpf.registerHotkey('Ctrl-Z', undoHandler);
- * </code>
- * @param {String} hotkey the key combination to user. This is a
- * combination of Ctrl, Alt, Shift and a normal key to press. Use + to
- * seperate the keys.
- * @param {Function} handler the code to be executed when the key
- * combination is pressed.
- */
- jpf.registerHotkey = function(hotkey, handler){
- var hashId = 0, key;
-
- var keys = hotkey.splitSafe("\\-|\\+| ", null, true),
- bHasCtrl = false,
- bHasMeta = false;
- for (var i = 0; i < keys.length; i++) {
- if (keyMods[keys[i]]) {
- hashId = hashId | keyMods[keys[i]];
- if (jpf.isMac) {
- bHasCtrl = (keyMods[keys[i]] === keyMods["ctrl"]);
- bHasMeta = (keyMods[keys[i]] === keyMods["meta"]);
- }
- }
- else
- key = keys[i];
- }
-
- if (bHasCtrl && !bHasMeta) //for improved Mac hotkey support
- hashId = hashId | keyMods["meta"];
-
- if (!key) {
- throw new Error("missing key for hotkey: " + hotkey);
- }
-
- (hotkeys[hashId] || (hotkeys[hashId] = {}))[key] = handler;
- };
-
- /**
- * Removes a registered hotkey.
- * @param {String} hotkey the hotkey combination.
- */
- jpf.removeHotkey = function(hotkey){
- jpf.registerHotkey(hotkey, null);
- };
-
- jpf.addEventListener("hotkey", function(e){
- // enable meta-hotkey support for macs, like for Apple-Z, Apple-C, etc.
- if (jpf.isMac && e.metaKey)
- e.ctrlKey = true;
- var hashId = 0 | (e.ctrlKey ? 1 : 0)
- | (e.shiftKey ? 2 : 0) | (e.shiftKey ? 4 : 0) | (e.metaKey ? 8 : 0);
-
- var key = keyNames[e.keyCode];
- if (!hashId && !key) //Hotkeys should always have one of the modifiers
- return;
-
- var handler = (hotkeys[hashId] || {})[(key
- || String.fromCharCode(e.keyCode)).toLowerCase()];
- if (handler) {
- handler();
- e.returnValue = false;
- }
- });
-
- this.destroy = function(){
- this.$at = null;
-
- jpf.destroy(this);
- jpf.windowManager.destroy(this);
-
- jpf =
- this.win =
- this.window =
- this.document = null;
-
- window.onfocus =
- window.onerror =
- window.onunload =
- window.onbeforeunload =
- window.onbeforeprint =
- window.onafterprint =
- window.onmousewheel =
- window.onblur = null;
-
- document.oncontextmenu =
- document.onmousedown =
- document.onmousemove =
- document.onmouseup =
- document.onselectstart =
- document.onmousewheel =
- document.onkeyup =
- document.onkeydown = null
-
- document.body.onmousedown =
- document.body.onmousemove =
- document.body.onmouseup = null;
-
- document.body.innerHTML = "";
- };
-};
-
-/**
- * The jml document. This is the jml node with nodeType 9. It is the root of
- * the application and has a refererence to the documentElement.
- *
- * @constructor
- *
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.8
- */
-jpf.DocumentImplementation = function(){
- jpf.makeClass(this);
-
- this.inherit(jpf.JmlDom); /** @inherits jpf.JmlDom */
-
- this.nodeType = jpf.NODE_DOCUMENT;
- this.nodeFunc = jpf.NODE_HIDDEN;
- this.$jmlLoaded = true;
-
- /**
- * The root element node of the jml application. This is an element with
- * the tagName 'application'. This is similar to the 'html' element
- */
- this.documentElement = {
-
- uniqueId : jpf.all.push(this) - 1,
- nodeType : 1,
- nodeFunc : jpf.NODE_HIDDEN,
- tagName : "application",
- parentNode : this,
- ownerDocument : this,
- pHtmlNode : document.body,
- $jml : jpf.JmlParser.$jml,
- $tabList : [], //Prevents documentElement from being focussed
- $jmlLoaded : true,
- $focussable : jpf.KEYBOARD,
- focussable : true,
- visible : true,
-
- isWindowContainer : true,
- canHaveChildren : true,
-
- focus : function(){
- this.dispatchEvent("focus");
- },
-
- blur : function(){
- this.dispatchEvent("blur");
- }
- };
-
- this.appendChild =
- this.insertBefore = function(){
- this.documentElement.insertBefore.apply(this.documentElement, arguments);
- };
-
- jpf.inherit.call(this.documentElement, jpf.Class);
- jpf.window.$addFocus(this.documentElement);
-
- jpf.inherit.call(this.documentElement, jpf.JmlDom);
-
- this.getElementById = function(id){
- return self[id];
- };
-
- /**
- * Creates a new jml element.
- * @param {mixed} tagName information about the new node to create.
- * Possible values:
- * {String} the tagName of the new element to create
- * {String} the jml definition for a single or multiple elements.
- * {XMLElement} the jml definition for a single or multiple elements.
- * @return {JMLElement} the created jml element.
- */
- this.createElement = function(tagName){
- var x, o;
-
- //We're supporting the nice IE hack
- if (tagName.nodeType) {
- x = tagName;
- }
- else if (tagName.indexOf("<") > -1) {
- x = jpf.getXml(tagName)
- }
- else {
- var prefix = jpf.findPrefix(jpf.JmlParser.$jml, jpf.ns.jml);
- var doc = jpf.JmlParser.$jml.ownerDocument;
-
- if(jpf.JmlParser.$jml && doc.createElementNS) {
- x = doc.createElementNS(jpf.ns.jml, prefix + ":" + tagName);
- }
- else {
- x = jpf.getXml("<" + prefix + ":" + tagName + " xmlns:"
- + prefix + "='" + jpf.ns.jml + "' />", true);
- }
- }
-
- if (jpf.isIE) {
- if (!prefix)
- prefix = x.prefix;
-
- x.ownerDocument.setProperty("SelectionNamespaces",
- "xmlns:" + prefix + "='" + jpf.ns.jml + "'");
- }
-
- tagName = x[jpf.TAGNAME];
- var initId;
-
- if (typeof jpf[tagName] != "function") { //Call JMLParser??
- o = new jpf.JmlDom(tagName, null, jpf.NODE_HIDDEN, x);
- if (jpf.JmlParser.handler[tagName]) {
- initId = o.$domHandlers["reparent"].push(function(b, pNode){
- this.$domHandlers.reparent[initId] = null;
-
- if (!pNode.$jmlLoaded)
- return; //the jmlParser will handle the rest
-
- o = jpf.JmlParser.handler[tagName](this.$jml,
- pNode, pNode.oInt);
-
- if (o) jpf.extend(this, o); //ruins prototyped things
-
- //Add this component to the nameserver
- if (o && this.name)
- jpf.nameserver.register(tagName, this.name, o);
-
- if (this.name)
- jpf.setReference(name, o);
-
- o.$jmlLoaded = true;
- }) - 1;
- }
- }
- else {
- o = new jpf[tagName](null, tagName, x);
- if (o.loadJml) {
- initId = o.$domHandlers["reparent"].push(function(b, pNode){
- this.$domHandlers.reparent[initId] = null;
-
- if (!pNode.$jmlLoaded) //We're not ready yet
- return;
-
- function loadJml(o, pHtmlNode){
- if (!o.$jmlLoaded) {
- //Process JML
- var length = o.childNodes.length;
-
- o.pHtmlNode = pHtmlNode || document.body;
- o.loadJml(o.$jml);
- o.$jmlLoaded = false; //small hack
-
- if (length) {
- for (var i = 0, l = o.childNodes.length; i < l; i++) {
- if (o.childNodes[i].loadJml) {
- loadJml(o.childNodes[i], o.canHaveChildren
- ? o.oInt
- : document.body);
- }
- else
- o.childNodes[i].$jmlLoaded = true;
- }
- }
- }
- if (o.$reappendToParent) {
- o.$reappendToParent();
- }
-
- o.$jmlLoaded = true;
- o.$reappendToParent = null;
- }
-
- var parsing = jpf.isParsing;
- jpf.isParsing = true;
- jpf.JmlParser.parseFirstPass([x]);
-
- loadJml(o, pNode && pNode.oInt || document.body);
-
- if (pNode && pNode.pData)
- jpf.layout.compileAlignment(pNode.pData);
-
- if (pNode.pData)
- jpf.layout.activateRules(pNode.oInt || document.body);
- //jpf.layout.activateRules();//@todo maybe use processQueue
-
- jpf.JmlParser.parseLastPass();
- jpf.isParsing = parsing;
- }) - 1;
- }
- }
-
- if (o.name)
- jpf.setReference(o.name, o);
-
- o.$jml = x;
-
- return o;
- };
-
- this.createDocumentFragment = function(){
- return new jpf.JmlDom(jpf.NODE_DOCUMENT_FRAGMENT)
- }
-
- /**
- * See W3C evaluate
- */
- this.evaluate = function(sExpr, contextNode, nsResolver, type, x){
- var result = jpf.XPath.selectNodes(sExpr,
- contextNode || this.documentElement);
-
- return {
- snapshotLength : result.length,
- snapshotItem : function(i){
- return result[i];
- }
- }
- };
-
- /**
- * See W3C createNSResolver
- */
- this.createNSResolver = function(contextNode){
- return {};
- };
-};
-
-
-jpf.sanitizeTextbox = function(oTxt){
- oTxt.onfocus = function(){
- jpf.window.$focusfix2();
- };
-
- oTxt.onblur = function(){
- jpf.window.$blurfix();
- };
-}
- - -/*FILEHEAD(/var/lib/jpf/src/core/crypto/rsa.js)SIZE(-1077090856)TIME(1224578765)*/ - -/** - * RSA, a suite of routines for performing RSA public-key computations in - * JavaScript. - * - * Requires BigInt.js and Barrett.js. - * - * Copyright 1998-2005 David Shapiro. - * - * You may use, re-use, abuse, copy, and modify this code to your liking, but - * please keep this header. - * - * Thanks! - * - * @author Dave Shapiro <dave AT ohdave DOT com> - */ - - -jpf.crypto.RSA = (function() { - function RSAKeyPair(encryptionExponent, decryptionExponent, modulus) { - this.e = jpf.crypto.BigInt.fromHex(encryptionExponent); - this.d = jpf.crypto.BigInt.fromHex(decryptionExponent); - this.m = jpf.crypto.BigInt.fromHex(modulus); - /* - * We can do two bytes per digit, so - * chunkSize = 2 * (number of digits in modulus - 1). - * Since biHighIndex returns the high index, not the number of digits, 1 has - * already been subtracted. - */ - ////////////////////////////////// TYF - this.digitSize = 2 * jpf.crypto.BigInt.highIndex(this.m) + 2; - this.chunkSize = this.digitSize - 11; // maximum, anything lower is fine - ////////////////////////////////// TYF - this.radix = 16; - this.barrett = new jpf.crypto.Barrett(this.m); - } - - function twoDigit(n) { - return (n < 10 ? "0" : "") + String(n); - } - - function encryptedString(key, s) { - /* - * Altered by Rob Saunders (rob@robsaunders.net). New routine pads the - * string after it has been converted to an array. This fixes an - * incompatibility with Flash MX's ActionScript. - * Altered by Tang Yu Feng for interoperability with Microsoft's - * RSACryptoServiceProvider implementation. - */ - ////////////////////////////////// TYF - if (key.chunkSize > key.digitSize - 11) { - return "Error"; - } - ////////////////////////////////// TYF - var a = new Array(); - var sl = s.length; - - var i = 0; - while (i < sl) { - a[i] = s.charCodeAt(i); - i++; - } - - var al = a.length; - var result = ""; - var j, k, block; - for (i = 0; i < al; i += key.chunkSize) { - block = new jpf.crypto.BigInt.construct(); - j = 0; - ////////////////////////////////// TYF - /* - * Add PKCS#1 v1.5 padding - * 0x00 || 0x02 || PseudoRandomNonZeroBytes || 0x00 || Message - * Variable a before padding must be of at most digitSize-11 - * That is for 3 marker bytes plus at least 8 random non-zero bytes - */ - var x; - var msgLength = (i+key.chunkSize)>al ? al%key.chunkSize : key.chunkSize; - - // Variable b with 0x00 || 0x02 at the highest index. - var b = new Array(); - for (x = 0; x < msgLength; x++) { - b[x] = a[i + msgLength - 1 - x]; - } - b[msgLength] = 0; // marker - var paddedSize = Math.max(8, key.digitSize - 3 - msgLength); - for (x = 0; x < paddedSize; x++) { - b[msgLength + 1 + x] = Math.floor(Math.random() * 254) + 1; // [1,255] - } - // It can be asserted that msgLength+paddedSize == key.digitSize-3 - b[key.digitSize - 2] = 2; // marker - b[key.digitSize - 1] = 0; // marker - - for (k = 0; k < key.digitSize; ++j) - { - block.digits[j] = b[k++]; - block.digits[j] += b[k++] << 8; - } - ////////////////////////////////// TYF - - var crypt = key.barrett.powMod(block, key.e); - var text = key.radix == 16 ? jpf.crypto.BigInt.toHex(crypt) : jpf.crypto.BigInt.toString(crypt, key.radix); - result += text + " "; - } - return result.substring(0, result.length - 1); // Remove last space. - } - - function decryptedString(key, s) { - var blocks = s.split(" "); - var result = ""; - var i, j, block; - for (i = 0; i < blocks.length; ++i) { - var bi; - if (key.radix == 16) { - bi = jpf.crypto.BigInt.fromHex(blocks[i]); - } else { - bi = jpf.crypto.BigInt.fromString(blocks[i], key.radix); - } - block = key.barrett.powMod(bi, key.d); - for (j = 0; j <= jpf.crypto.BigInt.highIndex(block); ++j) { - result += String.fromCharCode(block.digits[j] & 255, - block.digits[j] >> 8); - } - } - // Remove trailing null, if any. - if (result.charCodeAt(result.length - 1) == 0) { - result = result.substring(0, result.length - 1); - } - return result; - } - - //publish public functions: - return { - F4: "10001", - E3: "3", - getKeyPair: RSAKeyPair, - twoDigit: twoDigit, - encrypt: encryptedString, - decrypt: decryptedString - }; -})(); - - - - -/*FILEHEAD(/var/lib/jpf/src/core/crypto/barrett.js)SIZE(-1077090856)TIME(1225628610)*/ - -/**
- * Crypt.Barrett, a class for performing Barrett modular reduction computations in
- * JavaScript.
- *
- * Requires BigInt.js.
- *
- * Copyright 2004-2005 David Shapiro.
- *
- * You may use, re-use, abuse, copy, and modify this code to your liking, but
- * please keep this header.
- *
- * Thanks!
- *
- * @author Dave Shapiro <dave AT ohdave DOT com>
- */
-
-
-/**
- * A class for performing Barrett modular reduction computations in JavaScript.
- *
- * @param {jpf.crypto.BigInt} m
- */
-jpf.crypto.Barrett = function(){this.init.apply(this, arguments);};
-jpf.crypto.Barrett.prototype = {
- init: function(m) {
- this.modulus = jpf.crypto.BigInt.copy(m);
- this.k = jpf.crypto.BigInt.highIndex(this.modulus) + 1;
- var b2k = new jpf.crypto.BigInt.construct();
- b2k.digits[2 * this.k] = 1; // b2k = b^(2k)
- this.mu = jpf.crypto.BigInt.divide(b2k, this.modulus);
- this.bkplus1 = new jpf.crypto.BigInt.construct();
- this.bkplus1.digits[this.k + 1] = 1; // bkplus1 = b^(k+1)
- },
- modulo: function(x) {
- var q1 = jpf.crypto.BigInt.divideByRadixPower(x, this.k - 1);
- var q2 = jpf.crypto.BigInt.multiply(q1, this.mu);
- var q3 = jpf.crypto.BigInt.divideByRadixPower(q2, this.k + 1);
- var r1 = jpf.crypto.BigInt.moduloByRadixPower(x, this.k + 1);
- var r2term = jpf.crypto.BigInt.multiply(q3, this.modulus);
- var r2 = jpf.crypto.BigInt.moduloByRadixPower(r2term, this.k + 1);
- var r = jpf.crypto.BigInt.subtract(r1, r2);
- if (r.isNeg) {
- r = jpf.crypto.BigInt.add(r, this.bkplus1);
- }
- var rgtem = jpf.crypto.BigInt.compare(r, this.modulus) >= 0;
- while (rgtem) {
- r = jpf.crypto.BigInt.subtract(r, this.modulus);
- rgtem = jpf.crypto.BigInt.compare(r, this.modulus) >= 0;
- }
- return r;
- },
- multiplyMod: function(x, y) {
- /*
- * x = this.modulo(x);
- * y = this.modulo(y);
- */
- var xy = jpf.crypto.BigInt.multiply(x, y);
- return this.modulo(xy);
- },
- powMod: function(x, y) {
- var result = new jpf.crypto.BigInt.construct();
- result.digits[0] = 1;
- var a = x;
- var k = y;
- while (true) {
- if ((k.digits[0] & 1) != 0) result = this.multiplyMod(result, a);
- k = jpf.crypto.BigInt.shiftRight(k, 1);
- if (k.digits[0] == 0 && jpf.crypto.BigInt.highIndex(k) == 0) break;
- a = this.multiplyMod(a, a);
- }
- return result;
- }
-};
-
- - -/*FILEHEAD(/var/lib/jpf/src/core/crypto/bigint.js)SIZE(-1077090856)TIME(1225628610)*/ - -/**
- * BigInt, a suite of routines for performing multiple-precision arithmetic in
- * JavaScript.
- *
- * Copyright 1998-2005 David Shapiro.
- *
- * You may use, re-use, abuse,
- * copy, and modify this code to your liking, but please keep this header.
- * Thanks!
- *
- * @author Dave Shapiro <dave AT ohdave DOT com>
- * @author Ian Bunning
- *
- * IMPORTANT THING: Be sure to set maxDigits according to your precision
- * needs. Use the setMaxDigits() function to do this. See comments below.
- *
- * Tweaked by Ian Bunning
- * Alterations:
- * Fix bug in function biFromHex(s) to allow
- * parsing of strings of length != 0 (mod 4)
- *
- * Changes made by Dave Shapiro as of 12/30/2004:
- *
- * The BigInt() constructor doesn't take a string anymore. If you want to
- * create a BigInt from a string, use biFromDecimal() for base-10
- * representations, biFromHex() for base-16 representations, or
- * biFromString() for base-2-to-36 representations.
- *
- * biFromArray() has been removed. Use biCopy() instead, passing a BigInt
- * instead of an array.
- *
- * The BigInt() constructor now only constructs a zeroed-out array.
- * Alternatively, if you pass <true>, it won't construct any array. See the
- * biCopy() method for an example of this.
- *
- * Be sure to set maxDigits depending on your precision needs. The default
- * zeroed-out array ZERO_ARRAY is constructed inside the setMaxDigits()
- * function. So use this function to set the variable. DON'T JUST SET THE
- * VALUE. USE THE FUNCTION.
- *
- * ZERO_ARRAY exists to hopefully speed up construction of BigInts(). By
- * precalculating the zero array, we can just use slice(0) to make copies of
- * it. Presumably this calls faster native code, as opposed to setting the
- * elements one at a time. I have not done any timing tests to verify this
- * claim.
- * Max number = 10^16 - 2 = 9999999999999998;
- * 2^53 = 9007199254740992;
- */
-
-
-jpf.crypto.BigInt = (function() {
- var biRadixBase = 2;
- var biRadixBits = 16;
- var bitsPerDigit = biRadixBits;
- var biRadix = 1 << 16; // = 2^16 = 65536
- var biHalfRadix = biRadix >>> 1;
- var biRadixSquared = biRadix * biRadix;
- var maxDigitVal = biRadix - 1;
- var maxInteger = 9999999999999998;
-
- /*
- * maxDigits:
- * Change this to accommodate your largest number size. Use setMaxDigits()
- * to change it!
- *
- * In general, if you're working with numbers of size N bits, you'll need 2*N
- * bits of storage. Each digit holds 16 bits. So, a 1024-bit key will need
- *
- * 1024 * 2 / 16 = 128 digits of storage.
- */
-
- var maxDigits;
- var ZERO_ARRAY;
- var bigZero, bigOne;
-
- function setMaxDigits(value) {
- maxDigits = value;
- ZERO_ARRAY = new Array(maxDigits);
- for (var iza = 0; iza < ZERO_ARRAY.length; iza++) ZERO_ARRAY[iza] = 0;
- bigZero = new BigInt();
- bigOne = new BigInt();
- bigOne.digits[0] = 1;
- }
-
- setMaxDigits(20);
-
- // The maximum number of digits in base 10 you can convert to an
- // integer without JavaScript throwing up on you.
- var dpl10 = 15;
- // lr10 = 10 ^ dpl10
- var lr10 = biFromNumber(1000000000000000);
-
- function BigInt(flag) {
- if (typeof flag == "boolean" && flag == true) {
- this.digits = null;
- } else {
- this.digits = ZERO_ARRAY.slice(0);
- }
- this.isNeg = false;
- }
-
- function biFromDecimal(s) {
- var isNeg = s.charAt(0) == '-';
- var i = isNeg ? 1 : 0;
- var result;
- // Skip leading zeros.
- while (i < s.length && s.charAt(i) == '0') ++i;
- if (i == s.length) {
- result = new BigInt();
- } else {
- var digitCount = s.length - i;
- var fgl = digitCount % dpl10;
- if (fgl == 0) fgl = dpl10;
- result = biFromNumber(Number(s.substr(i, fgl)));
- i += fgl;
- while (i < s.length) {
- result = biAdd(biMultiply(result, lr10),
- biFromNumber(Number(s.substr(i, dpl10))));
- i += dpl10;
- }
- result.isNeg = isNeg;
- }
- return result;
- }
-
- function biCopy(bi) {
- var result = new BigInt(true);
- result.digits = bi.digits.slice(0);
- result.isNeg = bi.isNeg;
- return result;
- }
-
- function biFromNumber(i) {
- var result = new BigInt();
- result.isNeg = i < 0;
- i = Math.abs(i);
- var j = 0;
- while (i > 0) {
- result.digits[j++] = i & maxDigitVal;
- i = Math.floor(i / biRadix);
- }
- return result;
- }
-
- function reverseStr(s) {
- var result = "";
- for (var i = s.length - 1; i > -1; --i) {
- result += s.charAt(i);
- }
- return result;
- }
-
- var hexatrigesimalToChar = new Array(
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
- 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
- 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
- 'u', 'v', 'w', 'x', 'y', 'z'
- );
-
- function biToString(x, radix) {
- // 2 <= radix <= 36
- var b = new BigInt();
- b.digits[0] = radix;
- var qr = biDivideModulo(x, b);
- var result = hexatrigesimalToChar[qr[1].digits[0]];
- while (biCompare(qr[0], bigZero) == 1) {
- qr = biDivideModulo(qr[0], b);
- digit = qr[1].digits[0];
- result += hexatrigesimalToChar[qr[1].digits[0]];
- }
- return (x.isNeg ? "-" : "") + reverseStr(result);
- }
-
- function biToDecimal(x) {
- var b = new BigInt();
- b.digits[0] = 10;
- var qr = biDivideModulo(x, b);
- var result = String(qr[1].digits[0]);
- while (biCompare(qr[0], bigZero) == 1) {
- qr = biDivideModulo(qr[0], b);
- result += String(qr[1].digits[0]);
- }
- return (x.isNeg ? "-" : "") + reverseStr(result);
- }
-
- var hexToChar = new Array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
- 'a', 'b', 'c', 'd', 'e', 'f');
-
- function digitToHex(n) {
- var mask = 0xf;
- var result = "";
- for (i = 0; i < 4; ++i) {
- result += hexToChar[n & mask];
- n >>>= 4;
- }
- return reverseStr(result);
- }
-
- function biToHex(x) {
- var result = "";
- var n = biHighIndex(x);
- for (var i = biHighIndex(x); i > -1; --i) {
- result += digitToHex(x.digits[i]);
- }
- return result;
- }
-
- function charToHex(c) {
- var ZERO = 48;
- var NINE = ZERO + 9;
- var littleA = 97;
- var littleZ = littleA + 25;
- var bigA = 65;
- var bigZ = 65 + 25;
- var result;
-
- if (c >= ZERO && c <= NINE) {
- result = c - ZERO;
- } else if (c >= bigA && c <= bigZ) {
- result = 10 + c - bigA;
- } else if (c >= littleA && c <= littleZ) {
- result = 10 + c - littleA;
- } else {
- result = 0;
- }
- return result;
- }
-
- function hexToDigit(s) {
- var result = 0;
- var sl = Math.min(s.length, 4);
- for (var i = 0; i < sl; ++i) {
- result <<= 4;
- result |= charToHex(s.charCodeAt(i))
- }
- return result;
- }
-
- function biFromHex(s) {
- var result = new BigInt();
- var sl = s.length;
- for (var i = sl, j = 0; i > 0; i -= 4, ++j) {
- result.digits[j] = hexToDigit(s.substr(Math.max(i - 4, 0), Math.min(i, 4)));
- }
- return result;
- }
-
- function biFromString(s, radix) {
- var isNeg = s.charAt(0) == '-';
- var istop = isNeg ? 1 : 0;
- var result = new BigInt();
- var place = new BigInt();
- place.digits[0] = 1; // radix^0
- for (var i = s.length - 1; i >= istop; i--) {
- var c = s.charCodeAt(i);
- var digit = charToHex(c);
- var biDigit = biMultiplyDigit(place, digit);
- result = biAdd(result, biDigit);
- place = biMultiplyDigit(place, radix);
- }
- result.isNeg = isNeg;
- return result;
- }
-
- function biDump(b) {
- return (b.isNeg ? "-" : "") + b.digits.join(" ");
- }
-
- function biAdd(x, y) {
- var result;
-
- if (x.isNeg != y.isNeg) {
- y.isNeg = !y.isNeg;
- result = biSubtract(x, y);
- y.isNeg = !y.isNeg;
- } else {
- result = new BigInt();
- var c = 0;
- var n;
- for (var i = 0; i < x.digits.length; ++i) {
- n = x.digits[i] + y.digits[i] + c;
- result.digits[i] = n % biRadix;
- c = Number(n >= biRadix);
- }
- result.isNeg = x.isNeg;
- }
- return result;
- }
-
- function biSubtract(x, y) {
- var result;
- if (x.isNeg != y.isNeg) {
- y.isNeg = !y.isNeg;
- result = biAdd(x, y);
- y.isNeg = !y.isNeg;
- } else {
- result = new BigInt();
- var n, c;
- c = 0;
- for (var i = 0; i < x.digits.length; ++i) {
- n = x.digits[i] - y.digits[i] + c;
- result.digits[i] = n % biRadix;
- // Stupid non-conforming modulus operation.
- if (result.digits[i] < 0) result.digits[i] += biRadix;
- c = 0 - Number(n < 0);
- }
- // Fix up the negative sign, if any.
- if (c == -1) {
- c = 0;
- for (var i = 0; i < x.digits.length; ++i) {
- n = 0 - result.digits[i] + c;
- result.digits[i] = n % biRadix;
- // Stupid non-conforming modulus operation.
- if (result.digits[i] < 0) result.digits[i] += biRadix;
- c = 0 - Number(n < 0);
- }
- // Result is opposite sign of arguments.
- result.isNeg = !x.isNeg;
- } else {
- // Result is same sign.
- result.isNeg = x.isNeg;
- }
- }
- return result;
- }
-
- function biHighIndex(x) {
- var result = x.digits.length - 1;
- while (result > 0 && x.digits[result] == 0) --result;
- return result;
- }
-
- function biNumBits(x) {
- var n = biHighIndex(x);
- var d = x.digits[n];
- var m = (n + 1) * bitsPerDigit;
- var result;
- for (result = m; result > m - bitsPerDigit; --result) {
- if ((d & 0x8000) != 0) break;
- d <<= 1;
- }
- return result;
- }
-
- function biMultiply(x, y) {
- var result = new BigInt();
- var c;
- var n = biHighIndex(x);
- var t = biHighIndex(y);
- var u, uv, k;
-
- for (var i = 0; i <= t; ++i) {
- c = 0;
- k = i;
- for (j = 0; j <= n; ++j, ++k) {
- uv = result.digits[k] + x.digits[j] * y.digits[i] + c;
- result.digits[k] = uv & maxDigitVal;
- c = uv >>> biRadixBits;
- //c = Math.floor(uv / biRadix);
- }
- result.digits[i + n + 1] = c;
- }
- // Someone give me a logical xor, please.
- result.isNeg = x.isNeg != y.isNeg;
- return result;
- }
-
- function biMultiplyDigit(x, y) {
- var n, c, uv;
-
- result = new BigInt();
- n = biHighIndex(x);
- c = 0;
- for (var j = 0; j <= n; ++j) {
- uv = result.digits[j] + x.digits[j] * y + c;
- result.digits[j] = uv & maxDigitVal;
- c = uv >>> biRadixBits;
- //c = Math.floor(uv / biRadix);
- }
- result.digits[1 + n] = c;
- return result;
- }
-
- function arrayCopy(src, srcStart, dest, destStart, n) {
- var m = Math.min(srcStart + n, src.length);
- for (var i = srcStart, j = destStart; i < m; ++i, ++j) {
- dest[j] = src[i];
- }
- }
-
- var highBitMasks = new Array(0x0000, 0x8000, 0xC000, 0xE000, 0xF000, 0xF800,
- 0xFC00, 0xFE00, 0xFF00, 0xFF80, 0xFFC0, 0xFFE0,
- 0xFFF0, 0xFFF8, 0xFFFC, 0xFFFE, 0xFFFF);
-
- function biShiftLeft(x, n) {
- var digitCount = Math.floor(n / bitsPerDigit);
- var result = new BigInt();
- arrayCopy(x.digits, 0, result.digits, digitCount,
- result.digits.length - digitCount);
- var bits = n % bitsPerDigit;
- var rightBits = bitsPerDigit - bits;
- for (var i = result.digits.length - 1, i1 = i - 1; i > 0; --i, --i1) {
- result.digits[i] = ((result.digits[i] << bits) & maxDigitVal) |
- ((result.digits[i1] & highBitMasks[bits]) >>>
- (rightBits));
- }
- result.digits[0] = ((result.digits[i] << bits) & maxDigitVal);
- result.isNeg = x.isNeg;
- return result;
- }
-
- var lowBitMasks = new Array(0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F,
- 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF,
- 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF);
-
- function biShiftRight(x, n) {
- var digitCount = Math.floor(n / bitsPerDigit);
- var result = new BigInt();
- arrayCopy(x.digits, digitCount, result.digits, 0,
- x.digits.length - digitCount);
- var bits = n % bitsPerDigit;
- var leftBits = bitsPerDigit - bits;
- for (var i = 0, i1 = i + 1; i < result.digits.length - 1; ++i, ++i1) {
- result.digits[i] = (result.digits[i] >>> bits) |
- ((result.digits[i1] & lowBitMasks[bits]) << leftBits);
- }
- result.digits[result.digits.length - 1] >>>= bits;
- result.isNeg = x.isNeg;
- return result;
- }
-
- function biMultiplyByRadixPower(x, n) {
- var result = new BigInt();
- arrayCopy(x.digits, 0, result.digits, n, result.digits.length - n);
- return result;
- }
-
- function biDivideByRadixPower(x, n) {
- var result = new BigInt();
- arrayCopy(x.digits, n, result.digits, 0, result.digits.length - n);
- return result;
- }
-
- function biModuloByRadixPower(x, n) {
- var result = new BigInt();
- arrayCopy(x.digits, 0, result.digits, 0, n);
- return result;
- }
-
- function biCompare(x, y) {
- if (x.isNeg != y.isNeg) {
- return 1 - 2 * Number(x.isNeg);
- }
- for (var i = x.digits.length - 1; i >= 0; --i) {
- if (x.digits[i] != y.digits[i]) {
- if (x.isNeg) {
- return 1 - 2 * Number(x.digits[i] > y.digits[i]);
- } else {
- return 1 - 2 * Number(x.digits[i] < y.digits[i]);
- }
- }
- }
- return 0;
- }
-
- function biDivideModulo(x, y) {
- var nb = biNumBits(x);
- var tb = biNumBits(y);
- var origYIsNeg = y.isNeg;
- var q, r;
- if (nb < tb) {
- // |x| < |y|
- if (x.isNeg) {
- q = biCopy(bigOne);
- q.isNeg = !y.isNeg;
- x.isNeg = false;
- y.isNeg = false;
- r = biSubtract(y, x);
- // Restore signs, 'cause they're references.
- x.isNeg = true;
- y.isNeg = origYIsNeg;
- } else {
- q = new BigInt();
- r = biCopy(x);
- }
- return new Array(q, r);
- }
-
- q = new BigInt();
- r = x;
-
- // Normalize Y.
- var t = Math.ceil(tb / bitsPerDigit) - 1;
- var lambda = 0;
- while (y.digits[t] < biHalfRadix) {
- y = biShiftLeft(y, 1);
- ++lambda;
- ++tb;
- t = Math.ceil(tb / bitsPerDigit) - 1;
- }
- // Shift r over to keep the quotient constant. We'll shift the
- // remainder back at the end.
- r = biShiftLeft(r, lambda);
- nb += lambda; // Update the bit count for x.
- var n = Math.ceil(nb / bitsPerDigit) - 1;
-
- var b = biMultiplyByRadixPower(y, n - t);
- while (biCompare(r, b) != -1) {
- ++q.digits[n - t];
- r = biSubtract(r, b);
- }
- for (var i = n; i > t; --i) {
- var ri = (i >= r.digits.length) ? 0 : r.digits[i];
- var ri1 = (i - 1 >= r.digits.length) ? 0 : r.digits[i - 1];
- var ri2 = (i - 2 >= r.digits.length) ? 0 : r.digits[i - 2];
- var yt = (t >= y.digits.length) ? 0 : y.digits[t];
- var yt1 = (t - 1 >= y.digits.length) ? 0 : y.digits[t - 1];
- if (ri == yt) {
- q.digits[i - t - 1] = maxDigitVal;
- } else {
- q.digits[i - t - 1] = Math.floor((ri * biRadix + ri1) / yt);
- }
-
- var c1 = q.digits[i - t - 1] * ((yt * biRadix) + yt1);
- var c2 = (ri * biRadixSquared) + ((ri1 * biRadix) + ri2);
- while (c1 > c2) {
- --q.digits[i - t - 1];
- c1 = q.digits[i - t - 1] * ((yt * biRadix) | yt1);
- c2 = (ri * biRadix * biRadix) + ((ri1 * biRadix) + ri2);
- }
-
- b = biMultiplyByRadixPower(y, i - t - 1);
- r = biSubtract(r, biMultiplyDigit(b, q.digits[i - t - 1]));
- if (r.isNeg) {
- r = biAdd(r, b);
- --q.digits[i - t - 1];
- }
- }
- r = biShiftRight(r, lambda);
- // Fiddle with the signs and stuff to make sure that 0 <= r < y.
- q.isNeg = x.isNeg != origYIsNeg;
- if (x.isNeg) {
- if (origYIsNeg) {
- q = biAdd(q, bigOne);
- } else {
- q = biSubtract(q, bigOne);
- }
- y = biShiftRight(y, lambda);
- r = biSubtract(y, r);
- }
- // Check for the unbelievably stupid degenerate case of r == -0.
- if (r.digits[0] == 0 && biHighIndex(r) == 0) r.isNeg = false;
-
- return new Array(q, r);
- }
-
- function biDivide(x, y) {
- return biDivideModulo(x, y)[0];
- }
-
- function biModulo(x, y) {
- return biDivideModulo(x, y)[1];
- }
-
- function biMultiplyMod(x, y, m) {
- return biModulo(biMultiply(x, y), m);
- }
-
- function biPow(x, y) {
- var result = bigOne;
- var a = x;
- while (true) {
- if ((y & 1) != 0) result = biMultiply(result, a);
- y >>= 1;
- if (y == 0) break;
- a = biMultiply(a, a);
- }
- return result;
- }
-
- function biPowMod(x, y, m) {
- var result = bigOne;
- var a = x;
- var k = y;
- while (true) {
- if ((k.digits[0] & 1) != 0) result = biMultiplyMod(result, a, m);
- k = biShiftRight(k, 1);
- if (k.digits[0] == 0 && biHighIndex(k) == 0) break;
- a = biMultiplyMod(a, a, m);
- }
- return result;
- }
-
- //publish public methods:
- return {
- construct: BigInt,
- setMaxDigits: setMaxDigits,
- fromDecimal: biFromDecimal,
- copy: biCopy,
- fromNumber: biFromNumber,
- toString: biToString,
- toDecimal: biToDecimal,
- toHex: biToHex,
- fromHex: biFromHex,
- fromString: biFromString,
- dump: biDump,
- add: biAdd,
- subtract: biSubtract,
- highIndex: biHighIndex,
- numBits: biNumBits,
- multiply: biMultiply,
- shiftLeft: biShiftLeft,
- shiftRight: biShiftRight,
- compare: biCompare,
- pow: biPow,
- powMod: biPowMod,
- divide: biDivide,
- divideByRadixPower: biDivideByRadixPower,
- moduloByRadixPower: biModuloByRadixPower
- };
-})();
-
- - -/*FILEHEAD(/var/lib/jpf/src/core/crypto/base64.js)SIZE(-1077090856)TIME(1224578765)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -jpf.crypto.Base64 = (function() { - - var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; - - // public method for encoding - function encode(input) { - var output = ""; - var chr1, chr2, chr3, enc1, enc2, enc3, enc4; - var i = 0; - - input = jpf.crypto.UTF8.encode(input); - - while (i < input.length) { - chr1 = input.charCodeAt(i++); - chr2 = input.charCodeAt(i++); - chr3 = input.charCodeAt(i++); - - enc1 = chr1 >> 2; - enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); - enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); - enc4 = chr3 & 63; - - if (isNaN(chr2)) { - enc3 = enc4 = 64; - } else if (isNaN(chr3)) { - enc4 = 64; - } - - output = output + - keyStr.charAt(enc1) + keyStr.charAt(enc2) + - keyStr.charAt(enc3) + keyStr.charAt(enc4); - } - - return output; - } - - // public method for decoding - function decode(input) { - var output = ""; - var chr1, chr2, chr3; - var enc1, enc2, enc3, enc4; - var i = 0; - - input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); - - while (i < input.length) { - enc1 = keyStr.indexOf(input.charAt(i++)); - enc2 = keyStr.indexOf(input.charAt(i++)); - enc3 = keyStr.indexOf(input.charAt(i++)); - enc4 = keyStr.indexOf(input.charAt(i++)); - - chr1 = (enc1 << 2) | (enc2 >> 4); - chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); - chr3 = ((enc3 & 3) << 6) | enc4; - - output = output + String.fromCharCode(chr1); - - if (enc3 != 64) { - output = output + String.fromCharCode(chr2); - } - if (enc4 != 64) { - output = output + String.fromCharCode(chr3); - } - } - - output = jpf.crypto.UTF8.decode(output); - - return output; - } - - return { - decode: decode, - encode: encode - }; - -})(); - -jpf.crypto.UTF8 = { - // private method for UTF-8 encoding - encode : function (string) { - string = string.replace(/\r\n/g,"\n"); - var utftext = ""; - - for (var n = 0; n < string.length; n++) { - var c = string.charCodeAt(n); - - if (c < 128) { - utftext += String.fromCharCode(c); - } else if((c > 127) && (c < 2048)) { - utftext += String.fromCharCode((c >> 6) | 192); - utftext += String.fromCharCode((c & 63) | 128); - } else { - utftext += String.fromCharCode((c >> 12) | 224); - utftext += String.fromCharCode(((c >> 6) & 63) | 128); - utftext += String.fromCharCode((c & 63) | 128); - } - - } - - return utftext; - }, - - // private method for UTF-8 decoding - decode : function (utftext) { - var string = ""; - var i = 0; - var c = c1 = c2 = 0; - - while (i < utftext.length) { - c = utftext.charCodeAt(i); - - if (c < 128) { - string += String.fromCharCode(c); - i++; - } else if((c > 191) && (c < 224)) { - c2 = utftext.charCodeAt(i+1); - string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); - i += 2; - } else { - c2 = utftext.charCodeAt(i+1); - c3 = utftext.charCodeAt(i+2); - string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); - i += 3; - } - } - - return string; - } - -}; - - - -/*FILEHEAD(/var/lib/jpf/src/core/crypto/blowfish.js)SIZE(-1077090856)TIME(1224578765)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -/* - * Copyright (C) 2005 - Stephen Griffin, i-code.co.uk - * Copyright (C) 2005 - Raphael Derosso Pereira - thyAPI adaptation - * <raphaelpereira@users.sourceforge.net> - */ - -(function(global) { - -if (typeof jpf.crypt == "undefined") jpf.crypt = {}; - -function stringtoints(instring){ - var binary = []; - var i, ch; - - for (i = 0; i < instring.length; i++) { - ch = instring.charCodeAt(i); - binary[i >> 2] |= ch << (3 - i % 4) * 8; - } - return binary; -} - -function intstostring(intvalues){ - var outstring = new String(); - - for (var i = 0; i < intvalues.length; i++) { - outstring += String.fromCharCode(intvalues[i] >>> 24, - (intvalues[i] >>> 16) & 0xff, (intvalues[i] >>> 8) & 0xff, - intvalues[i] & 0xff); - } - return outstring; -} - -function base64tobin(codestring){ - var temp, i = 0; - var binary = []; - - while (i < codestring.length * 6) { - temp = codestring.charCodeAt(i / 6); - - if (temp > 47 && temp < 58) - temp -= 48; - if (temp > 62 && temp < 91) - temp -= 53; - if (temp > 96 && temp < 123) - temp -= 59; - - switch (i & 0x1f) { //i%32 - case 0: - binary[i >> 5] = temp; - i += 6; - break; - case 28: - binary[i >> 5] = (binary[i >> 5] << 4) | (temp >> 2); - i += 4; - binary[i >> 5] = temp & 0x03; - i += 2; - break; - case 30: - binary[i >> 5] = (binary[i >> 5] << 2) | (temp >> 4); - i += 2; - binary[i >> 5] = temp & 0x0f; - i += 4; - break; - default: - binary[i >> 5] = (binary[i >> 5] << 6) | temp; - i += 6; - } - } - return binary; -} - -function base64encode(binary){ - var temp, bincount = 0; - var codestring = ""; - var chars = "0123456789?@ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - - while (bincount < binary.length) { - for (x = 0; x < 2; x++) { - temp = binary[bincount] >>> 26; - codestring += chars.charAt(temp); - temp = (binary[bincount] >>> 20) & 0x3f; - codestring += chars.charAt(temp); - - temp = (binary[bincount] >>> 14) & 0x3f; - codestring += chars.charAt(temp); - - temp = (binary[bincount] >>> 8) & 0x3f; - codestring += chars.charAt(temp); - - temp = (binary[bincount] >>> 2) & 0x3f; - codestring += chars.charAt(temp); - - temp = (binary[bincount++] & 0x3) << 4; - temp = temp | (binary[bincount] >>> 28); - codestring += chars.charAt(temp); - - temp = (binary[bincount] >>> 22) & 0x3f; - codestring += chars.charAt(temp); - - temp = (binary[bincount] >>> 16) & 0x3f; - codestring += chars.charAt(temp); - - temp = (binary[bincount] >>> 10) & 0x3f; - codestring += chars.charAt(temp); - - temp = (binary[bincount] >>> 4) & 0x3f; - codestring += chars.charAt(temp); - - temp = (binary[bincount++] & 0xf) << 2; - temp = temp | (binary[bincount] >>> 30); - codestring += chars.charAt(temp); - - temp = (binary[bincount] >>> 24) & 0x3f; - codestring += chars.charAt(temp); - - temp = (binary[bincount] >>> 18) & 0x3f; - codestring += chars.charAt(temp); - - temp = (binary[bincount] >>> 12) & 0x3f; - codestring += chars.charAt(temp); - - temp = (binary[bincount] >>> 6) & 0x3f; - codestring += chars.charAt(temp); - - temp = binary[bincount++] & 0x3f; - codestring += chars.charAt(temp); - } - } - return codestring; -} - -/** - * Class: Blowfish - * - * Blowfish cypher class. - * - * Algorithm gently taken from i-code.co.uk. Thanks Stephen! - * - */ -jpf.crypto.Blowfish = function(){this.init.apply(this, arguments);}; -jpf.crypto.Blowfish.prototype = { - init: function(m){ - this.P; - this.S; - this.previous_xHi = 0; - this.previous_xLo = 0; - }, - - /** - * Encodes the text passed with key - * - * @param {String} str The text to be encoded - * @param {String} pass The key to be used to encode the text - * @return Base64 encoded string - * @type String - */ - encode: function(str, pass){ - var ciphertext = new String(""); - var IV = new Array(); - - for (x = 0; x < 4; x++) { - if (typeof(this.customRand) == 'function') { - IV[x] = this.customRand(); - } else { - IV[x] = Math.floor(Math.random() * 0xFFFFFFFF); - } - } - - var key = this.passtokey(pass, IV[2], IV[3], IV[4]); - IV[4] = key[14];//hashHi - IV[5] = key[15];//hashLo - this.initialise(key, IV); - - var binary = stringtoints(str); - this.encipher_array(binary); - - return { - code: base64encode(binary), - init: base64encode(IV) - }; - }, - - /** - * Decodes a base64 encoded string to the original one, if key is correct - * - * @param {String} code The cyphered code - * @param {String} pass The key to be used - * @param {Number} init The base64 initialization int - */ - decode: function(code, pass, init){ - var initialints = base64tobin(init); - var key = this.passtokey(pass, initialints[2], initialints[3]); - - if ((initialints[4] == key[14]) && (initialints[5] == key[15])) { //check password hash - this.initialise(key, initialints); - var bincode = base64tobin(code); - this.decipher(bincode); - return intstostring(bincode); - } - - return null; - }, - - setConstants: function(){ - var s0 = [0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7, 0xB8E1AFED, - 0x6A267E96, 0xBA7C9045, 0xF12C7F99, 0x24A19947, 0xB3916CF7, 0x0801F2E2, - 0x858EFC16, 0x636920D8, 0x71574E69, 0xA458FEA3, 0xF4933D7E, 0x0D95748F, - 0x728EB658, 0x718BCD58, 0x82154AEE, 0x7B54A41D, 0xC25A59B5, 0x9C30D539, - 0x2AF26013, 0xC5D1B023, 0x286085F0, 0xCA417918, 0xB8DB38EF, 0x8E79DCB0, - 0x603A180E, 0x6C9E0E8B, 0xB01E8A3E, 0xD71577C1, 0xBD314B27, 0x78AF2FDA, - 0x55605C60, 0xE65525F3, 0xAA55AB94, 0x57489862, 0x63E81440, 0x55CA396A, - 0x2AAB10B6, 0xB4CC5C34, 0x1141E8CE, 0xA15486AF, 0x7C72E993, 0xB3EE1411, - 0x636FBC2A, 0x2BA9C55D, 0x741831F6, 0xCE5C3E16, 0x9B87931E, 0xAFD6BA33, - 0x6C24CF5C, 0x7A325381, 0x28958677, 0x3B8F4898, 0x6B4BB9AF, 0xC4BFE81B, - 0x66282193, 0x61D809CC, 0xFB21A991, 0x487CAC60, 0x5DEC8032, 0xEF845D5D, - 0xE98575B1, 0xDC262302, 0xEB651B88, 0x23893E81, 0xD396ACC5, 0x0F6D6FF3, - 0x83F44239, 0x2E0B4482, 0xA4842004, 0x69C8F04A, 0x9E1F9B5E, 0x21C66842, - 0xF6E96C9A, 0x670C9C61, 0xABD388F0, 0x6A51A0D2, 0xD8542F68, 0x960FA728, - 0xAB5133A3, 0x6EEF0B6C, 0x137A3BE4, 0xBA3BF050, 0x7EFB2A98, 0xA1F1651D, - 0x39AF0176, 0x66CA593E, 0x82430E88, 0x8CEE8619, 0x456F9FB4, 0x7D84A5C3, - 0x3B8B5EBE, 0xE06F75D8, 0x85C12073, 0x401A449F, 0x56C16AA6, 0x4ED3AA62, - 0x363F7706, 0x1BFEDF72, 0x429B023D, 0x37D0D724, 0xD00A1248, 0xDB0FEAD3, - 0x49F1C09B, 0x075372C9, 0x80991B7B, 0x25D479D8, 0xF6E8DEF7, 0xE3FE501A, - 0xB6794C3B, 0x976CE0BD, 0x04C006BA, 0xC1A94FB6, 0x409F60C4, 0x5E5C9EC2, - 0x196A2463, 0x68FB6FAF, 0x3E6C53B5, 0x1339B2EB, 0x3B52EC6F, 0x6DFC511F, - 0x9B30952C, 0xCC814544, 0xAF5EBD09, 0xBEE3D004, 0xDE334AFD, 0x660F2807, - 0x192E4BB3, 0xC0CBA857, 0x45C8740F, 0xD20B5F39, 0xB9D3FBDB, 0x5579C0BD, - 0x1A60320A, 0xD6A100C6, 0x402C7279, 0x679F25FE, 0xFB1FA3CC, 0x8EA5E9F8, - 0xDB3222F8, 0x3C7516DF, 0xFD616B15, 0x2F501EC8, 0xAD0552AB, 0x323DB5FA, - 0xFD238760, 0x53317B48, 0x3E00DF82, 0x9E5C57BB, 0xCA6F8CA0, 0x1A87562E, - 0xDF1769DB, 0xD542A8F6, 0x287EFFC3, 0xAC6732C6, 0x8C4F5573, 0x695B27B0, - 0xBBCA58C8, 0xE1FFA35D, 0xB8F011A0, 0x10FA3D98, 0xFD2183B8, 0x4AFCB56C, - 0x2DD1D35B, 0x9A53E479, 0xB6F84565, 0xD28E49BC, 0x4BFB9790, 0xE1DDF2DA, - 0xA4CB7E33, 0x62FB1341, 0xCEE4C6E8, 0xEF20CADA, 0x36774C01, 0xD07E9EFE, - 0x2BF11FB4, 0x95DBDA4D, 0xAE909198, 0xEAAD8E71, 0x6B93D5A0, 0xD08ED1D0, - 0xAFC725E0, 0x8E3C5B2F, 0x8E7594B7, 0x8FF6E2FB, 0xF2122B64, 0x8888B812, - 0x900DF01C, 0x4FAD5EA0, 0x688FC31C, 0xD1CFF191, 0xB3A8C1AD, 0x2F2F2218, - 0xBE0E1777, 0xEA752DFE, 0x8B021FA1, 0xE5A0CC0F, 0xB56F74E8, 0x18ACF3D6, - 0xCE89E299, 0xB4A84FE0, 0xFD13E0B7, 0x7CC43B81, 0xD2ADA8D9, 0x165FA266, - 0x80957705, 0x93CC7314, 0x211A1477, 0xE6AD2065, 0x77B5FA86, 0xC75442F5, - 0xFB9D35CF, 0xEBCDAF0C, 0x7B3E89A0, 0xD6411BD3, 0xAE1E7E49, 0x00250E2D, - 0x2071B35E, 0x226800BB, 0x57B8E0AF, 0x2464369B, 0xF009B91E, 0x5563911D, - 0x59DFA6AA, 0x78C14389, 0xD95A537F, 0x207D5BA2, 0x02E5B9C5, 0x83260376, - 0x6295CFA9, 0x11C81968, 0x4E734A41, 0xB3472DCA, 0x7B14A94A, 0x1B510052, - 0x9A532915, 0xD60F573F, 0xBC9BC6E4, 0x2B60A476, 0x81E67400, 0x08BA6FB5, - 0x571BE91F, 0xF296EC6B, 0x2A0DD915, 0xB6636521, 0xE7B9F9B6, 0xFF34052E, - 0xC5855664, 0x53B02D5D, 0xA99F8FA1, 0x08BA4799, 0x6E85076A]; - - var s1 = [0x4B7A70E9, 0xB5B32944, 0xDB75092E, 0xC4192623, 0xAD6EA6B0, 0x49A7DF7D, - 0x9CEE60B8, 0x8FEDB266, 0xECAA8C71, 0x699A17FF, 0x5664526C, 0xC2B19EE1, - 0x193602A5, 0x75094C29, 0xA0591340, 0xE4183A3E, 0x3F54989A, 0x5B429D65, - 0x6B8FE4D6, 0x99F73FD6, 0xA1D29C07, 0xEFE830F5, 0x4D2D38E6, 0xF0255DC1, - 0x4CDD2086, 0x8470EB26, 0x6382E9C6, 0x021ECC5E, 0x09686B3F, 0x3EBAEFC9, - 0x3C971814, 0x6B6A70A1, 0x687F3584, 0x52A0E286, 0xB79C5305, 0xAA500737, - 0x3E07841C, 0x7FDEAE5C, 0x8E7D44EC, 0x5716F2B8, 0xB03ADA37, 0xF0500C0D, - 0xF01C1F04, 0x0200B3FF, 0xAE0CF51A, 0x3CB574B2, 0x25837A58, 0xDC0921BD, - 0xD19113F9, 0x7CA92FF6, 0x94324773, 0x22F54701, 0x3AE5E581, 0x37C2DADC, - 0xC8B57634, 0x9AF3DDA7, 0xA9446146, 0x0FD0030E, 0xECC8C73E, 0xA4751E41, - 0xE238CD99, 0x3BEA0E2F, 0x3280BBA1, 0x183EB331, 0x4E548B38, 0x4F6DB908, - 0x6F420D03, 0xF60A04BF, 0x2CB81290, 0x24977C79, 0x5679B072, 0xBCAF89AF, - 0xDE9A771F, 0xD9930810, 0xB38BAE12, 0xDCCF3F2E, 0x5512721F, 0x2E6B7124, - 0x501ADDE6, 0x9F84CD87, 0x7A584718, 0x7408DA17, 0xBC9F9ABC, 0xE94B7D8C, - 0xEC7AEC3A, 0xDB851DFA, 0x63094366, 0xC464C3D2, 0xEF1C1847, 0x3215D908, - 0xDD433B37, 0x24C2BA16, 0x12A14D43, 0x2A65C451, 0x50940002, 0x133AE4DD, - 0x71DFF89E, 0x10314E55, 0x81AC77D6, 0x5F11199B, 0x043556F1, 0xD7A3C76B, - 0x3C11183B, 0x5924A509, 0xF28FE6ED, 0x97F1FBFA, 0x9EBABF2C, 0x1E153C6E, - 0x86E34570, 0xEAE96FB1, 0x860E5E0A, 0x5A3E2AB3, 0x771FE71C, 0x4E3D06FA, - 0x2965DCB9, 0x99E71D0F, 0x803E89D6, 0x5266C825, 0x2E4CC978, 0x9C10B36A, - 0xC6150EBA, 0x94E2EA78, 0xA5FC3C53, 0x1E0A2DF4, 0xF2F74EA7, 0x361D2B3D, - 0x1939260F, 0x19C27960, 0x5223A708, 0xF71312B6, 0xEBADFE6E, 0xEAC31F66, - 0xE3BC4595, 0xA67BC883, 0xB17F37D1, 0x018CFF28, 0xC332DDEF, 0xBE6C5AA5, - 0x65582185, 0x68AB9802, 0xEECEA50F, 0xDB2F953B, 0x2AEF7DAD, 0x5B6E2F84, - 0x1521B628, 0x29076170, 0xECDD4775, 0x619F1510, 0x13CCA830, 0xEB61BD96, - 0x0334FE1E, 0xAA0363CF, 0xB5735C90, 0x4C70A239, 0xD59E9E0B, 0xCBAADE14, - 0xEECC86BC, 0x60622CA7, 0x9CAB5CAB, 0xB2F3846E, 0x648B1EAF, 0x19BDF0CA, - 0xA02369B9, 0x655ABB50, 0x40685A32, 0x3C2AB4B3, 0x319EE9D5, 0xC021B8F7, - 0x9B540B19, 0x875FA099, 0x95F7997E, 0x623D7DA8, 0xF837889A, 0x97E32D77, - 0x11ED935F, 0x16681281, 0x0E358829, 0xC7E61FD6, 0x96DEDFA1, 0x7858BA99, - 0x57F584A5, 0x1B227263, 0x9B83C3FF, 0x1AC24696, 0xCDB30AEB, 0x532E3054, - 0x8FD948E4, 0x6DBC3128, 0x58EBF2EF, 0x34C6FFEA, 0xFE28ED61, 0xEE7C3C73, - 0x5D4A14D9, 0xE864B7E3, 0x42105D14, 0x203E13E0, 0x45EEE2B6, 0xA3AAABEA, - 0xDB6C4F15, 0xFACB4FD0, 0xC742F442, 0xEF6ABBB5, 0x654F3B1D, 0x41CD2105, - 0xD81E799E, 0x86854DC7, 0xE44B476A, 0x3D816250, 0xCF62A1F2, 0x5B8D2646, - 0xFC8883A0, 0xC1C7B6A3, 0x7F1524C3, 0x69CB7492, 0x47848A0B, 0x5692B285, - 0x095BBF00, 0xAD19489D, 0x1462B174, 0x23820E00, 0x58428D2A, 0x0C55F5EA, - 0x1DADF43E, 0x233F7061, 0x3372F092, 0x8D937E41, 0xD65FECF1, 0x6C223BDB, - 0x7CDE3759, 0xCBEE7460, 0x4085F2A7, 0xCE77326E, 0xA6078084, 0x19F8509E, - 0xE8EFD855, 0x61D99735, 0xA969A7AA, 0xC50C06C2, 0x5A04ABFC, 0x800BCADC, - 0x9E447A2E, 0xC3453484, 0xFDD56705, 0x0E1E9EC9, 0xDB73DBD3, 0x105588CD, - 0x675FDA79, 0xE3674340, 0xC5C43465, 0x713E38D8, 0x3D28F89E, 0xF16DFF20, - 0x153E21E7, 0x8FB03D4A, 0xE6E39F2B, 0xDB83ADF7]; - - var s2 = [0xE93D5A68, 0x948140F7, 0xF64C261C, 0x94692934, 0x411520F7, 0x7602D4F7, - 0xBCF46B2E, 0xD4A20068, 0xD4082471, 0x3320F46A, 0x43B7D4B7, 0x500061AF, - 0x1E39F62E, 0x97244546, 0x14214F74, 0xBF8B8840, 0x4D95FC1D, 0x96B591AF, - 0x70F4DDD3, 0x66A02F45, 0xBFBC09EC, 0x03BD9785, 0x7FAC6DD0, 0x31CB8504, - 0x96EB27B3, 0x55FD3941, 0xDA2547E6, 0xABCA0A9A, 0x28507825, 0x530429F4, - 0x0A2C86DA, 0xE9B66DFB, 0x68DC1462, 0xD7486900, 0x680EC0A4, 0x27A18DEE, - 0x4F3FFEA2, 0xE887AD8C, 0xB58CE006, 0x7AF4D6B6, 0xAACE1E7C, 0xD3375FEC, - 0xCE78A399, 0x406B2A42, 0x20FE9E35, 0xD9F385B9, 0xEE39D7AB, 0x3B124E8B, - 0x1DC9FAF7, 0x4B6D1856, 0x26A36631, 0xEAE397B2, 0x3A6EFA74, 0xDD5B4332, - 0x6841E7F7, 0xCA7820FB, 0xFB0AF54E, 0xD8FEB397, 0x454056AC, 0xBA489527, - 0x55533A3A, 0x20838D87, 0xFE6BA9B7, 0xD096954B, 0x55A867BC, 0xA1159A58, - 0xCCA92963, 0x99E1DB33, 0xA62A4A56, 0x3F3125F9, 0x5EF47E1C, 0x9029317C, - 0xFDF8E802, 0x04272F70, 0x80BB155C, 0x05282CE3, 0x95C11548, 0xE4C66D22, - 0x48C1133F, 0xC70F86DC, 0x07F9C9EE, 0x41041F0F, 0x404779A4, 0x5D886E17, - 0x325F51EB, 0xD59BC0D1, 0xF2BCC18F, 0x41113564, 0x257B7834, 0x602A9C60, - 0xDFF8E8A3, 0x1F636C1B, 0x0E12B4C2, 0x02E1329E, 0xAF664FD1, 0xCAD18115, - 0x6B2395E0, 0x333E92E1, 0x3B240B62, 0xEEBEB922, 0x85B2A20E, 0xE6BA0D99, - 0xDE720C8C, 0x2DA2F728, 0xD0127845, 0x95B794FD, 0x647D0862, 0xE7CCF5F0, - 0x5449A36F, 0x877D48FA, 0xC39DFD27, 0xF33E8D1E, 0x0A476341, 0x992EFF74, - 0x3A6F6EAB, 0xF4F8FD37, 0xA812DC60, 0xA1EBDDF8, 0x991BE14C, 0xDB6E6B0D, - 0xC67B5510, 0x6D672C37, 0x2765D43B, 0xDCD0E804, 0xF1290DC7, 0xCC00FFA3, - 0xB5390F92, 0x690FED0B, 0x667B9FFB, 0xCEDB7D9C, 0xA091CF0B, 0xD9155EA3, - 0xBB132F88, 0x515BAD24, 0x7B9479BF, 0x763BD6EB, 0x37392EB3, 0xCC115979, - 0x8026E297, 0xF42E312D, 0x6842ADA7, 0xC66A2B3B, 0x12754CCC, 0x782EF11C, - 0x6A124237, 0xB79251E7, 0x06A1BBE6, 0x4BFB6350, 0x1A6B1018, 0x11CAEDFA, - 0x3D25BDD8, 0xE2E1C3C9, 0x44421659, 0x0A121386, 0xD90CEC6E, 0xD5ABEA2A, - 0x64AF674E, 0xDA86A85F, 0xBEBFE988, 0x64E4C3FE, 0x9DBC8057, 0xF0F7C086, - 0x60787BF8, 0x6003604D, 0xD1FD8346, 0xF6381FB0, 0x7745AE04, 0xD736FCCC, - 0x83426B33, 0xF01EAB71, 0xB0804187, 0x3C005E5F, 0x77A057BE, 0xBDE8AE24, - 0x55464299, 0xBF582E61, 0x4E58F48F, 0xF2DDFDA2, 0xF474EF38, 0x8789BDC2, - 0x5366F9C3, 0xC8B38E74, 0xB475F255, 0x46FCD9B9, 0x7AEB2661, 0x8B1DDF84, - 0x846A0E79, 0x915F95E2, 0x466E598E, 0x20B45770, 0x8CD55591, 0xC902DE4C, - 0xB90BACE1, 0xBB8205D0, 0x11A86248, 0x7574A99E, 0xB77F19B6, 0xE0A9DC09, - 0x662D09A1, 0xC4324633, 0xE85A1F02, 0x09F0BE8C, 0x4A99A025, 0x1D6EFE10, - 0x1AB93D1D, 0x0BA5A4DF, 0xA186F20F, 0x2868F169, 0xDCB7DA83, 0x573906FE, - 0xA1E2CE9B, 0x4FCD7F52, 0x50115E01, 0xA70683FA, 0xA002B5C4, 0x0DE6D027, - 0x9AF88C27, 0x773F8641, 0xC3604C06, 0x61A806B5, 0xF0177A28, 0xC0F586E0, - 0x006058AA, 0x30DC7D62, 0x11E69ED7, 0x2338EA63, 0x53C2DD94, 0xC2C21634, - 0xBBCBEE56, 0x90BCB6DE, 0xEBFC7DA1, 0xCE591D76, 0x6F05E409, 0x4B7C0188, - 0x39720A3D, 0x7C927C24, 0x86E3725F, 0x724D9DB9, 0x1AC15BB4, 0xD39EB8FC, - 0xED545578, 0x08FCA5B5, 0xD83D7CD3, 0x4DAD0FC4, 0x1E50EF5E, 0xB161E6F8, - 0xA28514D9, 0x6C51133C, 0x6FD5C7E7, 0x56E14EC4, 0x362ABFCE, 0xDDC6C837, - 0xD79A3234, 0x92638212, 0x670EFA8E, 0x406000E0]; - - var s3 = [0x3A39CE37, 0xD3FAF5CF, 0xABC27737, 0x5AC52D1B, 0x5CB0679E, 0x4FA33742, - 0xD3822740, 0x99BC9BBE, 0xD5118E9D, 0xBF0F7315, 0xD62D1C7E, 0xC700C47B, - 0xB78C1B6B, 0x21A19045, 0xB26EB1BE, 0x6A366EB4, 0x5748AB2F, 0xBC946E79, - 0xC6A376D2, 0x6549C2C8, 0x530FF8EE, 0x468DDE7D, 0xD5730A1D, 0x4CD04DC6, - 0x2939BBDB, 0xA9BA4650, 0xAC9526E8, 0xBE5EE304, 0xA1FAD5F0, 0x6A2D519A, - 0x63EF8CE2, 0x9A86EE22, 0xC089C2B8, 0x43242EF6, 0xA51E03AA, 0x9CF2D0A4, - 0x83C061BA, 0x9BE96A4D, 0x8FE51550, 0xBA645BD6, 0x2826A2F9, 0xA73A3AE1, - 0x4BA99586, 0xEF5562E9, 0xC72FEFD3, 0xF752F7DA, 0x3F046F69, 0x77FA0A59, - 0x80E4A915, 0x87B08601, 0x9B09E6AD, 0x3B3EE593, 0xE990FD5A, 0x9E34D797, - 0x2CF0B7D9, 0x022B8B51, 0x96D5AC3A, 0x017DA67D, 0xD1CF3ED6, 0x7C7D2D28, - 0x1F9F25CF, 0xADF2B89B, 0x5AD6B472, 0x5A88F54C, 0xE029AC71, 0xE019A5E6, - 0x47B0ACFD, 0xED93FA9B, 0xE8D3C48D, 0x283B57CC, 0xF8D56629, 0x79132E28, - 0x785F0191, 0xED756055, 0xF7960E44, 0xE3D35E8C, 0x15056DD4, 0x88F46DBA, - 0x03A16125, 0x0564F0BD, 0xC3EB9E15, 0x3C9057A2, 0x97271AEC, 0xA93A072A, - 0x1B3F6D9B, 0x1E6321F5, 0xF59C66FB, 0x26DCF319, 0x7533D928, 0xB155FDF5, - 0x03563482, 0x8ABA3CBB, 0x28517711, 0xC20AD9F8, 0xABCC5167, 0xCCAD925F, - 0x4DE81751, 0x3830DC8E, 0x379D5862, 0x9320F991, 0xEA7A90C2, 0xFB3E7BCE, - 0x5121CE64, 0x774FBE32, 0xA8B6E37E, 0xC3293D46, 0x48DE5369, 0x6413E680, - 0xA2AE0810, 0xDD6DB224, 0x69852DFD, 0x09072166, 0xB39A460A, 0x6445C0DD, - 0x586CDECF, 0x1C20C8AE, 0x5BBEF7DD, 0x1B588D40, 0xCCD2017F, 0x6BB4E3BB, - 0xDDA26A7E, 0x3A59FF45, 0x3E350A44, 0xBCB4CDD5, 0x72EACEA8, 0xFA6484BB, - 0x8D6612AE, 0xBF3C6F47, 0xD29BE463, 0x542F5D9E, 0xAEC2771B, 0xF64E6370, - 0x740E0D8D, 0xE75B1357, 0xF8721671, 0xAF537D5D, 0x4040CB08, 0x4EB4E2CC, - 0x34D2466A, 0x0115AF84, 0xE1B00428, 0x95983A1D, 0x06B89FB4, 0xCE6EA048, - 0x6F3F3B82, 0x3520AB82, 0x011A1D4B, 0x277227F8, 0x611560B1, 0xE7933FDC, - 0xBB3A792B, 0x344525BD, 0xA08839E1, 0x51CE794B, 0x2F32C9B7, 0xA01FBAC9, - 0xE01CC87E, 0xBCC7D1F6, 0xCF0111C3, 0xA1E8AAC7, 0x1A908749, 0xD44FBD9A, - 0xD0DADECB, 0xD50ADA38, 0x0339C32A, 0xC6913667, 0x8DF9317C, 0xE0B12B4F, - 0xF79E59B7, 0x43F5BB3A, 0xF2D519FF, 0x27D9459C, 0xBF97222C, 0x15E6FC2A, - 0x0F91FC71, 0x9B941525, 0xFAE59361, 0xCEB69CEB, 0xC2A86459, 0x12BAA8D1, - 0xB6C1075E, 0xE3056A0C, 0x10D25065, 0xCB03A442, 0xE0EC6E0E, 0x1698DB3B, - 0x4C98A0BE, 0x3278E964, 0x9F1F9532, 0xE0D392DF, 0xD3A0342B, 0x8971F21E, - 0x1B0A7441, 0x4BA3348C, 0xC5BE7120, 0xC37632D8, 0xDF359F8D, 0x9B992F2E, - 0xE60B6F47, 0x0FE3F11D, 0xE54CDA54, 0x1EDAD891, 0xCE6279CF, 0xCD3E7E6F, - 0x1618B166, 0xFD2C1D05, 0x848FD2C5, 0xF6FB2299, 0xF523F357, 0xA6327623, - 0x93A83531, 0x56CCCD02, 0xACF08162, 0x5A75EBB5, 0x6E163697, 0x88D273CC, - 0xDE966292, 0x81B949D0, 0x4C50901B, 0x71C65614, 0xE6C6C7BD, 0x327A140A, - 0x45E1D006, 0xC3F27B9A, 0xC9AA53FD, 0x62A80F00, 0xBB25BFE2, 0x35BDD2F6, - 0x71126905, 0xB2040222, 0xB6CBCF7C, 0xCD769C2B, 0x53113EC0, 0x1640E3D3, - 0x38ABBD60, 0x2547ADF0, 0xBA38209C, 0xF746CE76, 0x77AFA1C5, 0x20756060, - 0x85CBFE4E, 0x8AE88DD8, 0x7AAAF9B0, 0x4CF9AA7E, 0x1948C25C, 0x02FB8A8C, - 0x01C36AE4, 0xD6EBE1F9, 0x90D4F869, 0xA65CDEA0, 0x3F09252D, 0xC208E69F, - 0xB74E6132, 0xCE77E25B, 0x578FDFE3, 0x3AC372E6]; - - this.S = [s0, s1, s2, s3]; - - this.P = [0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344, 0xA4093822, 0x299F31D0, - 0x082EFA98, 0xEC4E6C89, 0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C, - 0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917, 0x9216D5D9, 0x8979FB1B]; - }, - - encipher: function(x){ - var xHi = x[0]; - var xLo = x[1]; - var Round = 0; - - xHi ^= this.P[0]; - - while (Round < 16) { - xLo ^= (((this.S[0][xHi >>> 24] + this.S[1][(xHi >>> 16) & 0x0ff]) - ^ this.S[2][(xHi >>> 8) & 0x0ff]) + this.S[3][xHi & 0x0ff]) ^ this.P[++Round]; - xHi ^= (((this.S[0][xLo >>> 24] + this.S[1][(xLo >>> 16) & 0x0ff]) - ^ this.S[2][(xLo >>> 8) & 0x0ff]) + this.S[3][xLo & 0x0ff]) ^ this.P[++Round]; - } - - xLo ^= this.P[16 + 1]; - - x[0] = xLo; - x[1] = xHi; - }, - - encipher_array: function(x){ - var count, xHi, xLo, Round, temp; - - for (i = 0; (i < x.length) || (x.length % 6); i += 2) { - xHi = x[i]; - xLo = x[i + 1]; - - xHi ^= this.previous_xHi; - xLo ^= this.previous_xLo; - - xHi ^= this.P[0]; - - Round = 0; - - while (Round < 16) { - xLo ^= (((this.S[0][xHi >>> 24] + this.S[1][(xHi >>> 16) & 0x0ff]) - ^ this.S[2][(xHi >>> 8) & 0x0ff]) + this.S[3][xHi & 0x0ff]) ^ this.P[++Round]; - xHi ^= (((this.S[0][xLo >>> 24] + this.S[1][(xLo >>> 16) & 0x0ff]) - ^ this.S[2][(xLo >>> 8) & 0x0ff]) + this.S[3][xLo & 0x0ff]) ^ this.P[++Round]; - } - - xLo ^= this.P[17]; - - this.previous_xHi = xLo; - this.previous_xLo = xHi; - - x[i + 1] = xHi; - x[i] = xLo; - } - }, - - decipher: function(x){ - var xHi, xLo, Round, temp; - - for (i = 0; i < x.length; i += 2) { - xHi = x[i]; - xLo = x[i + 1]; - - xHi ^= this.P[17]; - - Round = 16; - - while (Round > 0) { - xLo ^= (((this.S[0][xHi >>> 24] + this.S[1][(xHi >>> 16) & 0xff]) - ^ this.S[2][(xHi >>> 8) & 0xff]) + this.S[3][xHi & 0xff]) ^ this.P[Round--]; - xHi ^= (((this.S[0][xLo >>> 24] + this.S[1][(xLo >>> 16) & 0xff]) - ^ this.S[2][(xLo >>> 8) & 0xff]) + this.S[3][xLo & 0xff]) ^ this.P[Round--]; - } - - xLo ^= this.P[0]; - - temp = x[i]; - x[i] = xLo ^ this.previous_xHi; - this.previous_xHi = temp; - - temp = x[i + 1]; - x[i + 1] = xHi ^ this.previous_xLo; - this.previous_xLo = temp; - } - }, - - initialise: function(key, IV){ - var i, j, k, data; - var block = new Array(2); - - this.previous_xHi = IV[0]; - this.previous_xLo = IV[1]; - - this.setConstants(); - - for (j = 0, i = 0; i < 16 + 2; ++i) { - this.P[i] = this.P[i] ^ key[j]; - j = (j + 1) % 14; - } - - for (i = 0; i < 16 + 2; i += 2) { - this.encipher(block); - - this.P[i] = block[0]; - this.P[i + 1] = block[1]; - } - - for (i = 0; i < 4; ++i) { - for (j = 0; j < 256; j += 2) { - this.encipher(block); - this.S[i][j] = block[0]; - this.S[i][j + 1] = block[1]; - } - } - }, - - passtokey: function(pass, HiIV, LoIV){ - var binarypassword = stringtoints(pass); - var block = new Array(2); - var key = new Array(16); - var i = 0, j; - - block[0] = HiIV; - block[1] = LoIV; - - do { - this.initialise(key, block, 16); - - for (j = 0; j < 16;) { - block[0] ^= binarypassword[i]; - - this.encipher(block); - - key[j++] ^= block[0]; - key[j++] ^= block[1]; - } - } while (++i < binarypassword.length) - - return key; - } -}; - -})(this); - - - -/*FILEHEAD(/var/lib/jpf/src/core/crypto/md4.js)SIZE(-1077090856)TIME(1224578765)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-jpf.crypto.MD4 = {
- /*
- * Configurable variables. You may need to tweak these to be compatible with
- * the server-side, but the defaults work in most cases.
- */
- hexcase: 0, /* hex output format. 0 - lowercase; 1 - uppercase */
- b64pad : "", /* base-64 pad character. "=" for strict RFC compliance */
- chrsz : 8, /* bits per input character. 8 - ASCII; 16 - Unicode */
-
- /*
- * These are the functions you'll usually want to call
- */
- hex_md4: function(s){
- return this.binl2hex(this.core_md4(this.str2binl(s), s.length * this.chrsz));
- },
-
- b64_md4: function(s){
- return this.binl2b64(this.core_md4(this.str2binl(s), s.length * this.chrsz));
- },
-
- str_md4: function(s){
- return this.binl2str(this.core_md4(this.str2binl(s), s.length * this.chrsz));
- },
-
- hex_hmac_md4: function(key, data){
- return this.binl2hex(this.core_hmac_md4(key, data));
- },
-
- b64_hmac_md4: function(key, data){
- return this.binl2b64(this.core_hmac_md4(key, data));
- },
-
- str_hmac_md4: function(key, data){
- return this.binl2str(this.core_hmac_md4(key, data));
- },
-
- /**
- * Perform a simple self-test to see if the VM is working
- */
- md4_vm_test: function(){
- return this.hex_md4("abc") == "a448017aaf21d8525fc10ae87aa6729d";
- },
-
- /**
- * Calculate the MD4 of an array of little-endian words, and a bit length
- */
- core_md4: function(x, len){
- /* append padding */
- x[len >> 5] |= 0x80 << (len % 32);
- x[(((len + 64) >>> 9) << 4) + 14] = len;
-
- var a = 1732584193;
- var b = -271733879;
- var c = -1732584194;
- var d = 271733878;
-
- for (var i = 0; i < x.length; i += 16) {
- var olda = a;
- var oldb = b;
- var oldc = c;
- var oldd = d;
-
- a = this.md4_ff(a, b, c, d, x[i + 0], 3);
- d = this.md4_ff(d, a, b, c, x[i + 1], 7);
- c = this.md4_ff(c, d, a, b, x[i + 2], 11);
- b = this.md4_ff(b, c, d, a, x[i + 3], 19);
- a = this.md4_ff(a, b, c, d, x[i + 4], 3);
- d = this.md4_ff(d, a, b, c, x[i + 5], 7);
- c = this.md4_ff(c, d, a, b, x[i + 6], 11);
- b = this.md4_ff(b, c, d, a, x[i + 7], 19);
- a = this.md4_ff(a, b, c, d, x[i + 8], 3);
- d = this.md4_ff(d, a, b, c, x[i + 9], 7);
- c = this.md4_ff(c, d, a, b, x[i + 10], 11);
- b = this.md4_ff(b, c, d, a, x[i + 11], 19);
- a = this.md4_ff(a, b, c, d, x[i + 12], 3);
- d = this.md4_ff(d, a, b, c, x[i + 13], 7);
- c = this.md4_ff(c, d, a, b, x[i + 14], 11);
- b = this.md4_ff(b, c, d, a, x[i + 15], 19);
-
- a = this.md4_gg(a, b, c, d, x[i + 0], 3);
- d = this.md4_gg(d, a, b, c, x[i + 4], 5);
- c = this.md4_gg(c, d, a, b, x[i + 8], 9);
- b = this.md4_gg(b, c, d, a, x[i + 12], 13);
- a = this.md4_gg(a, b, c, d, x[i + 1], 3);
- d = this.md4_gg(d, a, b, c, x[i + 5], 5);
- c = this.md4_gg(c, d, a, b, x[i + 9], 9);
- b = this.md4_gg(b, c, d, a, x[i + 13], 13);
- a = this.md4_gg(a, b, c, d, x[i + 2], 3);
- d = this.md4_gg(d, a, b, c, x[i + 6], 5);
- c = this.md4_gg(c, d, a, b, x[i + 10], 9);
- b = this.md4_gg(b, c, d, a, x[i + 14], 13);
- a = this.md4_gg(a, b, c, d, x[i + 3], 3);
- d = this.md4_gg(d, a, b, c, x[i + 7], 5);
- c = this.md4_gg(c, d, a, b, x[i + 11], 9);
- b = this.md4_gg(b, c, d, a, x[i + 15], 13);
-
- a = this.md4_hh(a, b, c, d, x[i + 0], 3);
- d = this.md4_hh(d, a, b, c, x[i + 8], 9);
- c = this.md4_hh(c, d, a, b, x[i + 4], 11);
- b = this.md4_hh(b, c, d, a, x[i + 12], 15);
- a = this.md4_hh(a, b, c, d, x[i + 2], 3);
- d = this.md4_hh(d, a, b, c, x[i + 10], 9);
- c = this.md4_hh(c, d, a, b, x[i + 6], 11);
- b = this.md4_hh(b, c, d, a, x[i + 14], 15);
- a = this.md4_hh(a, b, c, d, x[i + 1], 3);
- d = this.md4_hh(d, a, b, c, x[i + 9], 9);
- c = this.md4_hh(c, d, a, b, x[i + 5], 11);
- b = this.md4_hh(b, c, d, a, x[i + 13], 15);
- a = this.md4_hh(a, b, c, d, x[i + 3], 3);
- d = this.md4_hh(d, a, b, c, x[i + 11], 9);
- c = this.md4_hh(c, d, a, b, x[i + 7], 11);
- b = this.md4_hh(b, c, d, a, x[i + 15], 15);
-
- a = this.safe_add(a, olda);
- b = this.safe_add(b, oldb);
- c = this.safe_add(c, oldc);
- d = this.safe_add(d, oldd);
-
- }
- return Array(a, b, c, d);
-
- },
-
- /*
- * These functions implement the basic operation for each round of the
- * algorithm.
- */
- md4_cmn: function(q, a, b, x, s, t){
- return this.safe_add(rol(this.safe_add(this.safe_add(a, q), this.safe_add(x, t)), s), b);
- },
-
- md4_ff: function(a, b, c, d, x, s){
- return this.md4_cmn((b & c) | ((~ b) & d), a, 0, x, s, 0);
- },
-
- md4_gg: function(a, b, c, d, x, s){
- return this.md4_cmn((b & c) | (b & d) | (c & d), a, 0, x, s, 1518500249);
- },
-
- md4_hh: function(a, b, c, d, x, s){
- return this.md4_cmn(b ^ c ^ d, a, 0, x, s, 1859775393);
- },
-
- /**
- * Calculate the HMAC-MD4, of a key and some data
- */
- core_hmac_md4: function(key, data){
- var bkey = this.str2binl(key);
- if (bkey.length > 16)
- bkey = this.core_md4(bkey, key.length * this.chrsz);
-
- var ipad = Array(16), opad = Array(16);
- for (var i = 0; i < 16; i++) {
- ipad[i] = bkey[i] ^ 0x36363636;
- opad[i] = bkey[i] ^ 0x5C5C5C5C;
- }
-
- var hash = this.core_md4(ipad.concat(this.str2binl(data)), 512 + data.length * this.chrsz);
- return this.core_md4(opad.concat(hash), 512 + 128);
- },
-
- /**
- * Add integers, wrapping at 2^32. This uses 16-bit operations internally
- * to work around bugs in some JS interpreters.
- */
- safe_add: function(x, y){
- var lsw = (x & 0xFFFF) + (y & 0xFFFF);
- var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
- return (msw << 16) | (lsw & 0xFFFF);
- },
-
- /**
- * Bitwise rotate a 32-bit number to the left.
- */
- rol: function(num, cnt){
- return (num << cnt) | (num >>> (32 - cnt));
- },
-
- /**
- * Convert a string to an array of little-endian words
- * If chrsz is ASCII, characters >255 have their hi-byte silently ignored.
- */
- str2binl: function(str){
- var bin = Array();
- var mask = (1 << this.chrsz) - 1;
- for (var i = 0; i < str.length * this.chrsz; i += this.chrsz)
- bin[i >> 5] |= (str.charCodeAt(i / this.chrsz) & mask) << (i % 32);
- return bin;
- },
-
- /**
- * Convert an array of little-endian words to a string
- */
- binl2str: function(bin){
- var str = "";
- var mask = (1 << this.chrsz) - 1;
- for (var i = 0; i < bin.length * 32; i += this.chrsz)
- str += String.fromCharCode((bin[i >> 5] >>> (i % 32)) & mask);
- return str;
- },
-
- /**
- * Convert an array of little-endian words to a hex string.
- */
- binl2hex: function(binarray){
- var hex_tab = this.hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
- var str = "";
- for (var i = 0; i < binarray.length * 4; i++) {
- str += hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8 + 4)) & 0xF) +
- hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8)) & 0xF);
- }
- return str;
- },
-
- /**
- * Convert an array of little-endian words to a base-64 string
- */
- binl2b64: function(binarray){
- var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
- var str = "";
- for (var i = 0; i < binarray.length * 4; i += 3) {
- var triplet = (((binarray[i >> 2] >> 8 * (i % 4)) & 0xFF) << 16) |
- (((binarray[i + 1 >> 2] >> 8 * ((i + 1) % 4)) & 0xFF) << 8) |
- ((binarray[i + 2 >> 2] >> 8 * ((i + 2) % 4)) & 0xFF);
- for (var j = 0; j < 4; j++) {
- if (i * 8 + j * 6 > binarray.length * 32)
- str += this.b64pad;
- else
- str += tab.charAt((triplet >> 6 * (3 - j)) & 0x3F);
- }
- }
- return str;
- }
-};
-
- - -/*FILEHEAD(/var/lib/jpf/src/core/crypto/md5.js)SIZE(-1077090856)TIME(1224578765)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-jpf.crypto.MD5 = {
- /*
- * Configurable variables. You may need to tweak these to be compatible with
- * the server-side, but the defaults work in most cases.
- */
- hexcase: 0, /* hex output format. 0 - lowercase; 1 - uppercase */
- b64pad : "", /* base-64 pad character. "=" for strict RFC compliance */
- chrsz : 8, /* bits per input character. 8 - ASCII; 16 - Unicode */
-
- /*
- * These are the functions you'll usually want to call
- * They take string arguments and return either hex or base-64 encoded strings
- */
- hex_md5: function(s) {
- return this.binl2hex(this.core_md5(this.str2binl(s), s.length * this.chrsz));
- },
- b64_md5: function(s) {
- return this.binl2b64(this.core_md5(this.str2binl(s), s.length * this.chrsz));
- },
- str_md5: function(s) {
- return this.binl2str(this.core_md5(this.str2binl(s), s.length * this.chrsz));
- },
- hex_hmac_md5: function(key, data) {
- return this.binl2hex(this.core_hmac_md5(key, data));
- },
- b64_hmac_md5: function(key, data) {
- return this.binl2b64(this.core_hmac_md5(key, data));
- },
- str_hmac_md5: function(key, data) {
- return this.binl2str(this.core_hmac_md5(key, data));
- },
- /**
- * Calculate the MD5 of an array of little-endian words, and a bit length
- */
- core_md5: function(x, len) {
- /* append padding */
- x[len >> 5] |= 0x80 << ((len) % 32);
- x[(((len + 64) >>> 9) << 4) + 14] = len;
-
- var a = 1732584193;
- var b = -271733879;
- var c = -1732584194;
- var d = 271733878;
-
- for(var i = 0; i < x.length; i += 16) {
- var olda = a;
- var oldb = b;
- var oldc = c;
- var oldd = d;
-
- a = this.md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
- d = this.md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
- c = this.md5_ff(c, d, a, b, x[i+ 2], 17, 606105819);
- b = this.md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
- a = this.md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
- d = this.md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426);
- c = this.md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
- b = this.md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
- a = this.md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416);
- d = this.md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
- c = this.md5_ff(c, d, a, b, x[i+10], 17, -42063);
- b = this.md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
- a = this.md5_ff(a, b, c, d, x[i+12], 7 , 1804603682);
- d = this.md5_ff(d, a, b, c, x[i+13], 12, -40341101);
- c = this.md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
- b = this.md5_ff(b, c, d, a, x[i+15], 22, 1236535329);
-
- a = this.md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
- d = this.md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
- c = this.md5_gg(c, d, a, b, x[i+11], 14, 643717713);
- b = this.md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
- a = this.md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
- d = this.md5_gg(d, a, b, c, x[i+10], 9 , 38016083);
- c = this.md5_gg(c, d, a, b, x[i+15], 14, -660478335);
- b = this.md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
- a = this.md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438);
- d = this.md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
- c = this.md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
- b = this.md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501);
- a = this.md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
- d = this.md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
- c = this.md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473);
- b = this.md5_gg(b, c, d, a, x[i+12], 20, -1926607734);
-
- a = this.md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
- d = this.md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
- c = this.md5_hh(c, d, a, b, x[i+11], 16, 1839030562);
- b = this.md5_hh(b, c, d, a, x[i+14], 23, -35309556);
- a = this.md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
- d = this.md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353);
- c = this.md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
- b = this.md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
- a = this.md5_hh(a, b, c, d, x[i+13], 4 , 681279174);
- d = this.md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
- c = this.md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
- b = this.md5_hh(b, c, d, a, x[i+ 6], 23, 76029189);
- a = this.md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
- d = this.md5_hh(d, a, b, c, x[i+12], 11, -421815835);
- c = this.md5_hh(c, d, a, b, x[i+15], 16, 530742520);
- b = this.md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);
-
- a = this.md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
- d = this.md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415);
- c = this.md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
- b = this.md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
- a = this.md5_ii(a, b, c, d, x[i+12], 6 , 1700485571);
- d = this.md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
- c = this.md5_ii(c, d, a, b, x[i+10], 15, -1051523);
- b = this.md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
- a = this.md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359);
- d = this.md5_ii(d, a, b, c, x[i+15], 10, -30611744);
- c = this.md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
- b = this.md5_ii(b, c, d, a, x[i+13], 21, 1309151649);
- a = this.md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
- d = this.md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
- c = this.md5_ii(c, d, a, b, x[i+ 2], 15, 718787259);
- b = this.md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);
-
- a = this.safe_add(a, olda);
- b = this.safe_add(b, oldb);
- c = this.safe_add(c, oldc);
- d = this.safe_add(d, oldd);
- }
- return Array(a, b, c, d);
- },
- /*
- * These functions implement the four basic operations the algorithm uses.
- */
- md5_cmn: function(q, a, b, x, s, t) {
- return this.safe_add(this.bit_rol(this.safe_add(this.safe_add(a, q), this.safe_add(x, t)), s),b);
- },
- md5_ff: function(a, b, c, d, x, s, t) {
- return this.md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
- },
- md5_gg: function(a, b, c, d, x, s, t) {
- return this.md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
- },
- md5_hh: function(a, b, c, d, x, s, t) {
- return this.md5_cmn(b ^ c ^ d, a, b, x, s, t);
- },
- md5_ii: function(a, b, c, d, x, s, t) {
- return this.md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
- },
- /**
- * Calculate the HMAC-MD5, of a key and some data
- */
- core_hmac_md5: function(key, data) {
- var bkey = this.str2binl(key);
- if(bkey.length > 16) bkey = this.core_md5(bkey, key.length * this.chrsz);
-
- var ipad = Array(16), opad = Array(16);
- for(var i = 0; i < 16; i++) {
- ipad[i] = bkey[i] ^ 0x36363636;
- opad[i] = bkey[i] ^ 0x5C5C5C5C;
- }
-
- var hash = this.core_md5(ipad.concat(this.str2binl(data)), 512 + data.length * this.chrsz);
- return this.core_md5(opad.concat(hash), 512 + 128);
- },
- /**
- * Add integers, wrapping at 2^32. This uses 16-bit operations internally
- * to work around bugs in some JS interpreters.
- */
- safe_add: function(x, y) {
- var lsw = (x & 0xFFFF) + (y & 0xFFFF);
- var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
- return (msw << 16) | (lsw & 0xFFFF);
- },
- /**
- * Bitwise rotate a 32-bit number to the left.
- */
- bit_rol: function(num, cnt) {
- return (num << cnt) | (num >>> (32 - cnt));
- },
- /**
- * Convert a string to an array of little-endian words
- * If chrsz is ASCII, characters >255 have their hi-byte silently ignored.
- */
- str2binl: function(str) {
- var bin = Array();
- var mask = (1 << this.chrsz) - 1;
- for(var i = 0; i < str.length * this.chrsz; i += this.chrsz)
- bin[i>>5] |= (str.charCodeAt(i / this.chrsz) & mask) << (i%32);
- return bin;
- },
- /**
- * Convert an array of little-endian words to a string
- */
- binl2str: function(bin) {
- var str = "";
- var mask = (1 << this.chrsz) - 1;
- for(var i = 0; i < bin.length * 32; i += this.chrsz)
- str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask);
- return str;
- },
- /**
- * Convert an array of little-endian words to a hex string.
- */
- binl2hex: function(binarray) {
- var hex_tab = this.hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
- var str = "";
- for(var i = 0; i < binarray.length * 4; i++) {
- str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) +
- hex_tab.charAt((binarray[i>>2] >> ((i%4)*8 )) & 0xF);
- }
- return str;
- },
- /**
- * Convert an array of little-endian words to a base-64 string
- */
- binl2b64: function(binarray) {
- var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
- var str = "";
- for(var i = 0; i < binarray.length * 4; i += 3) {
- var triplet = (((binarray[i >> 2] >> 8 * ( i %4)) & 0xFF) << 16)
- | (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 )
- | ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF);
- for(var j = 0; j < 4; j++) {
- if(i * 8 + j * 6 > binarray.length * 32) str += this.b64pad;
- else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
- }
- }
- return str;
- }
-};
-
- - -/*FILEHEAD(/var/lib/jpf/src/core/crypto/sha1.js)SIZE(-1077090856)TIME(1224578765)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-jpf.crypto.SHA1 = {
- /*
- * Configurable variables. You may need to tweak these to be compatible with
- * the server-side, but the defaults work in most cases.
- */
- hexcase: 0, /* hex output format. 0 - lowercase; 1 - uppercase */
- b64pad : "", /* base-64 pad character. "=" for strict RFC compliance */
- chrsz : 8, /* bits per input character. 8 - ASCII; 16 - Unicode */
-
- /*
- * These are the functions you'll usually want to call
- * They take string arguments and return either hex or base-64 encoded strings
- */
- hex_sha1: function(s){
- return this.binb2hex(this.core_sha1(this.str2binb(s), s.length * this.chrsz));
- },
-
- b64_sha1: function(s){
- return this.binb2b64(this.core_sha1(this.str2binb(s), s.length * this.chrsz));
- },
-
- str_sha1: function(s){
- return this.binb2str(this.core_sha1(this.str2binb(s), s.length * this.chrsz));
- },
-
- hex_hmac_sha1: function(key, data){
- return this.binb2hex(this.core_hmac_sha1(key, data));
- },
-
- b64_hmac_sha1: function(key, data){
- return this.binb2b64(this.core_hmac_sha1(key, data));
- },
-
- str_hmac_sha1: function(key, data){
- return this.binb2str(this.core_hmac_sha1(key, data));
- },
-
- /**
- * Perform a simple self-test to see if the VM is working
- */
- sha1_vm_test: function(){
- return this.hex_sha1("abc") == "a9993e364706816aba3e25717850c26c9cd0d89d";
- },
-
- /**
- * Calculate the SHA-1 of an array of big-endian words, and a bit length
- */
- core_sha1: function(x, len){
- /* append padding */
- x[len >> 5] |= 0x80 << (24 - len % 32);
- x[((len + 64 >> 9) << 4) + 15] = len;
-
- var w = Array(80);
- var a = 1732584193;
- var b = -271733879;
- var c = -1732584194;
- var d = 271733878;
- var e = -1009589776;
-
- for (var i = 0; i < x.length; i += 16) {
- var olda = a;
- var oldb = b;
- var oldc = c;
- var oldd = d;
- var olde = e;
-
- for (var j = 0; j < 80; j++) {
- if (j < 16)
- w[j] = x[i + j];
- else
- w[j] = this.rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1);
- var t = this.safe_add(this.safe_add(rol(a, 5), this.sha1_ft(j, b, c, d)),
- this.safe_add(this.safe_add(e, w[j]), this.sha1_kt(j)));
- e = d;
- d = c;
- c = this.rol(b, 30);
- b = a;
- a = t;
- }
-
- a = this.safe_add(a, olda);
- b = this.safe_add(b, oldb);
- c = this.safe_add(c, oldc);
- d = this.safe_add(d, oldd);
- e = this.safe_add(e, olde);
- }
- return Array(a, b, c, d, e);
-
- },
-
- /**
- * Perform the appropriate triplet combination for the current
- * iteration
- */
- sha1_ft: function(t, b, c, d){
- if (t < 20)
- return (b & c) | ((~ b) & d);
- if (t < 40)
- return b ^ c ^ d;
- if (t < 60)
- return (b & c) | (b & d) | (c & d);
- return b ^ c ^ d;
- },
-
- /**
- * Determine the appropriate additive constant for the current iteration
- */
- sha1_kt: function(t){
- return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 : (t < 60) ? -1894007588 : -899497514;
- },
-
- /**
- * Calculate the HMAC-SHA1 of a key and some data
- */
- core_hmac_sha1: function(key, data){
- var bkey = this.str2binb(key);
- if (bkey.length > 16)
- bkey = this.core_sha1(bkey, key.length * this.chrsz);
-
- var ipad = Array(16), opad = Array(16);
- for (var i = 0; i < 16; i++) {
- ipad[i] = bkey[i] ^ 0x36363636;
- opad[i] = bkey[i] ^ 0x5C5C5C5C;
- }
-
- var hash = this.core_sha1(ipad.concat(str2binb(data)), 512 + data.length * this.chrsz);
- return this.core_sha1(opad.concat(hash), 512 + 160);
- },
-
- /**
- * Add integers, wrapping at 2^32. This uses 16-bit operations internally
- * to work around bugs in some JS interpreters.
- */
- safe_add: function(x, y){
- var lsw = (x & 0xFFFF) + (y & 0xFFFF);
- var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
- return (msw << 16) | (lsw & 0xFFFF);
- },
-
- /**
- * Bitwise rotate a 32-bit number to the left.
- */
- rol: function(num, cnt){
- return (num << cnt) | (num >>> (32 - cnt));
- },
-
- /**
- * Convert an 8-bit or 16-bit string to an array of big-endian words
- * In 8-bit function, characters >255 have their hi-byte silently ignored.
- */
- str2binb: function(str){
- var bin = Array();
- var mask = (1 << this.chrsz) - 1;
- for (var i = 0; i < str.length * this.chrsz; i += this.chrsz)
- bin[i >> 5] |= (str.charCodeAt(i / this.chrsz) & mask) << (32 - this.chrsz - i % 32);
- return bin;
- },
-
- /**
- * Convert an array of big-endian words to a string
- */
- binb2str: function(bin){
- var str = "";
- var mask = (1 << this.chrsz) - 1;
- for (var i = 0; i < bin.length * 32; i += this.chrsz)
- str += String.fromCharCode((bin[i >> 5] >>> (32 - this.chrsz - i % 32)) & mask);
- return str;
- },
-
- /**
- * Convert an array of big-endian words to a hex string.
- */
- binb2hex: function(binarray){
- var hex_tab = this.hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
- var str = "";
- for (var i = 0; i < binarray.length * 4; i++) {
- str += hex_tab.charAt((binarray[i >> 2] >> ((3 - i % 4) * 8 + 4)) & 0xF) +
- hex_tab.charAt((binarray[i >> 2] >> ((3 - i % 4) * 8)) & 0xF);
- }
- return str;
- },
-
- /**
- * Convert an array of big-endian words to a base-64 string
- */
- binb2b64: function(binarray){
- var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
- var str = "";
- for (var i = 0; i < binarray.length * 4; i += 3) {
- var triplet = (((binarray[i >> 2] >> 8 * (3 - i % 4)) & 0xFF) << 16) |
- (((binarray[i + 1 >> 2] >> 8 * (3 - (i + 1) % 4)) & 0xFF) << 8) |
- ((binarray[i + 2 >> 2] >> 8 * (3 - (i + 2) % 4)) & 0xFF);
- for (var j = 0; j < 4; j++) {
- if (i * 8 + j * 6 > binarray.length * 32)
- str += this.b64pad;
- else
- str += tab.charAt((triplet >> 6 * (3 - j)) & 0x3F);
- }
- }
- return str;
- }
-};
-
- - -/*FILEHEAD(/var/lib/jpf/src/core/node/interactive.js)SIZE(-1077090856)TIME(1238944816)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-var __INTERACTIVE__ = 1 << 21;
-
-
-/**
- * Baseclass giving interactive features to this element, it makes an
- * element draggable and resizable.
- * Example:
- * <code>
- * <j:textarea draggable="true" resizable="true" />
- * </code>
- *
- * @attribute {Boolean} draggable makes an element draggable. The user will
- * able to move the element around while holding the mouse button down on the
- * element.
- * Example:
- * <code>
- * <j:bar draggable="true" />
- * </code>
- * @attribute {Boolean} resizable makes an element resizable. The user will able
- * to resize the element by grabbing one of the four edges of the element and
- * pulling it in either direction. Grabbing the corners allow the users the
- * resize horizontally and vertically at the same time. The right bottom corner
- * is special because it offers an especially big grab area. The size of this
- * area can be configured in the skin of the element.
- * Example:
- * <code>
- * <j:window resizable="true" />
- * </code>
- * @attribute {Number} minwidth the minimum horizontal size the element can get when resizing.
- * @attribute {Number} minheight the minimum vertical size the element can get when resizing.
- * @attribute {Number} maxwidth the maximum horizontal size the element can get when resizing.
- * @attribute {Number} maxheight the maximum vertical size the element can get when resizing.
- *
- * @event drag Fires when the widget has been dragged.
- * @event resizestart Fires before the widget is resized.
- * cancellable: Prevents this resize action to start.
- * object:
- * {String} type the type of resize. This is a combination of the four directions, n, s, e, w.
- * @event resize Fires when the widget has been resized.
- *
- * @constructor
- *
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 1.0
- *
- * @see element.appsettings.attribute.outline
- * @see element.appsettings.attribute.resize-outline
- * @see element.appsettings.attribute.drag-outline
- */
-jpf.Interactive = function(){
- var nX, nY, rX, rY, startPos, lastCursor = null, l, t, lMax, tMax,
- w, h, we, no, ea, so, rszborder, rszcorner, marginBox,
- verdiff, hordiff, _self = this, posAbs, oX, oY, overThreshold,
- dragOutline, resizeOutline;
-
- this.$regbase = this.$regbase | __INTERACTIVE__;
-
- this.$propHandlers["draggable"] = function(value){
- if (jpf.isFalse(value))
- this.draggable = value = false;
- else if (jpf.isTrue(value))
- this.draggable = value = true;
-
- var o = this.oDrag || this.oExt;
- if (o.interactive & 1)
- return;
-
- var mdown = o.onmousedown;
- o.onmousedown = function(){
- if (mdown && mdown.apply(this, arguments) === false)
- return;
-
- dragStart.apply(this, arguments);
- }
- o.interactive = (o.interactive||0)+1;
-
- //this.oExt.style.position = "absolute";
- };
-
- this.$propHandlers["resizable"] = function(value){
- if (jpf.isFalse(value))
- this.resizable = value = false;
- else if (jpf.isTrue(value))
- this.resizable = value = true;
-
- var o = this.oResize || this.oExt;
- if (o.interactive & 2)
- return;
-
- var mdown = o.onmousedown;
- var mmove = o.onmousemove;
-
- o.onmousedown = function(){
- if (mdown && mdown.apply(this, arguments) === false)
- return;
-
- resizeStart.apply(this, arguments);
- };
-
- o.onmousemove = function(){
- if (mmove && mmove.apply(this, arguments) === false)
- return;
-
- resizeIndicate.apply(this, arguments);
- };
-
- o.interactive = (o.interactive||0)+2;
-
- //this.oExt.style.position = "absolute";
-
- rszborder = this.$getOption && parseInt(this.$getOption("Main", "resize-border")) || 3;
- rszcorner = this.$getOption && parseInt(this.$getOption("Main", "resize-corner")) || 12;
- marginBox = jpf.getBox(jpf.getStyle(this.oExt, jpf.isIE ? "borderWidth" : "border-width"));
- };
-
- /*
- this.$propHandlers["minwidth"] =
- this.$propHandlers["maxwidth"] =
- this.$propHandlers["minheight"] =
- this.$propHandlers["maxheight"] = function(value, force, prop){
- if (this.aData)
- this.aData[prop] = parseInt(value);
- }
- if (this.aData) {
- this.aData.minwidth = this.minwidth;
- this.aData.minheight = this.minheight;
- }*/
-
- function dragStart(e){
- if (!e) e = event;
-
- if (!_self.draggable || jpf.dragmode.isDragging)
- return;
-
- dragOutline = !(_self.dragOutline == false || !jpf.appsettings.dragOutline);
-
- jpf.dragmode.isDragging = true;
- overThreshold = false;
-
- jpf.popup.forceHide();
-
- posAbs = "absolute|fixed".indexOf(jpf.getStyle(_self.oExt, "position")) > -1;
- if (!posAbs)
- _self.oExt.style.position = "relative";
-
- //@todo not for docking
- if (posAbs && !_self.aData) {
- jpf.plane.show(dragOutline
- ? oOutline
- : _self.oExt);//, true
- }
-
- var pos = posAbs
- ? jpf.getAbsolutePosition(_self.oExt, _self.oExt.offsetParent)
- : [parseInt(_self.oExt.style.left) || _self.oExt.offsetLeft || 0,
- parseInt(_self.oExt.style.top) || _self.oExt.offsetTop || 0];
-
- nX = pos[0] - (oX = e.clientX);
- nY = pos[1] - (oY = e.clientY);
-
- if (_self.hasFeature && _self.hasFeature(__ANCHORING__))
- _self.disableAnchoring();
-
- if (posAbs && dragOutline) {
- oOutline.className = "drag";
-
- var diffOutline = jpf.getDiff(oOutline);
- _self.oExt.parentNode.appendChild(oOutline);
- oOutline.style.left = pos[0] + "px";
- oOutline.style.top = pos[1] + "px";
- oOutline.style.width = (_self.oExt.offsetWidth - diffOutline[0]) + "px";
- oOutline.style.height = (_self.oExt.offsetHeight - diffOutline[1]) + "px";
- }
-
- jpf.dragmode.mode = true;
-
- document.onmousemove = dragMove;
- document.onmouseup = function(){
- document.onmousemove = document.onmouseup = null;
-
- jpf.dragmode.mode = false;
-
- if (posAbs && !_self.aData)
- jpf.plane.hide();
-
- if (overThreshold) {
- if (_self.setProperty) {
- if(l) _self.setProperty("left", l);
- if(t) _self.setProperty("top", t);
- }
- else if (dragOutline) {
- _self.oExt.style.left = l + "px";
- _self.oExt.style.top = t + "px";
- }
- }
-
- if (!posAbs)
- _self.oExt.style.position = "relative";
-
- if (_self.showdragging)
- jpf.setStyleClass(_self.oExt, "", ["dragging"]);
-
- if (posAbs && dragOutline)
- oOutline.style.display = "none";
-
- jpf.dragmode.isDragging = false;
-
- if (_self.dispatchEvent)
- _self.dispatchEvent("drag");
- };
-
- if (jpf.isIE)
- document.onmousedown();
-
- return false;
- };
-
- function dragMove(e){
- if(!e) e = event;
-
- if (!overThreshold && _self.showdragging)
- jpf.setStyleClass(_self.oExt, "dragging");
-
- // usability rule: start dragging ONLY when mouse pointer has moved delta x pixels
- var dx = e.clientX - oX,
- dy = e.clientY - oY,
- distance;
-
- if (!overThreshold
- && (distance = dx*dx > dy*dy ? dx : dy) * distance < 2)
- return;
-
- //Drag outline support
- else if (!overThreshold && dragOutline
- && oOutline.style.display != "block")
- oOutline.style.display = "block";
-
- var oHtml = dragOutline
- ? oOutline
- : _self.oExt;
-
- oHtml.style.left = (l = e.clientX + nX) + "px";
- oHtml.style.top = (t = e.clientY + nY) + "px";
-
- overThreshold = true;
- };
-
- function resizeStart(e){
- if (!e) e = event;
-
- if (!_self.resizable)
- return;
-
- resizeOutline = !(_self.resizeOutline == false || !jpf.appsettings.resizeOutline);
-
- if (!resizeOutline) {
- var diff = jpf.getDiff(_self.oExt);
- hordiff = diff[0];
- verdiff = diff[1];
- }
-
- //@todo This is probably not gen purpose
- startPos = jpf.getAbsolutePosition(_self.oExt);//, _self.oExt.offsetParent);
- startPos.push(_self.oExt.offsetWidth);
- startPos.push(_self.oExt.offsetHeight);
-
- var sLeft = document.documentElement.scrollLeft;
- var sTop = document.documentElement.scrollTop;
- var x = (oX = e.clientX) - startPos[0] + sLeft;
- var y = (oY = e.clientY) - startPos[1] + sTop;
-
- var resizeType = getResizeType.call(_self.oExt, x, y);
- rX = x;
- rY = y;
-
- if (!resizeType)
- return;
-
- if (_self.dispatchEvent && _self.dispatchEvent("resizestart", {
- type : resizeType
- }) === false)
- return;
-
- jpf.popup.forceHide();
-
- if (_self.hasFeature && _self.hasFeature(__ANCHORING__))
- _self.disableAnchoring();
-
- jpf.dragmode.isDragging = true;
- overThreshold = false;
-
- var r = "|" + resizeType + "|"
- we = "|w|nw|sw|".indexOf(r) > -1;
- no = "|n|ne|nw|".indexOf(r) > -1;
- ea = "|e|se|ne|".indexOf(r) > -1;
- so = "|s|se|sw|".indexOf(r) > -1;
-
- if (!_self.minwidth) _self.minwidth = 0;
- if (!_self.minheight) _self.minheight = 0;
- if (!_self.maxwidth) _self.maxwidth = 10000;
- if (!_self.maxheight) _self.maxheight = 10000;
-
- if (posAbs) {
- lMax = startPos[0] + startPos[2] - _self.minwidth;
- tMax = startPos[1] + startPos[3] - _self.minheight;
- lMin = startPos[0] + startPos[2] - _self.maxwidth;
- tMin = startPos[1] + startPos[3] - _self.maxheight;
- }
-
- if (posAbs) {
- jpf.plane.show(resizeOutline
- ? oOutline
- : _self.oExt);//, true
- }
-
- if (resizeOutline) {
- oOutline.className = "resize";
- var diffOutline = jpf.getDiff(oOutline);
- hordiff = diffOutline[0];
- verdiff = diffOutline[1];
-
- //_self.oExt.parentNode.appendChild(oOutline);
- oOutline.style.left = startPos[0] + "px";
- oOutline.style.top = startPos[1] + "px";
- oOutline.style.width = (_self.oExt.offsetWidth - hordiff) + "px";
- oOutline.style.height = (_self.oExt.offsetHeight - verdiff) + "px";
- oOutline.style.display = "block";
- }
-
- if (lastCursor === null)
- lastCursor = document.body.style.cursor;//jpf.getStyle(document.body, "cursor");
- document.body.style.cursor = resizeType + "-resize";
-
- jpf.dragmode.mode = true;
-
- document.onmousemove = resizeMove;
- document.onmouseup = function(e){
- document.onmousemove = document.onmouseup = null;
-
- jpf.dragmode.mode = false;
-
- if (posAbs)
- jpf.plane.hide();
-
- if (resizeOutline) {
- var diff = jpf.getDiff(_self.oExt);
- hordiff = diff[0];
- verdiff = diff[1];
- }
-
- doResize(e || event, true);
-
- if (_self.setProperty) {
- if (posAbs) {
- if (l) _self.setProperty("left", l);
- if (t) _self.setProperty("top", t);
- }
-
- if (w) _self.setProperty("width", w + hordiff)
- if (h) _self.setProperty("height", h + verdiff);
- }
-
- l = t = w = h = null;
-
- document.body.style.cursor = lastCursor;
- lastCursor = null;
-
- if (resizeOutline)
- oOutline.style.display = "none";
-
- jpf.dragmode.isDragging = false;
-
- if (_self.dispatchEvent)
- _self.dispatchEvent("resize");
- };
-
- if (jpf.isIE)
- document.onmousedown();
-
- return false;
- };
-
- var min = Math.min, max = Math.max, lastTime;
- function resizeMove(e){
- if(!e) e = event;
-
- //if (!e.button)
- //return this.onmouseup();
-
- // usability rule: start dragging ONLY when mouse pointer has moved delta x pixels
- /*var dx = e.clientX - oX,
- dy = e.clientY - oY,
- distance;
-
- if (!overThreshold
- && (distance = dx*dx > dy*dy ? dx : dy) * distance < 4)
- return;*/
-
- if (lastTime && new Date().getTime()
- - lastTime < (resizeOutline ? 6 : jpf.mouseEventBuffer))
- return;
- lastTime = new Date().getTime();
-
- doResize(e);
-
- //overThreshold = true;
- };
-
- function doResize(e, force){
- var oHtml = resizeOutline && !force
- ? oOutline
- : _self.oExt;
-
- var sLeft = document.documentElement.scrollLeft;
- var sTop = document.documentElement.scrollTop;
-
- if (we) {
- oHtml.style.left = (l = max(lMin, min(lMax, e.clientX - rX + sLeft))) + "px";
- oHtml.style.width = (w = min(_self.maxwidth - hordiff,
- max(hordiff, _self.minwidth,
- startPos[2] - (e.clientX - startPos[0]) + rX + sLeft
- ) - hordiff) + sLeft) + "px"; //@todo
- }
-
- if (no) {
- oHtml.style.top = (t = max(tMin, min(tMax, e.clientY - rY + sTop))) + "px";
- oHtml.style.height = (h = min(_self.maxheight - verdiff,
- max(verdiff, _self.minheight,
- startPos[3] - (e.clientY - startPos[1]) + rY + sTop
- ) - verdiff)) + "px"; //@todo
- }
-
- if (ea)
- oHtml.style.width = (w = min(_self.maxwidth - hordiff,
- max(hordiff, _self.minwidth,
- e.clientX - startPos[0] + (startPos[2] - rX) + sLeft)
- - hordiff)) + "px";
-
- if (so)
- oHtml.style.height = (h = min(_self.maxheight - verdiff,
- max(verdiff, _self.minheight,
- e.clientY - startPos[1] + (startPos[3] - rY) + sTop)
- - verdiff)) + "px";
-
- if (jpf.hasSingleRszEvent)
- jpf.layout.forceResize(_self.oInt);
- }
-
- function getResizeType(x, y){
- var cursor = "",
- tcursor = "";
- posAbs = "absolute|fixed".indexOf(jpf.getStyle(_self.oExt, "position")) > -1;
-
- if (_self.resizable == true || _self.resizable == "vertical") {
- if (y < rszborder + marginBox[0])
- cursor = posAbs ? "n" : "";
- else if (y > this.offsetHeight - rszborder) //marginBox[0] - marginBox[2] -
- cursor = "s";
- else if (y > this.offsetHeight - rszcorner) //marginBox[0] - marginBox[2] -
- tcursor = "s";
- }
-
- if (_self.resizable == true || _self.resizable == "horizontal") {
- if (x < (cursor ? rszcorner : rszborder) + marginBox[0])
- cursor += tcursor + (posAbs ? "w" : "");
- else if (x > this.offsetWidth - (cursor || tcursor ? rszcorner : rszborder)) //marginBox[1] - marginBox[3] -
- cursor += tcursor + "e";
- }
-
- return cursor;
- }
-
- var originalCursor;
- function resizeIndicate(e){
- if(!e) e = event;
-
- if (!_self.resizable || document.onmousemove)
- return;
-
- //@todo This is probably not gen purpose
- var pos = jpf.getAbsolutePosition(_self.oExt);//, _self.oExt.offsetParent
- var sLeft = document.documentElement.scrollLeft;
- var sTop = document.documentElement.scrollTop;
- var x = e.clientX - pos[0] + sLeft;
- var y = e.clientY - pos[1] + sTop;
-
- if (!originalCursor)
- originalCursor = jpf.getStyle(this, "cursor");
-
- var cursor = getResizeType.call(_self.oExt, x, y);
- this.style.cursor = cursor
- ? cursor + "-resize"
- : originalCursor || "default";
- };
-
- if (!this.pHtmlDoc)
- this.pHtmlDoc = window.document;
-
- var oOutline = this.pHtmlDoc.getElementById("jpf_outline");
- if (!oOutline) {
- oOutline = this.pHtmlDoc.body.appendChild(this.pHtmlDoc.createElement("div"));
-
- oOutline.refCount = 0;
- oOutline.setAttribute("id", "jpf_outline");
-
- oOutline.style.position = "absolute";
- oOutline.style.display = "none";
- oOutline.style.zIndex = 100000000;
- }
- oOutline.refCount++;
-
- /*this.$jmlDestroyers.push(function(){
- oOutline.refCount--;
-
- if (!oOutline.refCount) {
- //destroy
- }
- });*/
-};
-
- - -/*FILEHEAD(/var/lib/jpf/src/core/node/media.js)SIZE(-1077090856)TIME(1238933673)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - -var __MEDIA__ = 1 << 20; - - -/** - * Interface that adds Media node features and dynamics to this Element. - * @see http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html#media7 - * - * @constructor - * @baseclass - * @author Mike de Boer - * @version %I%, %G% - * @since 1.0 - */ -jpf.Media = function(){ - this.$regbase = this.$regbase | __MEDIA__; - - this.muted = false; - - this.$booleanProperties["paused"] = true; - this.$booleanProperties["muted"] = true; - this.$booleanProperties["seeking"] = true; - this.$booleanProperties["autoplay"] = true; - this.$booleanProperties["controls"] = true; - this.$booleanProperties["ready"] = true; - - this.$supportedProperties.push("position", "networkState", "readyState", - "progress", "buffered", "bufferedBytes", "totalBytes", "currentTime", - "paused", "seeking", "volume", "type", "src", "autoplay", "controls"); - - this.mainBind = "src"; - - this.$propHandlers["readyState"] = function(value){ //in seconds - if (this.readyState !== value) - this.readyState = value; - if (value == jpf.Media.HAVE_NOTHING) { - jpf.console.error("Unable to open medium with URL '" + this.src - + "'. Please check if the URL you entered as src is pointing to \ - a valid resource."); - - var oError = this.MediaError("Unable to open medium with URL '" + this.src - + "'. Please check if the URL you entered as src is pointing to \ - a valid resource."); - if (this.dispatchEvent("havenothing", { - error : oError, - bubbles : true - }) === false) - throw oError; - } - else if (value == jpf.Media.HAVE_CURRENT_DATA) - this.dispatchEvent("havecurrentdata"); - else if (value == jpf.Media.HAVE_FUTURE_DATA) - this.dispatchEvent("havefuturedata"); - else if (value == jpf.Media.HAVE_ENOUGH_DATA) { - this.dispatchEvent("haveenoughdata"); - this.setProperty('ready', true); - } - }; - - this.$propHandlers["bufferedBytes"] = function(value) { - this.setProperty("progress", this.totalBytes - ? value.end / this.totalBytes - : 0); - }; - - this.$propHandlers["position"] = function(value){ - if (this.duration > 0 && this.seek) { - // first, check if the seek action doesn't go beyond the download progress of the media element. - if (value >= this.progress) - value = this.progress - 0.05; - - var isPlaying = !this.paused; - if (isPlaying) - this.pause(); - - if (value < 0) - value = 0; - else if (value > 1) - value = 1; - - this.seek(Math.round(value * this.duration)); - - this.setProperty('paused', !isPlaying); - } - }; - - this.$propHandlers["currentTime"] = function(value){ //in milliseconds - if (value >= 0 && this.seek) - this.seek(value); - }; - - this.$propHandlers["volume"] = function(value){ - if (!this.player) return; - if (value < 0) - throw this.MediaError("Attempt to set the volume to a negative volue '" + value); - - if (value < 1 && value > 0) - value = value * 100; - - if (this.setVolume) - this.setVolume(value); - if (value > 0 && this.muted) - this.setProperty("muted", false); - }; - - var oldVolume = null; - - this.$propHandlers["muted"] = function(value){ - if (!this.player || !this.setVolume) return; - - if (value) { //mute the player - oldVolume = this.volume; - this.setVolume(0); - } - else - this.setVolume(oldVolume || 20); - }; - - this.$propHandlers["paused"] = function(value){ - if (!this.player) return; - - this.paused = jpf.isTrue(value); - if (this.paused) - this.player.pause(); - else - this.player.play(); - }; - - var loadTimer = null; - - this.$propHandlers["type"] = function(value){ - if (loadTimer) return; - - var _self = this; - loadTimer = window.setTimeout(function() { - reload.call(_self); - }); - }; - - this.$propHandlers["src"] = function(value){ - if (loadTimer || !value) return; //@todo for mike: please check if this is the best behaviour for setting an empty value - - var oUrl = new jpf.url(value); - this.src = oUrl.uri; - - if (!oUrl.isSameLocation()) - jpf.console.warn("Media player: the medium with URL '" + this.src + "' \ - does not have the same origin as your web application. This can \ - cause the medium to not load and/ or play.", "media"); - if (oUrl.protocol == "file") - jpf.console.warn("Media player: the medium with URL '" + this.src + "' \ - will be loaded through the 'file://' protocol. This can \ - cause the medium to not load and/ or play.", "media"); - - if (this.src != this.currentSrc && this.networkState !== jpf.Media.LOADING) { - var type = this.$guessType(this.src); - if (type == this.type) { - reset.call(this); - this.loadMedia(); - } - else { - this.type = type; - var _self = this; - loadTimer = window.setTimeout(function() { - reload.call(_self); - }); - } - } - }; - - this.$propHandlers["ID3"] = function(value){ - if (!this.player) return; - // usually this feature is only made available BY media as getters - if (typeof this.player.setID3 == "function") - this.player.setID3(value); - }; - - /**** DOM Hooks ****/ - - this.$domHandlers["remove"].push(function(doOnlyAdmin){ - jpf.console.log('Media: removing node...'); - reset.call(this); - }); - - this.$domHandlers["reparent"].push(function(beforeNode, pNode, withinParent){ - if (!this.$jmlLoaded) - return; - - jpf.console.log('Media: reparenting - ' + beforeNode + ', ' + pNode); - - this.$draw(); - reload.call(this, true); - }); - - function reset() { - this.setProperty('networkState', jpf.Media.NETWORK_EMPTY); - //this.setProperty('readyState', jpf.Media.HAVE_NOTHING); - this.setProperty('ready', false); - //this.setProperty('buffered', {start: 0, end: 0, length: 0}); - //this.setProperty('bufferedBytes', {start: 0, end: 0, length: 0}); - this.buffered = {start: 0, end: 0, length: 0}; - this.bufferedBytes = {start: 0, end: 0, length: 0}; - this.totalBytes = 0; - this.setProperty('progress', 0); - //this.setProperty('totalBytes', 0); - - this.setProperty('seeking', false); - this.setProperty('paused', true); - this.setProperty('position', 0); - this.currentTime = this.duration = 0; - this.played = this.seekable = null; - this.ended = false; - - this.start = this.end = this.loopStart = this.loopEnd = - this.playCount = this.currentLoop = 0; - this.controls = this.muted = false; - } - - function reload(bNoReset) { - jpf.console.log('Media: reloading medium with mimetype ', this.type); - - window.clearTimeout(loadTimer); - loadTimer = null; - - if (!bNoReset) - reset.call(this); - - this.$destroy(true); //bRuntime = true - - this.playerType = this.$getPlayerType(this.type); - - // sanity checking - if (!this.playerType || !this.$isSupported()) { - this.oExt.innerHTML = this.notSupported; - return; - } - - this.$initPlayer(); - } - - // error state - this.MediaError = function(sMsg) { - return new Error(jpf.formatErrorString(0, this, "Media", sMsg)); - }; - - // network state - this.src = this.currentSrc = null; - this.networkState = jpf.Media.NETWORK_EMPTY; //default state - this.bufferingRate = 0; - this.bufferingThrottled = false; - this.buffered = {start: 0, end: 0, length: 0}; //TimeRanges container {start: Function(idx):Float, end: Function(idx):Float, length: n} - this.bufferedBytes = {start: 0, end: 0, length: 0}; //ByteRanges container {start: Function(idx):Number, end: Function(idx):Number, length: n} - this.totalBytes = 0; - this.volume = 100; - - this.loadMedia = function() { - //must be overridden by the component - }; - - // ready state - this.readyState = jpf.Media.HAVE_NOTHING; - this.seeking = false; - - // playback state - this.currentTime = this.duration = 0; - this.paused = true; - this.defaultPlaybackRate = this.playbackRate = 0; - this.played = null; // TimeRanges container - this.seekable = null; // TimeRanges container - this.ended = this.autoplay = false; - - /** - * @see http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html#dom-navigator-canplaytype - */ - this.canPlayType = function(sType) { - if (this.$getPlayerType) { - var sPlayer = this.$getPlayerType(sType); - if (!sPlayer || !this.$isSupported(sPlayer)) - return "no"; - if (sPlayer.indexOf("Wmp") != -1) - return "maybe"; - return "probably"; //we're sooo confident ;) - } - - return "no"; - }; - - this.play = function() { - this.setProperty('paused', false); - }; - - this.pause = function() { - this.setProperty('paused', true); - }; - - // looping - this.start = this.end = this.loopStart = this.loopEnd = - this.playCount = this.currentLoop = 0; - - // cue ranges - this.addCueRange = function(sClassName, sId, iStart, iEnd, bPauseOnExit, fEnterCallback, fExitCallback) { - //to be overridden by the component - }; - - this.removeCueRanges = function(sClassName) { - //to be overridden by the component - }; - - /** - * Return a counter as you commonly see in front panels of CD/ DVD players - * - * @link http://php.net/strftime - * @param {Number} iMillis Amount of milliseconds to transform in a counter - * @param {String} sFormat Format of the counter is the form of PHP's strftime function: - * %H - hour as a decimal number using a 24-hour clock (range 00 to 23) - * %M - minute as a decimal number - * %S - second as a decimal number - * %Q - Millisecond as decimal (000-999) - * %n - newline character - * %t - tab character - * %T - current time, equal to %H:%M:%S - * %% - a literal `%' character - * @param {Boolean} bReverse Show the counter in reverse notation (countdown) - * @type {String} - */ - this.getCounter = function(iMillis, sFormat, bReverse) { - // for String.pad, 'jpf.PAD_LEFT' is implicit - if (bReverse) - iMillis = iMillis - this.duration; - var iSeconds = Math.round(Math.abs(iMillis / 1000)), - sHours = String(Math.round(Math.abs(iSeconds / 60 / 60))).pad(2, "0"), - sMinutes = String(Math.round(Math.abs(iSeconds / 60))).pad(2, "0"), - sSeconds = String(iSeconds).pad(2, "0"), - sMillis = String(Math.round(Math.abs(iMillis % 1000))).pad(3, "0"); - return (bReverse ? "- " : "") + sFormat.replace(/\%T/g, "%H:%M:%S") - .replace(/\%[a-zA-Z\%]/g, function(sMatch) { - switch (sMatch) { - case "%H": - return sHours; - case "%M": - return sMinutes; - case "%S": - return sSeconds; - case "%Q": - return sMillis; - case "%n": - return "\n"; - case "%t": - return "\t"; - case "%%": - return "%"; - } - }); - }; - - /** - * Set the source for a media element by going through all the <source> - * child elements of the <audio> or <video> node, searching for - * a valid source media file that is playable by one of our plugins. - * The 'src' and 'type' attributes respectively have precedence over any - * <source> element. - * It also parses the <nomedia> tag that specifies what text or HTML to - * display when a medium is not supported and/ or playable. - * - * @param {XmlDomElement} [jml] Parent Jml node of the player - * @return {Boolean} Tells the client that no supported/ playable source file was found - */ - this.setSource = function(jml) { - jml = jml || this.$jml; - // first get the 'Not supported' placeholder... - var aNodes = $xmlns(jml, "nomedia", jpf.ns.jml); - if (!aNodes.length) { - this.notSupported = (jml.firstChild && jml.firstChild.nodeType == 3) - ? jml.firstChild.nodeValue - : "Unable to playback, medium not supported."; - } - else - this.notSupported = aNodes[0].innerHTML; - - if (!this.src) { // no direct src-attribute set - var src, type, oSources = $xmlns(jml, "source", jpf.ns.jml); - // iterate through all the <source> tags from left to right - for (var i = 0, j = oSources.length; i < j; i++) { - src = oSources[i].getAttribute("src"); - if (!src) continue; - type = oSources[i].getAttribute("type"); - if (!type) // auto-detect type, based on file extension - type = this.$guessType(src); - if (this.canPlayType(type) != "no") { - // yay! we found a type that we can play for the client - this.src = src; - this.type = type; - break; //escape! - } - } - } - else if (!this.type) { - this.type = this.$guessType(this.src); - if (this.canPlayType(this.type) == "no") - return false; - } - - return (this.src && this.type); - }; -}; - -// network state (.networkState) -jpf.Media.NETWORK_EMPTY = 0; -jpf.Media.NETWORK_IDLE = 1; -jpf.Media.NETWORK_LOADING = 2; -jpf.Media.NETWORK_LOADED = 3; - -// ready state (.readyState) -jpf.Media.HAVE_NOTHING = 0; -jpf.Media.HAVE_METADATA = 1; -jpf.Media.HAVE_SOME_DATA = 2; //wtf?? -jpf.Media.HAVE_CURRENT_DATA = 3; -jpf.Media.HAVE_FUTURE_DATA = 4; -jpf.Media.HAVE_ENOUGH_DATA = 5; - - - -/*FILEHEAD(/var/lib/jpf/src/core/node/delayedrender.js)SIZE(-1077090856)TIME(1238944816)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-var __DELAYEDRENDER__ = 1 << 11
-
-
-/**
- * Baseclass adding delayed rendering features to this element. Any element
- * that is (partially) hidden at startup has the possibility to delay rendering
- * it's childNodes by setting render="runtime" on the element. These elements
- * include window, tab, pages, form and container.
- * For instance a Tab page in a container is initally hidden and does not
- * need to be rendered. When the tab button is pressed to activate the page
- * the page is rendered and then displayed. This can dramatically decrease
- * the startup time of the application.
- * Example:
- * In this example the button isn't rendered until the advanced tab becomes active.
- * <code>
- * <j:tab>
- * <j:page caption="General">
- * ...
- * </j:page>
- * <j:page caption="Advanced" render="runtime">
- * <j:button>OK</j:button>
- * </j:page>
- * </j:tab>
- * </code>
- *
- * @event beforerender Fires before elements are rendered. Use this event to display a loader.
- * cancellable: Prevents rendering of the childNodes
- * @event afterrender Fires after elements are rendered. User this event to hide a loader.
- *
- * @attribute {String} render when the contents of this element is rendered.
- * Possible values:
- * init elements are rendered during init of the application.
- * runtime elements are rendered when the user requests them.
- * @attribute {Boolean} use-render-delay wether there's a short delay between showing this element and rendering it's contents.
- * Possible values:
- * true The elements are rendered immediately
- * false There is a delay between showing this element and the actual rendering, allowing the browsers' render engine to draw (for instance a loader).
- *
- * @constructor
- * @baseclass
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.8.9
- */
-jpf.DelayedRender = function(){
- this.$regbase = this.$regbase | __DELAYEDRENDER__;
- this.isRendered = false;
-
- var withheld = false;
-
- this.$checkDelay = function(x){
- if (x.getAttribute("render") == "runtime") {
- x.setAttribute("render-status", "withheld");
- if (!jpf.JmlParser.renderWithheld)
- jpf.JmlParser.renderWithheld = [];
- jpf.JmlParser.renderWithheld.push(this);
-
- withheld = true;
- return true;
- }
-
- this.isRendered = true;
- return false;
- };
-
- /**
- * Renders the children of this element.
- *
- * @param {Boolean} [usedelay] whether a delay is added between calling this function and the actual rendering. This allows the browsers' render engine to draw (for instance a loader).
- */
- this.$render = function(usedelay){
- if (this.isRendered || this.$jml.getAttribute("render-status") != "withheld")
- return;
- this.dispatchEvent("beforerender");
-
- if (jpf.isNull(this.usedelay))
- this.usedelay = jpf.xmldb.getInheritedAttribute(this.$jml,
- "use-render-delay") == "true";
-
- if (this.usedelay || usedelay)
- setTimeout("jpf.lookup(" + this.uniqueId + ").$renderparse()", 10);
- else
- this.$renderparse();
- };
-
- this.$renderparse = function(){
- if (this.isRendered)
- return;
-
- jpf.JmlParser.parseMoreJml(this.$jml, this.oInt, this)
-
- this.$jml.setAttribute("render-status", "done");
- this.$jml.removeAttribute("render"); //Experimental
- this.isRendered = true;
- withheld = false;
-
- this.dispatchEvent("afterrender");
- };
-};
-
- - -/*FILEHEAD(/var/lib/jpf/src/core/node/databinding.js)SIZE(-1077090856)TIME(1239018215)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-var __DATABINDING__ = 1 << 1;
-
-
-/**
- * Baseclass adding databinding features to this element. Databinding takes
- * care of automatically going from data to representation and establishing a
- * permanent link between the two. In this way data that is changed will
- * change the representation as well. Furthermore, actions that are executed on
- * the representation will change the underlying data.
- * Example:
- * <code>
- * <j:list>
- * <j:bindings>
- * <j:icon select="@icon" />
- * <j:caption select="text()" />
- * <j:traverse select="item" />
- * </j:bindings>
- * </j:list>
- * </code>
- *
- * @event error Fires when a communication error has occured while making a request for this element.
- * cancellable: Prevents the error from being thrown.
- * bubbles:
- * object:
- * {Error} error the error object that is thrown when the event callback doesn't return false.
- * {Number} state the state of the call
- * Possible values:
- * jpf.SUCCESS the request was successfull
- * jpf.TIMEOUT the request has timed out.
- * jpf.ERROR an error has occurred while making the request.
- * jpf.OFFLINE the request was made while the application was offline.
- * {mixed} userdata data that the caller wanted to be available in the callback of the http request.
- * {XMLHttpRequest} http the object that executed the actual http request.
- * {String} url the url that was requested.
- * {Http} tpModule the teleport module that is making the request.
- * {Number} id the id of the request.
- * {String} message the error message.
-
- *
- * @constructor
- * @baseclass
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.4
- */
-jpf.DataBinding = function(){
- var loadqueue;
- var cXmlOnLoad = [];
- var cXmlSelect = [];
- var cXmlChoice = [];
-
- this.$regbase = this.$regbase | __DATABINDING__;
- this.mainBind = "value";
- var _self = this;
-
- /**** Public Methods ****/
-
- /**
- * Gets the xpath statement from the main bind rule. Each databound
- * element which does not implement jpf.MultiSelect has a main bind rule.
- * This method gets the xpath statement in the select attribute of this rule.
- *
- * @return {String} the xpath statement
- * @see element.smartbinding
- */
- this.getMainBindXpath = function(){
- if (this.hasFeature(__MULTIBINDING__))
- return this.$getMultiBind().getMainBindXpath();
- var m = this.getModel(true);
- return (m && m.connect
- ? m.connect.select + "/"
- : (this.dataParent
- ? this.dataParent.xpath + "/"
- : "")) + this.smartBinding.bindings[this.mainBind][0].getAttribute("select");
- };
-
- /**
- * Checks whether this element is completely bound.
- *
- * @return {Boolean}
- */
- this.isBoundComplete = function(){
- if (!this.smartBinding) return true;
- if (!this.xmlRoot) return false;
-
- if (this.hasFeature(__MULTIBINDING__) && !this.$getMultiBind().xmlRoot)
- return false;
- return true;
- };
-
- /**
- * Queries the bound data for a string value
- *
- * @param {String} xpath the xpath statement which queries on the data this element is bound on.
- * @return {String} value of the selected XML Node
- * @todo
- * lstRev.query('revision/text()', 'selected');
- * lstRev.query('revision/text()', 'xmlRoot');
- * lstRev.query('revision/text()', 'indicator');
- */
- this.queryValue = function(xpath, type){
- return jpf.getXmlValue(this[type || 'xmlRoot'], xpath );
- };
- /**
- * Queries the bound data for an array of string values
- *
- * @param {String} xpath the xpath statement which queries on the data this element is bound on.
- * @return {String} value of the selected XML Node
- */
- this.queryValues = function(xpath, type){
- return jpf.getXmlValues(this[type || 'xmlRoot'], xpath );
- };
-
- /**
- * Executes an xpath statement on the data of this model
- *
- * @param {String} xpath the xpath used to select the XMLNode(s).
- * @return {variant} XMLNode or NodeList with the result of the selection
- */
- this.queryNode = function(xpath, type){
- var n = this[type||'xmlRoot'];
- return n?n.selectSingleNode(xpath):null;
- };
-
-
- /**
- * Executes an xpath statement on the data of this model
- *
- * @param {String} xpath the xpath used to select the XMLNode(s).
- * @return {variant} XMLNode or NodeList with the result of the selection
- */
- this.queryNodes = function(xpath, type){
- var n = this[type||'xmlRoot'];
- return n?n.selectNodes(xpath):null;
- };
-
- /**
- * Loads the binding rules from the j:bindings element
- *
- * @param {Array} rules the rules array created using {@link core.jpf.method.getrules}
- * @param {XMLElement} [xmlNode] the reference to the j:bindings xml element
- * @see element.smartbinding
- */
- this.loadBindings = function(rules, node){
- if (this.bindingRules)
- this.unloadBindings();
- this.bindingRules = rules;
-
- jpf.console.info("Initializing Bindings for " + this.tagName + "[" + (this.name || '') + "]");
-
- if (this.$loaddatabinding)
- this.$loaddatabinding();
-
- if (this.bindingRules["traverse"])
- this.parseTraverse(this.bindingRules["traverse"][0]);
-
- this.$checkLoadQueue();
- };
-
- this.$checkLoadQueue = function(){
- // Load from queued load request
- if (loadqueue) {
- if (this.load(loadqueue[0], loadqueue[1]) != loadqueue)
- loadqueue = null;
- }
- };
-
- /**
- * Unloads the binding rules from this element
- *
- * @see element.smartbinding
- */
- this.unloadBindings = function(){
- if (this.$unloaddatabinding)
- this.$unloaddatabinding();
-
- var node = this.xmlBindings;//this.$jml.selectSingleNode("Bindings");
- if (!node || !node.getAttribute("connect"))
- return;
-
- //Fails if parent window is closing...
- try {
- var o = eval(node.getAttribute("connect"));
- o.disconnect(this, node.getAttribute("type"));
- }
- catch(e) {}//ignore that case
-
- this.bindingRules = null;
-
- return this.uniqueId;
- };
-
- /**
- * Loads the action rules from the j:actions element
- *
- * @param {Array} rules the rules array created using {@link core.jpf.method.getrules}
- * @param {XMLElement} [xmlNode] the reference to the j:bindings element
- * @see element.smartbinding
- */
- this.loadActions = function(rules, node){
- if (this.actionRules)
- this.unloadActions();
- this.actionRules = rules;
-
- jpf.console.info("Initializing Actions for " + this.tagName
- + "[" + (this.name || '') + "]");
-
- //@todo revise this
- if (node && (jpf.isTrue(node.getAttribute("transaction"))
- || node.selectSingleNode("add|update"))){
- if (!this.hasFeature(__TRANSACTION__))
- this.inherit(jpf.Transaction); /** @inherits jpf.Transaction */
-
- //Load ActionTracker & xmldb
- if (!this.$at)
- this.$at = new jpf.actiontracker(this);
-
- this.$at.realtime = isTrue(node.getAttribute("realtime"));
- this.defaultMode = node.getAttribute("mode") || "update";
-
- //Turn caching off, it collides with rendering views on copies of data with the same id's
- this.caching = false;
- }
- };
-
- /**
- * Gets the ActionTracker this element communicates with.
- *
- * @return {ActionTracker}
- * @see element.smartbinding
- */
- this.getActionTracker = function(ignoreMe){
- if (!jpf.JmlDom)
- return jpf.window.$at;
-
- var pNode = this, tracker = ignoreMe ? null : this.$at;
- if (!tracker && this.connectId)
- tracker = self[this.connectId].$at;
-
- //jpf.xmldb.getInheritedAttribute(this.$jml, "actiontracker");
- while (!tracker) {
- //if(!pNode.parentNode) throw new Error(jpf.formatErrorString(1055, this, "ActionTracker lookup", "Could not find ActionTracker by traversing upwards"));
- if (!pNode.parentNode)
- return jpf.window.$at;
-
- tracker = (pNode = pNode.parentNode).$at;
- }
- return tracker;
- };
-
- /**
- * Unloads the action rules from this element
- *
- * @see element.smartbinding
- */
- this.unloadActions = function(){
- this.xmlActions = null;
- this.actionRules = null;
-
- //Weird, this cannot be correct... (hack?)
- if (this.$at) {
- if (this.$at.undolength)
- jpf.console.warn("Component : "
- + this.name + " [" + this.tagName + "]\n\
- Message : ActionTracker still has undo stack filled with "
- + this.$at.undolength + " items.");
-
- this.$at = null;
- }
- };
-
- var lock = {};
- var actions = {};
-
- /**
- * Start the specified action, does optional locking and can be offline aware
- * - This method can be cancelled by events, offline etc
- * - This method can execute pessimistic locking calls (<j:name locking="datainstr" /> rule)
- * - or for optimistic locking it will record the timestamp (a setting <j:appsettings locking="optimistic")
- * - During offline work, pessimistic locks will always fail
- * - During offline work, optimistic locks will be handled by taking the timestamp of going offline
- * - This method is always optional! The server should not expect locking to exist.
- * Single Client Locking
- * - Because of the increased complexity of this, when a lock fails (either pessimistic or optimistic)
- * the developer should handle this by reloading that part of the content for which the lock failed.
- * It is impossible for JPF to know which part this is and what to update
- * Example:
- * <code>
- * <j:rename set="..." lock="rpc:comm.lockFile(xpath:@path, unlock)" />
- * </code>
- * Note: I am expecting the status codes specified in RFC4918 for the locking implementation
- * http://tools.ietf.org/html/rfc4918#section-9.10.6
- *
- * @event locksuccess Fires when a lock request succeeds
- * bubbles: yes
- * object:
- * {Number} state the return code of the lock request
- * @event lockfailed Fires when a lock request failes
- * bubbles: yes
- * object:
- * {Number} state the return code of the lock request
- * @event unlocksuccess Fires when an unlock request succeeds
- * bubbles: yes
- * object:
- * {Number} state the return code of the unlock request
- * @event unlockfailed Fires when an unlock request fails
- * bubbles: yes
- * object:
- * {Number} state the return code of the unlock request
- */
- this.$startAction = function(name, xmlContext, fRollback){
- if (this.disabled)
- return false;
-
- var actionRule = this.getNodeFromRule(name, xmlContext, true);
- if (jpf.appsettings.autoDisableActions && !this.actionRules
- || this.actionRules && !actionRule)
- return false;
-
- var bHasOffline = typeof jpf.offline != "undefined";
- if (bHasOffline && !jpf.offline.canTransact())
- return false;
-
- if (this.dispatchEvent(name + "start", {
- xmlContext: xmlContext
- }) === false)
- return false;
-
-
- //Requesting a lock, whilst we still have one open
- if (lock[name] && !lock[name].stopped) {
- jpf.console.warn("Starting new action whilst previous \
- action wasn't terminated:" + name);
-
- this.$stopAction(); //or should we call: fRollback.call(this, xmlContext);
- }
-
- //Check if we should attain a lock (when offline, we just pretend to get it)
- var lockInstruction = actionRule ? actionRule.getAttribute("lock") : null;
- if ((bHasOffline && (!jpf.offline.enabled || !jpf.offline.onLine)) && lockInstruction) {
- var curLock = lock[name] = {
- start : bHasOffline && !jpf.offline.onLine
- ? jpf.offline.offlineTime
- : new Date().getTime(),
- stopped : false,
- xmlContext : xmlContext,
- instr : lockInstruction,
- rollback : fRollback
- };
-
- //Execute pessimistic locking request
- jpf.saveData(lockInstruction, xmlContext, null, function(data, state, extra){
- if (state == jpf.TIMEOUT && extra.retries < jpf.maxHttpRetries)
- return extra.tpModule.retry(extra.id);
-
- if (state == jpf.SUCCESS) {
- _self.dispatchEvent("locksuccess", jpf.extend({
- state : extra.http.status,
- bubbles : true
- }, extra));
-
- curLock.retrieved = true; //@todo Record timeout here... think of method
-
- //Action was apparently finished before the lock came in, cancelling lock
- if (curLock.stopped)
- _self.$stopAction(name, true, curLock);
-
- //That's it we're ready to go...
- }
- else {
- if (curLock.stopped) //If the action has terminated we just let it go
- return; //Do we want to take away the event from the developer??
-
- _self.dispatchEvent("lockfailed", jpf.extend({
- state : extra.http.status,
- bubbles : true
- }, extra));
-
- //Cancel the action, because we didnt get a lock
- fRollback.call(this, xmlContext);
- }
- });
- }
-
- actions[name] = xmlContext;
-
- return true;
- };
-
- // @todo think about if this is only for rsb
- this.addEventListener("xmlupdate", function(e){
- if (jpf.xmldb.disableRSB != 2)
- return;
-
- for (var name in actions) {
- if (jpf.xmldb.isChildOf(actions[name], e.xmlNode, true)) {
- //this.$stopAction(name, true);
- actions[name].rollback.call(this, actions[name].xmlContext);
- }
- }
- });
-
- this.$stopAction = function(name, isCancelled, curLock){
- delete actions[name];
-
- if (!curLock) curLock = lock[name];
-
- if (curLock && !curLock.stopped) {
- curLock.stopped = true;
-
- //The resource needs to unlock when the action is cancelled
- if (isCancelled && curLock.retrieved) {
- //Execute unlocking request
- jpf.saveData(curLock.instr, curLock.xmlContext, {
- unlock : true
- },
- function(data, state, extra){
- if (state == jpf.TIMEOUT && extra.retries < jpf.maxHttpRetries)
- return extra.tpModule.retry(extra.id);
-
- //Do we care if an unlock failed/succeeded?
- _self.dispatchEvent(
- (state == jpf.SUCCESS
- ? "unlocksuccess"
- : "unlockfailed"),
- jpf.extend({
- state : extra.http.status,
- bubbles : true
- }, extra));
- });
- }
- }
-
- return curLock;
- };
-
- /**
- * Executes an action using action rules set in the j:actions element
- *
- * @param {String} atAction the name of the action to be performed by the ActionTracker.
- * Possible values:
- * setTextNode sets the first text node of an xml element. {@link core.xmldb.method.setTextNode}
- * setAttribute sets the attribute of an xml element. {@link core.xmldb.method.setAttribute}
- * removeAttribute removes an attribute from an xml element. {@link core.xmldb.method.removeAttribute}
- * setAttributes sets multiple attribute on an xml element. Arguments are [xmlNode, Array]
- * replaceNode replaces an xml child with another one. {@link core.xmldb.method.replaceNode}
- * addChildNode adds a new xml node to a parent node. {@link core.xmldb.method.addChildNode}
- * appendChild appends an xml node to a parent node. {@link core.xmldb.method.appendChild}
- * moveNode moves an xml node from one parent to another. {@link core.xmldb.method.moveNode}
- * removeNode removes a node from it's parent. {@link core.xmldb.method.removeNode}
- * removeNodeList removes multiple nodes from their parent. {@link core.xmldb.method.removeNodeList}
- * setValueByXpath sets the nodeValue of an xml node whiche is selected by an xpath statement. Arguments are [xmlNode, xpath, value]
- * multicall calls multiple of these actions. Arguments is an array of argument arrays for these actions each with a func property which is the name of the action.
- * @param {Array} args the arguments to the function specified in <code>atAction</code>.
- * @param {String} action the name of the action rule defined in j:actions for this element.
- * @param {XMLElement} xmlNode the context for the action rules.
- * @param {Boolean} [noevent] whether or not to call events.
- * @param {XMLElement} [contextNode] the context node for action processing (such as RPC calls). Usually the same as <code>xmlNode</code>
- * @return {Boolean} specifies success or failure
- * @see element.smartbinding
- */
- this.executeAction = function(atAction, args, action, xmlNode, noevent, contextNode, multiple){
- if (this.disabled) return; //hack
-
- jpf.console.info("Executing action '" + action + "' for " + this.name
- + " [" + (this.tagName || "") + "]");
-
- if(typeof jpf.offline != "undefined" && !jpf.offline.canTransact())
- return false;
-
- //Get Rules from Array
- var rules = this.actionRules
- ? this.actionRules[action]
- : (!action.match(/change|select/) && jpf.appsettings.autoDisableActions
- ? false
- : []);
-
- if (!rules)
- return false;
-
- var curLock = this.$stopAction(action);
-
- for (var node, i = 0; i < (rules.length || 1); i++) {
- if (!rules[i] || !rules[i].getAttribute("select")
- || xmlNode.selectSingleNode(rules[i].getAttribute("select"))) {
-
- var ev = new jpf.Event("before" + action.toLowerCase(), {
- action : atAction,
- args : args,
- xmlActionNode : rules[i],
- jmlNode : this,
- selNode : contextNode,
- multiple : multiple || false
- ,timestamp : curLock
- ? curLock.start
- : new Date().getTime()
- });
-
- //Call Event and cancel if it returns false
- if (!noevent) {
- //Allow the action and arguments to be changed by the event
- if (this.dispatchEvent(ev.name, null, ev) === false)
- return false;
- }
-
- //Call ActionTracker and return ID of Action in Tracker
- var UndoObj = this.getActionTracker().execute(ev);
- ev.xmlNode = UndoObj.xmlNode;
- ev.undoObj = UndoObj;
-
- //Call After Event
- if (!noevent) {
- ev.name = "after" + action.toLowerCase();
- ev.cancelBubble = false;
- delete ev.returnValue;
- this.dispatchEvent(ev.name, null, ev);
- }
-
- return UndoObj;
- }
- }
-
- //Action not executed
- return false;
- };
-
- /**
- * Executes an action based on the set name and the new value
- * @param {String} atName the name of the action rule defined in j:actions for this element.
- * @param {String} setName the name of the binding rule defined in j:bindings for this element.
- * @param {XMLElement} xmlNode the xml element to which the rules are applied
- * @param {String} value the new value of the node
- */
- this.executeActionByRuleSet = function(atName, setName, xmlNode, value){
- var xpath, args, selInfo = this.getSelectFromRule(setName, xmlNode);
- var shouldLoad = false, atAction, node = selInfo[1];
-
- if (node) {
- if (jpf.xmldb.getNodeValue(node) == value) return; // Do nothing if value is unchanged
-
- atAction = (node.nodeType == 1 || node.nodeType == 3
- || node.nodeType == 4) ? "setTextNode" : "setAttribute";
- args = (node.nodeType == 1)
- ? [node, value]
- : (node.nodeType == 3 || node.nodeType == 4
- ? [node.parentNode, value]
- : [node.ownerElement || node.selectSingleNode(".."), node.nodeName, value]);
- }
- else {
- if (!this.createModel)
- return false;
-
- atAction = "setValueByXpath";
- xpath = selInfo[0];
-
- if (!xmlNode) {
- //Assuming this component is connnected to a model
- var model = this.getModel();
- if (model) {
- if (model.connect) {
- xmlNode = model.connect.node.selected || model.connect.node.xmlRoot;
- xpath = (model.connect.select || ".")
- + (xpath && xpath != "." ? "/" + xpath : "");
- shouldLoad = true;
- }
- else {
- if (!model.data)
- model.load("<data />");
-
- xpath = (model.getXpathByJmlNode(this) || ".")
- + (xpath && xpath != "." ? "/" + xpath : "");
- xmlNode = model.data;
- }
- }
- else {
- if (!this.dataParent)
- return false;
-
- xmlNode = this.dataParent.parent.selected || this.dataParent.parent.xmlRoot;
- xpath = (this.dataParent.xpath || ".")
- + (xpath && xpath != "." ? "/" + xpath : "");
- shouldLoad = true;
- }
- }
-
- args = [xmlNode, value, xpath];
- }
-
- //Use Action Tracker
- this.executeAction(atAction, args, atName, xmlNode);
-
- if (shouldLoad)
- this.load(xmlNode.selectSingleNode(xpath));
- };
-
- /**
- * Connects another element to this element. This connection is used
- * to push data from this element to the other element. Whenever this
- * element loads data, (a selection of) the data is pushed to the other
- * element. For elements inheriting from MultiSelect data is pushed
- * when a selection occurs.
- * Example:
- * This is how it's achieved using the javeline markup language.
- * <code>
- * <j:list id="lstExample" />
- * <j:text model="#lstExample:select" />
- * </code>
- *
- * @param {JmlNode} oElement JmlNode specifying the element which is connected to this element.
- * @param {Boolean} [dataOnly]
- * Possible values:
- * true data is sent only once.
- * false real connection is made.
- * @param {String} [xpath] the Xpath statement used to select a subset of the data to sent.
- * @param {String} [type]
- * Possible values:
- * select sents data when a node is selected
- * choice sents data when a node is chosen (by double clicking, or pressing enter)
- * @see element.smartbinding
- * @see baseclass.databinding.method.disconnect
- */
- this.connect = function(o, dataOnly, xpath, type, noselect){
- if (o.dataParent)
- o.dataParent.parent.disconnect(o);
-
- if (!this.signalXmlUpdate)
- this.signalXmlUpdate = {};
-
- o.dataParent = {
- parent: this,
- xpath : xpath
- };
-
- //Onload - check if problem when doing setConnections to early
- if (dataOnly) {
- if (!xpath && !this.selected) {
- throw new Error(jpf.formatErrorString(1056, null,
- "Connecting",
- "Illegal XPATH statement specified: '" + xpath + "'"));
- }
-
- if (cXmlOnLoad)
- return cXmlOnLoad.push([o, xpath]);
- else
- return o.load(xpath ? this.xmlRoot.selectSingleNode(xpath) : this.selected);//(this.selected || this.xmlRoot)
- }
-
- //jpf.debug Message
- //alert(this.tagName + ":" + o.tagName + " - " + type + "["+dataOnly+"]");
-
- //User action - Select || Choice
- if (!dataOnly)
- (!type || type == "select")
- ? cXmlSelect.push({o:o,xpath:xpath})
- : cXmlChoice.push({o:o,xpath:xpath});
-
- //Load Default
- if (type != "choice" && !noselect) {
- if (this.selected || !this.traverse && this.xmlRoot) {
- var xmlNode = this.selected || this.xmlRoot;
- if (xpath) {
- xmlNode = xmlNode.selectSingleNode(xpath);
- if (!xmlNode) {
- //Hack!!
- this.addEventListener("xmlupdate", function(){
- this.connect(o, false, xpath, type);
- this.removeEventListener("xmlupdate", arguments.callee);
- });
- }
- }
-
- if (xmlNode)
- o.load(xmlNode);
- }
- else {
- if (o.clear && !o.hasFeature(__MULTIBINDING__))
- o.clear(); //adding o.hasFeature(__MULTIBINDING__) is a quick fix. should be only with the bind="" level
- if (o.disable && o.createModel)
- o.setProperty("disabled", true);
- }
- }
- };
-
- /**
- * Disconnects a previously established connection with another element.
- *
- * @param {JmlNode} oElement the element to be disconnected from this element.
- * @param {String} [type]
- * Possible values:
- * select disconnects the select connection
- * choice disconnects the choice connection
- * @see element.smartbinding
- * @see baseclass.databinding.method.connect
- */
- this.disconnect = function(o, type){
- //User action - Select || Choice
- var ar = (!type || type == "select") ? cXmlSelect : cXmlChoice; //This should be both when there is no arg set
-
- if (this.signalXmlUpdate) {
- this.signalXmlUpdate[o.uniqueId] = null;
- delete this.signalXmlUpdate[o.uniqueId];
- }
-
- o.dataParent = null;
-
- //CAN BE OPTIMIZED IF NEEDED TO ONLY SET TO null
- for (var i = 0; i < ar.length; i++){
- if (ar[i].o != o) continue;
-
- for (var j = i; j < ar.length; j++)
- ar[j] = ar[j + 1];
- ar.length--;
- i--;
- }
- };
-
- /**
- * Pushes data to connected elements
- *
- * @param {XMLElement} xmlNode the xml data element to be pushed to the connected elements.
- * @param {String} [type]
- * Possible Values:
- * select pushes data to the elements registered for selection
- * choice pushes data to the elements registered for choice
- * @see element.smartbinding
- * @see baseclass.databinding.method.connect
- * @see baseclass.databinding.method.disconnect
- */
- this.setConnections = function(xmlNode, type){
- var a = type == "both"
- ? cXmlChoice.concat(cXmlSelect)
- : (type == "choice" ? cXmlChoice : cXmlSelect);
-
- //Call Load of objects
- for (var x, o, i = 0; i < a.length; i++) {
- o = a[i].o;
- xpath = a[i].xpath;
- o.load((xpath && xmlNode)
- ? xmlNode.selectSingleNode(xpath)
- : xmlNode);
- if (xmlNode && o.disabled && o.createModel)
- o.setProperty("disabled", false);
- }
-
- //Set Onload Connections only Once
- if (!cXmlOnLoad) return;
-
- for (var i = 0; i < cXmlOnLoad.length; i++)
- cXmlOnLoad[i][0].load(cXmlOnLoad[i][1]
- ? this.xmlRoot.selectSingleNode(cXmlOnLoad[i][1])
- : this.selected);//(this.selected || this.xmlRoot)
-
- cXmlOnLoad = null;
- };
-
- /**
- * @private
- */
- this.importConnections = function(x){
- cXmlSelect = x;
- };
-
- /**
- * @private
- */
- this.getConnections = function(){
- return cXmlSelect;
- };
-
- /**
- * @private
- */
- this.removeConnections = function(){
- cXmlSelect = [];
- };
-
- /**
- * Uses bind rules to convert data into a value string
- *
- * @param {String} setname the name of the binding rule set.
- * @param {XMLElement} cnode the xml element to which the binding rules are applied.
- * @param {String} [def] the default (fallback) value for the query.
- * @return {String} the calculated value
- * @see element.smartbinding
- */
- this.applyRuleSetOnNode = function(setname, cnode, def){
- if (!cnode) return "";
-
- //Get Rules from Array
- var rules = typeof setname == "string"
- ? (this.bindingRules || {})[setname]
- : setname;
-
- if (!this.$dcache)
- this.$dcache = {};
-
- if (!rules && !def && !this.$dcache[this.uniqueId + "." + setname]
- && typeof this[setname] != "string") {
- this.$dcache[this.uniqueId + "." + setname] = true;
- jpf.console.info("Could not find a binding rule for '" + setname
- + "' (" + this.tagName
- + " [" + (this.name || "") + "])")
- }
-
- if (!rules) {
- if (setname == "value") setname = "valuerule";
- return typeof this[setname] == "string" && setname != "value"
- && jpf.getXmlValue(cnode, this[setname])
- || def && cnode.selectSingleNode(def) || false;
- }
-
- var node = null, sel, i, o, v, rule;
- for (i = 0; i < rules.length; i++) {
- rule = rules[i];
- sel = jpf.parseExpression(rule.getAttribute("select")) || ".";
- o = cnode.selectSingleNode(sel);
-
- if (o) {
- this.lastRule = rule;
-
- if (v = rule.getAttribute("value")){ //Check for Default Value
- /**
- * @todo internationalization for <j:caption value="no value" />
- */
-
- //jpf.language.addElement(q.nodeValue.replace(/^\$(.*)\$$/,
- // "$1"), {htmlNode : pHtmlNode});
-
- return v;
- }
-
- //Process XSLT/JSLT Stylesheet if needed
- else if(rule.childNodes.length) {
- var xsltNode;
-
- //Check Cache
- if (v = rule.getAttribute("cacheId")) {
- xsltNode = jpf.nameserver.get("xslt", v);
- }
- else {
- //Find Xslt Node
- var prefix = jpf.findPrefix(rule, jpf.ns.xslt);
- var xsltNode;
-
- if (rule.getElementsByTagNameNS) {
- xsltNode = rule.getElementsByTagNameNS(jpf.ns.xslt, "*")[0];
- }
- else {
- var prefix = jpf.findPrefix(rule, jpf.ns.xslt, true);
- if (prefix) {
- if (!jpf.supportNamespaces)
- rule.ownerDocument.setProperty("SelectionNamespaces", "xmlns:"
- + prefix + "='" + jpf.ns.xslt + "'");
- xsltNode = rule.selectSingleNode(prefix + ":*");
- }
- }
-
- if (xsltNode) {
- if (xsltNode[jpf.TAGNAME] != "stylesheet") {
- //Add it
- var baseXslt = jpf.nameserver.get("base", "xslt");
- if (!baseXslt) {
- baseXslt = jpf.getXmlDom(
- '<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:template match="node()"></xsl:template></xsl:stylesheet>')
- .documentElement;
- jpf.nameserver.register("base", "xslt", xsltNode);
- }
-
- var xsltNode = baseXslt.cloneNode(true);
- for (var j = rule.childNodes.length; j >= 0; j++)
- xsltNode.firstChild.appendChild(rule.childNodes[j]);
-
- //Set cache Item
- rule.setAttribute("cacheId",
- jpf.nameserver.add("xslt", xsltNode));
- }
- }
- }
-
- //XSLT
- if (xsltNode) {
- var x = o.transformNode(xsltNode)
- .replace(/^<\?xml version="1\.0" encoding="UTF-16"\?>/, "")
- .replace(/\<\;/g, "<").replace(/\>\;/g, ">")
- .replace(/\&\;/g, "&");
- }
- //JSLT
- else {
- var x = jpf.JsltInstance.apply(rule, o);
-
- var d = document.createElement("div");
- var t = window.onerror;
- window.onerror = function(){
- window.onerror = t;
- throw new Error(jpf.formatErrorString(0, this, "JSLT transform", "HTML Error:"+x,rule));
- }
- d.innerHTML = x;
- d.innerHTML = '';
- window.onerror = t;
- }
-
- if (v = rule.getAttribute("method")) {
- try{
- eval(v);
- }
- catch(e) {
- jpf.console.warn("Method not available (yet): '" + v + "'");
- return false;
- }
- }
-
- return rule.getAttribute("method") ? self[rule.getAttribute("method")](x, this) : x;
- }
-
- //Execute Callback if any
- else if(v = rule.getAttribute("method")){
- if(!self[v]){
- jpf.console.warn("Method not available (yet): '" + v + "'");
-
- return false;
- }
-
- return self[v](o, this);
- }
- //Execute Expression
- else if(v = rule.getAttribute("eval")){
- var func = new Function('xmlNode', 'control', "return " + v);
-
- var value = func.call(this, o, this);
- if (!value) continue;
-
- return value;
- }
- //Process XMLElement
- else {
- var value;
- if (o.nodeType == 2) {
- try {
- value = unescape(decodeURI(o.nodeValue));
- }
- catch(e) {
- value = unescape(o.nodeValue);
- }
- }
- else {
- if (o.nodeType == 1) {
- if (!o.firstChild || o.firstChild.nodeType == 1 || o.firstChild.nodeType > 4)
- return "";
-
- value = o.firstChild.nodeValue;
- }
- else
- value = o.nodeValue;
- }
-
- //Mask Support
- if (v = rule.getAttribute("mask")) {
- if (value.match(/^(?:true|false)$/))
- value = value == "true" ? 1 : 0;
- return v.split(";")[value];
- }
- else
- return value;
- }
- }
- }
-
- if (!this.$dcache[this.uniqueId + "." + setname]) {
- this.$dcache[this.uniqueId + "." + setname] = true;
- jpf.console.warn("Could not find a SmartBindings rule for property \
- '" + setname + "' which matches any data for \
- component " + this.name + " [" + this.tagName + "].")
- }
-
- //Applying failed
- return false;
- };
-
- /**
- * Assigns a smartbinding definition to this element
- *
- * @param {mixed} sb
- * Possible values:
- * {SmartBinding} object to be assigned to this element.
- * {String} the name of the SmartBinding.
- * @throws Error If no SmartBinding was passed to the method.
- * @see element.smartbinding
- */
- this.setSmartBinding = function(sb){
- this.$propHandlers["smartbinding"].call(this, sb);
- /*
- this.setProperty && this.setProperty("smartbinding", sb)
- ||
- */
- };
-
- /**
- * Removes the smartbinding from this element
- *
- * @see element.smartbinding
- */
- this.removeSmartBinding = function(){
- this.setProperty("smartbinding", null);
- };
-
- /**
- * Gets the smartbinding of this element
- *
- * @returns {SmartBinding} The SmartBinding object of this element
- * @see element.smartbinding
- */
- this.getSmartBinding = function(){
- return this.smartBinding;
- };
-
- /**
- * Gets the model to which this element is connected.
- * This is the model which acts as a datasource for this element.
- *
- * @param {Boolean} doRecur whether the model should be searched recursively up the data tree.
- * @returns {Model} The model this element is connected to.
- * @see element.smartbinding
- */
- this.getModel = function(doRecur){
- if(doRecur && !this.$model)
- return this.dataParent ? this.dataParent.parent.getModel(true) : null;
-
- return this.$model;
- };
-
- /**
- * Sets the model to which this element is connected.
- * This is the model which acts as datasource for this element.
- *
- * @param {Model} model the model this element will be connected to.
- * @param {String} [xpath] the xpath statement used to query a subset of the data presented by the model.
- * @see element.smartbinding
- */
- this.setModel = function(model, xpath){
- if (this.$model)
- this.$model.unregister(this);
-
- if (typeof model == "string")
- model = jpf.nameserver.get("model", model);
-
- this.$model = model;
- model.register(this, xpath);
- };
-
- /**
- * Gets the data element or binding / action rule of a binding set.
- *
- * @param {String} setname the name of the binding/action rule set.
- * @param {XMLElement} cnode the xml element to which the binding rules are applied.
- * @param {Boolean} [isAction] whether search is for an action rule.
- * @param {Boolean} [getRule] whether search is for a binding rule.
- * @param {Boolean} [createNode] whether the xml data elementis created when it doesn't exist.
- * @returns {XMLElement} the requested node.
- * @see element.smartbinding
- */
- this.getNodeFromRule = function(setname, cnode, isAction, getRule, createNode){
- //Get Rules from Array
- var rules = ((isAction ? this.actionRules : this.bindingRules) || {})[setname];
- if (!rules) {
- if (setname == "value") setname = "valuerule";
- if (!isAction && !getRule && typeof this[setname] == "string") {
- return cnode.selectSingleNode(this[setname]) || (createNode
- ? jpf.xmldb.createNodeFromXpath(cnode, this[setname])
- : false);
- }
- return false;
- }
-
- for(var i = 0; i < rules.length; i++) {
- if (!rules[i]) continue;
-
- var sel = jpf.parseExpression(rules[i].getAttribute("select")) || ".";
-
- if (!sel)
- return getRule ? rules[i] : false;
- if (!cnode) return false;
-
- var o = cnode.selectSingleNode(sel);
- if (o)
- return getRule ? rules[i] : o;
-
- if (createNode || rules[i].getAttribute("create") == "true") {
- var o = jpf.xmldb.createNodeFromXpath(cnode, sel);
- return getRule ? rules[i] : o;
- }
- }
-
- //Retrieving Failed
- return false;
- };
-
- /**
- * Returns the select statement of a binding or action rule
- *
- * @param {String} setname the name of the binding/action rule set.
- * @param {XMLElement} cnode the xml element to which the binding rules are applied.
- * @returns {String}
- */
- this.getSelectFromRule = function(setname, cnode){
- var rules = this.bindingRules && this.bindingRules[setname];
- if (!rules || !rules.length) {
- if (setname == "value") setname = "valuerule";
- return typeof this[setname] == "string" && [this[setname]] || ["."];
-
- }
-
- for (var first, i = 0; i < rules.length; i++) {
- var sel = jpf.parseExpression(rules[i].getAttribute("select")) || ".";
-
- if (!cnode) return [sel];
- if (i == 0)
- first = sel;
-
- var o = cnode.selectSingleNode(sel);
- if (o)
- return [sel, o];
- }
-
- return [first];
- };
-
- /**
- * Reloads the data in this element.
- *
- */
- this.reload = function(){
- var sb = this.getSmartBinding();
- if (sb && sb.$isMarkedForUpdate(this)) {
- sb.$updateMarkedItems();
- }
- else
- this.load(this.xmlRoot, this.cacheID, true);
- };
-
- /**
- * Loads data in to this element using binding rules to transform the
- * data in to a presentation.
- * Example:
- * <code>
- * <j:list id="lstExample">
- * <j:bindings>
- * <j:caption select="text()" />
- * <j:icon select="@icon" />
- * <j:traverse select="image" />
- * </j:bindings>
- * </j:list>
- *
- * <j:script>
- * lstExample.load('<images>\
- * <image icon="icoTest.gif">image 1</image>\
- * <image icon="icoTest.gif">image 2</image>\
- * <image icon="icoTest.gif">image 3</image>');
- * </j:script>
- * </code>
- *
- * @param {mixed} [xmlRootNode]
- * Possible Values:
- * {XMLElement} an xml element loaded in to this element.
- * {String} an xml string which is loaded in this element.
- * {Null null clears this element from it's data {@link baseclass.cache.method.clear}.
- * @param {String} [cacheID] the xml element to which the binding rules are applied.
- * @param {Boolean} [forceNoCache] whether cache is checked before loading the data.
- * @event beforeload Fires before loading data in this element.
- * cancellable: Prevents the data from being loaded.
- * object:
- * {XMLElement} xmlNode the node that is loaded as the root data element.
- * @event afterload Fires after loading data in this element.
- * object:
- * {XMLElement} xmlNode the node that is loaded as the root data element.
- * @see element.smartbinding
- * @see baseclass.cache.method.clear
- */
- this.load = function(xmlRootNode, cacheID, forceNoCache, noClearMsg){
- if (jpf.popup.isShowing(this.uniqueId))
- jpf.popup.forceHide(); //This should be put in a more general position
-
- // If control hasn't loaded databinding yet, queue the call
- if ((!this.bindingRules && this.$jml
- && (!this.smartBinding || jpf.JmlParser.stackHasBindings(this.uniqueId))
- && !this.traverse) || (this.$canLoadData && !this.$canLoadData())) {
- if (!jpf.JmlParser.stackHasBindings(this.uniqueId)) {
- jpf.console.warn("Could not load data yet in " + this.tagName
- + "[" + (this.name || "") + "]. The loaded data is queued \
- until smartbinding rules are loaded or set manually.");
- }
- return loadqueue = [xmlRootNode, cacheID];
- }
- // Convert first argument to an xmlNode we can use;
- if (xmlRootNode)
- xmlRootNode = jpf.xmldb.getBindXmlNode(xmlRootNode);
-
- // If no xmlRootNode is given we clear the control, disable it and return
- if (this.dataParent && this.dataParent.xpath)
- this.dataParent.parent.signalXmlUpdate[this.uniqueId] = !xmlRootNode;
-
- if (!xmlRootNode && (!cacheID || !this.isCached(cacheID))) {
- jpf.console.warn("No xml root node was given to load in "
- + this.tagName + "[" + (this.name || '') + "]. Clearing any \
- loaded xml in this component");
-
- this.clear(noClearMsg, true);
-
- if (jpf.appsettings.autoDisable && !this.createModel)
- this.setProperty("disabled", true);
-
- this.setConnections();
- return;
- }
-
- var disabled = this.disabled;
- this.disabled = false;
-
- // Remove listen root if available (support for listening to non-available data)
- if (this.$listenRoot) {
- jpf.xmldb.removeNodeListener(this.$listenRoot, this);
- this.$listenRoot = null;
- }
-
- //Run onload event
- if (this.dispatchEvent("beforeload", {xmlNode : xmlRootNode}) === false)
- return false;
-
- jpf.console.info("Loading XML data in "
- + this.tagName + "[" + (this.name || '') + "]");
-
- // If reloading current document, and caching is disabled, exit
- if (this.caching && !forceNoCache && xmlRootNode && xmlRootNode == this.xmlRoot)
- return;
-
- // retrieve the cacheId
- if (!cacheID) {
- cacheID = xmlRootNode.getAttribute(jpf.xmldb.xmlIdTag) ||
- jpf.xmldb.nodeConnect(jpf.xmldb.getXmlDocId(xmlRootNode), xmlRootNode);
- }
-
- // Remove message notifying user the control is without data
- if (this.$removeClearMessage)
- this.$removeClearMessage();
-
- // Retrieve cached version of document if available
- var fromCache;
- if (this.caching && !forceNoCache && (fromCache = this.getCache(cacheID, xmlRootNode))) {
- if (fromCache == -1)
- return;
-
- if (!this.hasFeature(__MULTISELECT__))
- this.setConnections(this.xmlRoot, "select");
- else {
- var nodes = this.getTraverseNodes();
-
- //Information needs to be passed to the followers... even when cached...
- if (nodes.length && this.autoselect)
- this.select(nodes[0], null, null, null, true);
- else
- this.setConnections();
-
- if (!nodes.length)
- this.$setClearMessage(this.emptyMsg, "empty");
- }
-
- //@todo move this to getCache??
- if (this.hasFeature(__MULTISELECT__) && nodes.length != this.length)
- this.setProperty("length", nodes.length);
-
- this.dispatchEvent('afterload', {XMLRoot : xmlRootNode});
- return;
- }
- else
- this.clear(true);
-
- //Set usefull vars
- this.documentId = jpf.xmldb.getXmlDocId(xmlRootNode);
- this.cacheID = cacheID;
- this.xmlRoot = xmlRootNode;
-
- // Draw Content
- this.$load(xmlRootNode);
-
- // Check if subtree should be loaded
- this.$loadSubData(xmlRootNode);
-
- if (!this.createModel) {
- this.disabled = true;
- this.setProperty("disabled", false);
- }
- else
- this.disabled = disabled;
-
- // Check Connections
- if (!this.hasFeature(__MULTISELECT__))
- this.setConnections(this.xmlRoot);
-
- // Run onafteronload event
- this.dispatchEvent('afterload', {xmlNode : xmlRootNode});
- };
-
- /**
- * @binding load Determines how new data is loaded data is loaded into this
- * element. Usually this is only the root node containing no children.
- * Example:
- * This example shows a load rule in a text element. It gets its data from
- * a list. When a selection is made on the list the data is loaded into the
- * text element.
- * <code>
- * <j:list id="lstExample" smartbinding="..." />
- *
- * <j:text model="#lstExample">
- * <j:bindings>
- * <j:load get="url:getMessage.php?id={@id}" />
- * <j:contents select="message/text()" />
- * </j:bindings>
- * </j:text>
- * </code>
- * @attribute {string} get the data instruction on how to load data from the data source into the xmlRoot of this component.
- */
- this.$loadSubData = function(xmlRootNode){
- if (this.hasLoadStatus(xmlRootNode)) return;
-
- if (typeof jpf.offline != "undefined" && !jpf.offline.onLine) {
- jpf.offline.transactions.actionNotAllowed();
- this.loadedWhenOffline = true;
-
- if (this.hasFeature(__MULTISELECT__) && !this.getTraverseNodes().length)
- this.$setClearMessage(this.offlineMsg, "offline");
-
- return;
- }
-
- //var loadNode = this.applyRuleSetOnNode("load", xmlRootNode);
- var loadNode, rule = this.getNodeFromRule("load", xmlRootNode, false, true);
- var sel = (rule && rule.getAttribute("select"))
- ? rule.getAttribute("select")
- : ".";
-
- if (rule && (loadNode = xmlRootNode.selectSingleNode(sel))) {
- this.setLoadStatus(xmlRootNode, "loading");
-
- if (this.$setClearMessage)
- this.$setClearMessage(this.loadingMsg, "loading");
-
- //||jpf.xmldb.findModel(xmlRootNode)
- var mdl = this.getModel(true);
- if (!mdl)
- throw new Error("Could not find model");
-
- var jmlNode = this;
- if (mdl.insertFrom(rule.getAttribute("get"), loadNode, {
- insertPoint : xmlRootNode, //this.xmlRoot,
- jmlNode : this
- }, function(){
- jmlNode.setConnections(xmlRootNode);//jmlNode.xmlRoot);
- }) === false
- ) {
- this.clear(true);
- if (jpf.appsettings.autoDisable)
- this.setProperty("disabled", true);
- this.setConnections(null, "select"); //causes strange behaviour
- }
- }
- };
-
- /**
- * @private
- */
- this.setLoadStatus = function(xmlNode, state, remove){
- //remove old status if any
- var ostatus = xmlNode.getAttribute("j_loaded");
- ostatus = ostatus
- ? ostatus.replace(new RegExp("\\|\\w+\\:" + this.uniqueId + "\\|", "g"), "")
- : "";
-
- if (!remove)
- ostatus += "|" + state + ":" + this.uniqueId + "|";
-
- xmlNode.setAttribute("j_loaded", ostatus);
- };
-
- /**
- * @private
- */
- this.removeLoadStatus = function(xmlNode){
- this.setLoadStatus(xmlNode, null, true);
- };
-
- /**
- * @private
- */
- this.hasLoadStatus = function(xmlNode, state){
- var ostatus = xmlNode.getAttribute("j_loaded");
- if (!ostatus) return false;
-
- return (ostatus.indexOf((state || "") + ":" + this.uniqueId + "|") != -1)
- };
-
- /**
- * @event beforeinsert Fires before data is inserted.
- * cancellable: Prevents the data from being inserted.
- * object:
- * {XMLElement} xmlParentNode the parent in which the new data is inserted
- * @event afterinsert Fires after data is inserted.
- */
-
- /**
- * @private
- */
- this.insert = function(XMLRoot, parentXMLElement, options){
- if (typeof XMLRoot != "object")
- XMLRoot = jpf.getXmlDom(XMLRoot).documentElement;
- if (!parentXMLElement)
- parentXMLElement = this.xmlRoot;
-
- if (this.dispatchEvent("beforeinsert", {xmlParentNode : parentXMLElement}) === false)
- return false;
-
- //Integrate XMLTree with parentNode
- var newNode = jpf.xmldb.integrate(XMLRoot, parentXMLElement,
- jpf.extend(options, {copyAttributes: true}));
-
- //Call __XMLUpdate on all listeners
- jpf.xmldb.applyChanges("insert", parentXMLElement);
-
- //Select or propagate new data
- if (this.selectable && this.autoselect) {
- if (this.xmlRoot == newNode)
- this.$selectDefault(this.xmlRoot);
- }
- else if (this.xmlRoot == newNode)
- this.setConnections(this.xmlRoot, "select");
-
- if (this.hasLoadStatus(parentXMLElement, "loading"))
- this.setLoadStatus(parentXMLElement, "loaded");
-
- this.dispatchEvent("afterinsert");
-
- //Check Connections
- //this one shouldn't be called because they are listeners anyway...(else they will load twice)
- //if(this.selected) this.setConnections(this.selected, "select");
- };
-
- this.inherit(this.hasFeature(__MULTISELECT__)
- ? jpf.MultiselectBinding
- : jpf.StandardBinding);
-
- function findModel(x, isSelection) {
- return x.getAttribute((isSelection
- ? "ref"
- : "") + "model") || jpf.xmldb.getInheritedAttribute(x, null,
- function(xmlNode){
- if (isSelection && x == xmlNode)
- return false;
- if (xmlNode.getAttribute("model")) {
- /*
- var isCompRef = xmlNode.getAttribute("model").substr(0,1) == "#";
- if (xmlNode.getAttribute("id")
- && self[xmlNode.getAttribute("id")].hasFeature(__DATABINDING__)) {
- var data = xmlNode.getAttribute("model").split(":", 3);
- return "#" + xmlNode.getAttribute("id") + ((isCompRef
- ? data[2]
- : data[1]) || "");
- }
- */
- return xmlNode.getAttribute("model");
- }
- if (xmlNode.getAttribute("smartbinding")) {
- var bclass = x.getAttribute("smartbinding").split(" ")[0];
- if (jpf.nameserver.get("model", bclass))
- return bclass + ":select";
- }
- return false
- });
- }
-
- var initModelId = [];
- this.$addJmlLoader(function(x){
- //, this.ref && this.hasFeature(__MULTISELECT__)
- if (initModelId[0])
- jpf.setModel(initModelId[0], this);
- if (initModelId[1])
- jpf.setModel(initModelId[1], this, true);
-
- var hasModel = initModelId.length;
-
- //Set the model for normal smartbinding
- if ((!this.ref || this.hasFeature(__MULTISELECT__)) && !this.xmlRoot) {
- var sb = jpf.JmlParser.sbInit[this.uniqueId]
- && jpf.JmlParser.sbInit[this.uniqueId][0];
-
- //@todo experimental for traverse="" attributes
- if (this.traverse && (sb && !sb.model
- || !sb && this.hasFeature(__MULTISELECT__))
- || !initModelId[0] && sb) {
- initModelId = findModel(x);
-
- if (initModelId) {
- if (!sb)
- this.smartBinding = true; //@todo experimental for traverse="" attributes
-
- jpf.setModel(initModelId, this, 0);
- }
- }
- }
-
- initModelId = null;
-
- if (this.hasFeature(__MULTISELECT__) || this.$hasStateMessages) {
- //@todo An optimization might be to loop through the parents once
- var defProps = ["empty-message", "loading-message", "offline-message"];
-
- for (var i = 0, l = defProps.length; i < l; i++) {
- if (!x.getAttribute(defProps[i]))
- this.$propHandlers[defProps[i]].call(this);
- }
- }
-
- if (!x.getAttribute("create-model"))
- this.$propHandlers["create-model"].call(this);
-
- var hasInitSb = jpf.JmlParser.sbInit[this.uniqueId] ? true : false;
- if ((!hasInitSb || !hasModel) && this.$setClearMessage
- && (!loadqueue && !this.xmlRoot && (this.hasFeature(__MULTISELECT__)
- || this.ref || hasInitSb)))
- this.$setClearMessage(this.emptyMsg, "empty");
- });
-
- this.$jmlDestroyers.push(function(){
- // Remove data connections - Should be in DataBinding
- if (this.dataParent)
- this.dataParent.parent.disconnect(this);
- if (this.hasFeature(__DATABINDING__)) {
- this.unloadBindings();
- this.unloadActions();
- }
- });
-
- /**
- * @attribute {Boolean} render-root whether the xml element loaded into this
- * element is rendered as well. Default is false.
- * Example:
- * This example shows a tree which also renders the root element.
- * <code>
- * <j:tree render-root="true">
- * <j:model>
- * <root name="My Computer">
- * <drive letter="C">
- * <folder path="/Program Files" />
- * <folder path="/Desktop" />
- * </drive>
- * </root>
- * </j:model>
- * </j:tree>
- * </code>
- */
- this.$booleanProperties["render-root"] = true;
- this.$supportedProperties.push("empty-message", "loading-message",
- "offline-message", "render-root", "smartbinding", "create-model",
- "bindings", "actions", "dragdrop");
-
- this.$propHandlers["render-root"] = function(value){
- this.renderRoot = value;
- }
-
- /**
- * @attribute {String} empty-message the message displayed by this element
- * when it contains no data. This property is inherited from parent nodes.
- * When none is found it is looked for on the appsettings element. Otherwise
- * it defaults to the string "No items".
- */
- this.$propHandlers["empty-message"] = function(value){
- this.emptyMsg = value
- || jpf.xmldb.getInheritedAttribute(this.$jml, "empty-message")
- || "No items";
-
- if (!jpf.isParsing)
- this.$updateClearMessage(this.emptyMsg, "empty");
- };
-
- /**
- * @attribute {String} loading-message the message displayed by this
- * element when it's loading. This property is inherited from parent nodes.
- * When none is found it is looked for on the appsettings element. Otherwise
- * it defaults to the string "Loading...".
- * Example:
- * This example uses property binding to update the loading message. The
- * position of the progressbar should be updated by the script taking care
- * of loading the data.
- * <code>
- * <j:list loading-message="{'Loading ' + Math.round(progress1.value*100) + '%'}" />
- * <j:progressbar id="progress1" />
- * </code>
- * Remarks:
- * Usually a static loading message is displayed for only 100 milliseconds
- * or so, whilst loading the data from the server. This is done for instance
- * when the load binding rule is used. In the code example below a list
- * binds on the selection of a tree displaying folders. When the selection
- * changes, the list loads new data by extending the model. During the load
- * of this new data the loading message is displayed.
- * <code>
- * <j:list model="#trFolders">
- * <j:bindings>
- * ...
- * <j:load load="rpc:comm.getFiles({@path})" />
- * </j:bindings>
- * </j:list>
- * </code>
- */
- this.$propHandlers["loading-message"] = function(value){
- this.loadingMsg = value
- || jpf.xmldb.getInheritedAttribute(this.$jml, "loading-message")
- || "Loading...";
-
- if (!jpf.isParsing)
- this.$updateClearMessage(this.loadingMsg, "loading");
- };
-
- /**
- * @attribute {String} offline-message the message displayed by this
- * element when it can't load data because the application is offline.
- * This property is inherited from parent nodes. When none is found it is
- * looked for on the appsettings element. Otherwise it defaults to the
- * string "You are currently offline...".
- */
- this.$propHandlers["offline-message"] = function(value){
- this.offlineMsg = value
- || jpf.xmldb.getInheritedAttribute(this.$jml, "offline-message")
- || "You are currently offline...";
-
- if (!jpf.isParsing)
- this.$updateClearMessage(this.offlineMsg, "offline");
- };
-
- /**
- * @attribute {Boolean} create-model whether the model this element connects
- * to is extended when the data pointed to does not exist. Defaults to true.
- * Example:
- * In this example a model is extended when the user enters information in
- * the form elements. Because no model is specified for the form elements
- * the first available model is chosen. At the start it doesn't have any
- * data, this changes when for instance the name is filled in. A root node
- * is created and under that a 'name' element with a textnode containing
- * the entered text.
- * <code>
- * <j:model id="mdlForm" submission="url:save_form.php" />
- *
- * <j:bar>
- * <j:label>Name</j:label>
- * <j:textbox ref="name" required="true" />
- *
- * <j:label>Address</j:label>
- * <j:textarea ref="address" />
- *
- * <j:label>Country</j:label>
- * <j:dropdown ref="country" model="url:countries.xml" traverse="country" caption="@name" />
- *
- * <j:button action="submit">Submit</j:button>
- * </j:bar>
- * </code>
- */
- this.$propHandlers["create-model"] = function(value){
- this.createModel = !jpf.isFalse(
- jpf.xmldb.getInheritedAttribute(this.$jml, "create-model"));
-
- var mb;
- if (this.getMultibinding && (mb = this.getMultibinding()))
- mb.createModel = this.createModel;
- };
-
- /**
- * @attribute {String} smartbinding the name of the SmartBinding for this
- * element. A smartbinding is a collection of rules which define how data
- * is transformed into representation, how actions on the representation are
- * propagated to the data and it's original source, how drag&drop actions
- * change the data and where the data is loaded from. Each of these are
- * optionally defined in the smartbinding set and can exist independently
- * of the smartbinding object.
- * Example:
- * This example shows a fully specified smartbinding. Usually only parts
- * are used. This example shows a tree with files and folders.
- * <code>
- * <j:tree smartbinding="sbExample" />
- *
- * <j:smartbinding id="sbExample">
- * <j:bindings>
- * <j:caption select = "@name"/>
- * <j:icon select = "self::file"
- * value = "icoFile.gif" />
- * <j:icon value = "icoFolder.gif" />
- * <j:traverse select = "file|folder|root" />
- * </j:bindings>
- * <j:actions>
- * <j:remove set = "url:remove.php?path={@path}" />
- * <j:rename set = "url:move.php?from=oldValue&to={@path}" />
- * </j:actions>
- * <j:dragdrop>
- * <j:allow-drag select = "folder|file" />
- * <j:allow-drop select = "folder"
- * target = "root"
- * operation = "tree-append" />
- * <j:allow-drop select = "folder"
- * target = "folder"
- * operation = "insert-before" />
- * <j:allow-drop select = "file"
- * target = "folder|root"
- * soperation = "tree-append" />
- * <j:allow-drop select = "file"
- * target = "file"
- * operation = "insert-before" />
- * </j:dragdrop>
- * <j:model load="url:get_listing.php" />
- * </j:smartbinding>
- * </code>
- * Remarks:
- * The smartbinding parts can also be assigned to an element by adding them
- * directly as a child in jml.
- * <code>
- * <j:tree>
- * <j:bindings>
- * ...
- * </j:bindings>
- * <j:actions>
- * ...
- * </j:actions>
- * <j:dragdrop>
- * ...
- * </j:dragdrop>
- * <j:model />
- * </j:tree>
- * </code>
- *
- * See:
- * There are several ways to be less verbose in assigning certain rules.
- * <ul>
- * <li>{@link baseclass.multiselectbinding.binding.traverse}</li>
- * <li>{@link baseclass.dragdrop.attribute.dragEnabled}</li>
- * <li>{@link element.bindings}</li>
- * <li>{@link element.actions}</li>
- * <li>{@link element.dragdrop}</li>
- * <li>{@link baseclass.multiselectbinding.method.loadInlineData}</li>
- * </ul>
- */
- this.$propHandlers["smartbinding"] = function(value, forceInit){
- var sb;
-
- if (value && typeof value == "string") {
- sb = jpf.JmlParser.getSmartBinding(value);
-
- if (!sb)
- throw new Error(jpf.formatErrorString(1059, this,
- "Attaching a smartbinding to " + this.tagName
- + " [" + this.name + "]",
- "Smartbinding '" + value + "' was not found."));
- }
- else
- sb = value;
-
- if (this.smartBinding && this.smartBinding.deinitialize)
- this.smartBinding.deinitialize(this)
-
- if (jpf.isParsing) {
- if (forceInit === true)
- return (this.smartBinding = sb.initialize(this));
-
- return jpf.JmlParser.addToSbStack(this.uniqueId, sb);
- }
-
- return (this.smartBinding = sb.markForUpdate(this));
- };
-
- /**
- * @attribute {String} bindings the id of the j:bindings element which
- * provides the binding rules for this element.
- * Example:
- * This example shows a set of binding rules that transform data into the
- * representation of a list. In this case it displays the names of
- * several email accounts, with after each account name the number of unread
- * mails in that account. It uses JSLT to transform the caption.
- * <code>
- * <j:list bindings="bndExample" />
- *
- * <j:bindings id="bndExample">
- * <j:caption>{text()} (#'mail[@read=0]')</j:caption>
- * <j:icon select = "@icon" />
- * <j:traverse select = "account" sort="text()" />
- * </j:bindings>
- * </code>
- * Remarks:
- * Bindings can also be assigned directly by putting the bindings tag as a
- * child of this element.
- *
- * If the rule only contains a select attribute, it can be written in a
- * short way by adding an attribute with the name of the rule to the
- * element itself:
- * <code>
- * <j:list caption="text()" icon="@icon" traverse="item" />
- * </code>
- */
- this.$propHandlers["bindings"] = function(value){
- var sb = this.smartBinding || (jpf.isParsing
- ? jpf.JmlParser.getFromSbStack(this.uniqueId)
- : this.$propHandlers["smartbinding"].call(this, new jpf.smartbinding()));
-
- if (!value) {
- //sb.removeBindings();
- throw new Error("Not Implemented"); //@todo
- return;
- }
-
- if (!jpf.nameserver.get("bindings", value))
- throw new Error(jpf.formatErrorString(1064, this,
- "Connecting bindings",
- "Could not find bindings by name '" + value + "'", this.$jml));
-
- sb.addBindings(jpf.nameserver.get("bindings", value));
- };
-
- /**
- * @attribute {String} actions the id of the j:actions element which
- * provides the action rules for this element. Action rules are used to
- * send changes on the bound data to a server.
- * Example:
- * <code>
- * <j:tree actions="actExample" />
- *
- * <j:actions id="actExample">
- * <j:rename set="rpc:comm.update({@id}, {@name})" />
- * <j:remove set="rpc:comm.remove({@id})" />
- * <j:add get="rpc:comm.add({../@id})" />
- * </j:actions>
- * </code>
- */
- this.$propHandlers["actions"] = function(value){
- var sb = this.smartBinding || (jpf.isParsing
- ? jpf.JmlParser.getFromSbStack(this.uniqueId)
- : this.$propHandlers["smartbinding"].call(this, new jpf.smartbinding()));
-
- if (!value) {
- //sb.removeBindings();
- throw new Error("Not Implemented"); //@todo
- return;
- }
-
- if (!jpf.nameserver.get("actions", value))
- throw new Error(jpf.formatErrorString(1065, this,
- "Connecting bindings",
- "Could not find actions by name '" + value + "'", this.$jml));
-
- sb.addActions(jpf.nameserver.get("actions", value));
- };
-
- function refModelPropSet(strBindRef){
- var isSelection = this.hasFeature(__MULTISELECT__) ? 1 : 0;
- var o = isSelection
- ? this.$getMultiBind()
- : this;
-
- var sb = hasRefBinding && o.smartBinding || (jpf.isParsing
- ? jpf.JmlParser.getFromSbStack(this.uniqueId, isSelection, true)
- : this.$propHandlers["smartbinding"].call(this, new jpf.smartbinding()))
-
- //We don't want to change a shared smartbinding
- if (!hasRefBinding) {
- if (o.bindingRules)
- o.unloadBindings();
- o.bindingRules = {};
- }
-
- //Get or create bind rule
- var bindRule = (o.bindingRules[o.mainBind] ||
- (o.bindingRules[o.mainBind]
- = [jpf.getXml("<" + (o.mainBind || "value") + " />")]))[0];
-
- //Check if the smartbinding has the rule (We assume all or nothing)
- ((sb.bindings || (sb.bindings = o.bindingRules))[o.mainBind])
- || (sb.bindings[o.mainBind] = [bindRule]);
-
- // Define model
- var model, modelId;
- if (!jpf.isParsing)
- model = o.getModel();
-
- if (!model) {
- modelId = o.lastModelId =
- o.model || findModel(this.$jml, isSelection);
-
- //deprecated bindway: @todo test this!! with a model NOT a component (well that too)
-
- if (!modelId) {
- if (jpf.globalModel) {
- jpf.console.warn("Cannot find a model to connect to, will \
- try to use default model.");
- modelId = "@default";
- }
- else
- throw new Error(jpf.formatErrorString(1062, this, "init",
- "Could not find model to get data from", o.$jml));
- }
- }
-
- /*
- We don't want to connect to the root, that would create a rush
- of unnecessary update messages, so we'll find the element that's
- closest to the node that is gonna feed us the value
- */
- strBindRef.match(/^(.*?)((?:\@[\w-_\:]+|text\(\))(\[.*?\])?|[\w-_\:]+\[.*?\])?$/);
- var valuePath = RegExp.$1;
- var valueSelect = RegExp.$2 || ".";
-
- if (valuePath === null) {
- throw new Error(jpf.formatErrorString(1063, this,
- "Setting @ref",
- "Could not find xpath to determine XMLRoot: "
- + strBindRef, o.$jml));
-
- return;
- }
-
- if (modelId) {
- //Reconstructing modelId with new valuePath
- if (modelId == "@default") {
- valueSelect = strBindRef;
- }
- else if (valuePath) {
- var modelIdParts = modelId.split(":", 3);
-
- modelId = modelIdParts.shift();
- if (modelId.indexOf("#") == 0) {
- modelId += (modelIdParts[0]
- ? ":" + modelIdParts.shift()
- : ":select")
- }
-
- modelId += ":" + ((modelIdParts[0] ? modelIdParts[0] + "/" : "")
- + (valuePath || "."))
- .replace(/\/$/, "")
- .replace(/\/\/+/, "/");
- }
-
- if (jpf.isParsing && initModelId)
- initModelId[isSelection] = modelId
- else
- setModelQueue(modelId, isSelection);
- }
- else {
- var m = (o.lastModelId || "").split(":");
- var modelIdPart = ((m.shift().indexOf("#") == 0
- && m.shift() && m.shift() || m.shift()) || "");
-
- model.$register(this, ((modelIdPart ? modelIdPart + "/" : "")
- + (valuePath || "."))
- .replace(/\/$/, "")
- .replace(/\/\/+/, "/")); //Update model with new info
-
- //Add this item to the queue to reload
- sb.markForUpdate(this, "model");
- }
-
- bindRule.setAttribute("select", valueSelect);
- }
-
- var timer = [];
- function setModelQueue(modelId, isSelection){
- clearTimeout(timer[isSelection ? 1 : 0]);
- timer[isSelection ? 1 : 0] = setTimeout(function(){
- jpf.setModel(modelId, _self, isSelection);
- });
- }
-
- /**
- * @attribute {String} model the name of the model to load data from or a
- * datainstruction to load data.
- * Example:
- * <code>
- * <j:tree model="mdlExample" />
- * <j:model id="mdlExample" load="url:example.xml" />
- * </code>
- * Example:
- * <code>
- * <j:list model="url:friends.xml" />
- * </code>
- * Example:
- * <code>
- * <j:tree id="trContacts" model="rpc:comm.getContacts()" />
- * <j:text model="#trContacts" />
- * </code>
- * Remarks:
- * This attribute is inherited from a parent when not set. You can use this
- * to tell sets of elements to use the same model.
- * <code>
- * <j:bar model="mdlForm">
- * <j:label>Name</j:label>
- * <j:textbox ref="name" />
- *
- * <j:label>Happiness</j:label>
- * <j:slider ref="happiness" min="0" max="10"/>
- * </j:bar>
- *
- * <j:model id="mdlForm">
- * <data />
- * </j:model>
- * </code>
- * When no model is specified the default model is choosen. The default
- * model is the first model that is found without a name, or if all models
- * have a name, the first model found.
- *
- * @attribute {String} select-model the name of the model or a
- * datainstruction to load data that determines the selection of this
- * element.
- * Example:
- * This example shows a dropdown from which the user can select a country.
- * The list of countries is loaded from a model. Usually this would be loaded
- * from a seperate url, but for clarity it's inlined. When the user selects
- * a country in the dropdown the value of the item is stored in the second
- * model (mdlForm) at the position specified by the ref attribute. In this
- * case this is the country element.
- * <code>
- * <j:label>Name</j:label>
- * <j:textbox ref="name" model="mdlForm" />
- *
- * <j:label>Country</j:label>
- * <j:dropdown
- * ref = "country"
- * model = "mdlCountries"
- * select-model = "mdlForm"
- * traverse = "country"
- * value = "@value"
- * caption = "text()">
- * </j:dropdown>
- *
- * <j:model id="mdlCountries">
- * <countries>
- * <country value="USA">USA</country>
- * <country value="GB">Great Brittain</country>
- * <country value="NL">The Netherlands</country>
- * ...
- * </countries>
- * </j:model>
- *
- * <j:model id="mdlForm">
- * <data>
- * <name />
- * <country />
- * </data>
- * </j:model>
- * </code>
- * Remarks:
- * In most cases this attribute isn't used because the model is inherited
- * from a parent element. In a typical form this will happen as follows:
- * <code>
- * <j:bar model="mdlForm">
- * <j:label>Name</j:label>
- * <j:textbox ref="name" />
- *
- * <j:label>Country</j:label>
- * <j:dropdown
- * ref = "country"
- * model = "url:countries.xml"
- * traverse = "country"
- * value = "@value"
- * caption = "text()">
- * </j:dropdown>
- * </j:bar>
- *
- * <j:model id="mdlForm">
- * <data />
- * </j:model>
- * </code>
- * @see baseclass.databinding.attribute.model
- */
- this.$propHandlers["model"] = function(value){
- if (this.$modelIgnoreOnce) {
- delete this.$modelIgnoreOnce;
- return;
- }
-
- if (!value) {
- this.clear();
- this.$model.unregister(this);
- this.$model = null;
- this.lastModelId = "";
- return;
- }
-
- this.lastModelId = value;
-
- if (!this.hasFeature(__MULTISELECT__)) {
- if (jpf.isParsing && this.$jml.getAttribute("ref")) //@todo setting attribute in script block will go wrong
- return; //Ref will take care of everything
-
- //We're changing the model, lets do it using the @ref way
- if (this.ref) {
- refModelPropSet.call(this, this.ref);
- return;
- }
- }
-
- if (jpf.isParsing)
- initModelId[0] = value;
- else
- setModelQueue(value, this.hasFeature(__MULTISELECT__));
- };
-
- /**
- * @attribute {String} ref an xpath statement used to select the data xml
- * element to which this element is bound to.
- * Example:
- * <code>
- * <j:slider ref="@value" model="mdlExample" />
- *
- * <j:model id="mdlExample">
- * <data value="0.3" />
- * </j:model>
- * </code>
- */
- var hasRefBinding;
- this.$propHandlers["ref"] = function(value){
- if (!value) {
- this.unloadBindings();
- hasRefBinding = false;
- return;
- }
-
- refModelPropSet.call(this, value);
-
- //if (isSelection && x.getAttribute("selectcaption"))
- // strBind.push("/><caption select='", x.getAttribute("selectcaption"), "' "); //hack!
-
- hasRefBinding = value ? true : false;
- };
-
- /**
- * @attribute {String} viewport the way this element renders its data.
- * Possible values:
- * virtual this element only renders data that it needs to display.
- * normal this element renders all data at startup.
- * @experimental
- */
- this.$propHandlers["viewport"] = function(value){
- if (value != "virtual")
- return;
-
- this.inherit(jpf.VirtualViewport);
- };
-};
-
-/**
- * @constructor
- * @private
- * @baseclass
- */
-jpf.StandardBinding = function(){
- if (!this.defaultValue) //@todo please use this in a sentence
- this.defaultValue = "";
-
- /**
- * Load XML into this element
- * @private
- */
- this.$load = function(XMLRoot){
- //Add listener to XMLRoot Node
- jpf.xmldb.addNodeListener(XMLRoot, this);
-
- //Set Properties
-
- var lrule, rule;
- for (rule in this.bindingRules) {
- lrule = rule.toLowerCase();
- if (this.$supportedProperties.contains(lrule))
- this.setProperty(lrule, this.applyRuleSetOnNode(rule,
- this.xmlRoot) || "", null, true);
- }
-
- //Think should be set in the event by the Validation Class
- if (this.errBox && this.isValid())
- this.clearError();
- };
-
- /**
- * Set xml based properties of this element
- * @private
- */
- this.$xmlUpdate = function(action, xmlNode, listenNode, UndoObj){
- //Clear this component if some ancestor has been detached
- if (action == "redo-remove") {
- var retreatToListenMode = false, model = this.getModel(true);
- if (model) {
- var xpath = model.getXpathByJmlNode(this);
- if (xpath) {
- var xmlNode = model.data.selectSingleNode(xpath);
- if (xmlNode != this.xmlRoot)
- retreatToListenMode = true;
- }
- }
-
- if (retreatToListenMode || this.xmlRoot == xmlNode) {
- //RLD: Disabled because sometimes indeed components do not
- //have a model when their xmlRoot is removed.
- if (!model) {
- throw new Error(jpf.formatErrorString(0, this,
- "Setting change notifier on component",
- "Component without a model is listening for changes",
- this.$jml));
- }
-
- //Set Component in listening state untill data becomes available again.
- return model.loadInJmlNode(this, xpath);
- }
- }
-
- //Action Tracker Support
- if (UndoObj && !UndoObj.xmlNode)
- UndoObj.xmlNode = this.xmlRoot;
-
- //Set Properties
-
- var lrule, rule;
- for (rule in this.bindingRules) {
- lrule = rule.toLowerCase();
- if (this.$supportedProperties.contains(lrule)) {
- var value = this.applyRuleSetOnNode(rule, this.xmlRoot) || "";
-
- if (this[lrule] != value)
- this.setProperty(lrule, value, null, true);
- }
- }
-
- //Think should be set in the event by the Validation Class
- if (this.errBox && this.isValid())
- this.clearError();
- };
-
- if (!this.clear) {
- this.clear = function(nomsg, do_event){
- this.documentId = this.xmlRoot = this.cacheID = null;
-
- if (this.$clear)
- this.$clear(nomsg, do_event);
- };
- }
-};
-
-/**
- * @constructor
- * @baseclass
- * @private
- */
-jpf.MultiselectBinding = function(){
- this.length = 0;
-
- /**
- * @define bindings
- * @allowchild traverse
- * @binding traverse Determines the list of elements which for which each
- * gets a visual representation within the element. It also can determine
- * the sequence of how the elements are visualized by offering a way to
- * specify the sort order. (N.B. The sorting mechanism is very similar to
- * that of XSLT)
- * Example:
- * This example contains a list that displays elements with the tagName
- * 'mail' that do not have a deleted attribute set to 1.
- * <code>
- * <j:list>
- * <j:bindings>
- * ...
- * <j:traverse select="mail[not(@deleted='1')]" />
- * </j:bindings>
- * </j:list>
- * </code>
- * Example:
- * This example shows how to use the traverse rule to order files based
- * on their modified data.
- * <code>
- * <j:traverse
- * select = "file"
- * sort = "@date"
- * date-format = "DD-MM-YYYY"
- * order = "descending" />
- * </code>
- * Example:
- * This example shows how to do complex sorting using a javascript callback function.
- * <code>
- * <j:traverse select="file|folder" sort="@name" sort-method="compare" />
- * <j:script>
- * function compare(value, args, xmlNode) {
- * //Sort all folders together and all files and then sort on alphabet.
- * return (xmlNode.tagName == "folder" ? 0 : 1) + value;
- * }
- * </j:script>
- * </code>
- * @attribute {String} select an xpath statement which selects the nodes which will be rendered.
- * @attribute {String} sort an xpath statement which selects the value which is subject to the sorting algorithm.
- * @attribute {String} data-type the way sorting is executed. See {@link baseclass.multiselectbinding.binding.traverse.attribute.sort-method} for how to specify a custom sort method.
- * Possible values:
- * string Sorts alphabetically
- * number Sorts based on numerical value (i.e. 9 is lower than 10).
- * date Sorts based on the date sequence (21-6-1980 is lower than 1-1-2000). See {@link baseclass.multiselectbinding.binding.traverse.attribute.date-format} for how to specify the date format.
- * @attribute {String} date-format the format of the date on which is sorted.
- * Possible values:
- * YYYY Full year
- * YY Short year
- * DD Day of month
- * MM Month
- * hh Hours
- * mm Minutes
- * ss Seconds
- * Example:
- * <code>
- * date-format="DD-MM-YYYY"
- * </code>
- * @attribute {String} sort-method the name of a javascript function to executed to determine the value to sort on.
- * @attribute {String} order the order of the sorted list.
- * Possible values:
- * ascending Default sorting order
- * descending Reverses the default sorting order.
- * @attribute {String} case-order whether upper case characters have preference above lower case characters.
- * Possible values:
- * upper-first Upper case characters are higher.
- * lower-first Lower case characters are higher.
- */
- /**
- * @private
- */
- this.parseTraverse = function (xmlNode){
- this.traverse = xmlNode.getAttribute("select");
-
- this.$sort = xmlNode.getAttribute("sort") ? new jpf.Sort(xmlNode) : null;
- };
-
- /**
- * Change the sorting order of this element
- *
- * @param {Object} options the new sort options. These are applied incrementally. Any property not set is maintained unless the clear parameter is set to true.
- * Properties:
- * {String} order see {@link baseclass.multiselectbinding.binding.traverse.attribute.order}
- * {String} [xpath] see {@link baseclass.multiselectbinding.binding.traverse.attribute.sort}
- * {String} [type] see {@link baseclass.multiselectbinding.binding.traverse.attribute.data-type}
- * {String} [method] see {@link baseclass.multiselectbinding.binding.traverse.attribute.sort-method}
- * {Function} [getNodes] Function that retrieves a list of nodes.
- * {String} [dateFormat] see {@link baseclass.multiselectbinding.binding.traverse.attribute.date-format}
- * {Function} [getValue] Function that determines the string content based on an xml node as it's first argument.
- * @param {Boolean} clear removes the current sort options.
- * @param {Boolean} noReload wether to reload the data of this component.
- * @see baseclass.multiselectbinding.binding.traverse
- */
- this.resort = function(options, clear, noReload){
- if (!this.$sort)
- this.$sort = new jpf.Sort();
-
- this.$sort.set(options, clear);
- this.clearAllCache();
-
- if (noReload)
- return;
-
- /*if(this.hasFeature(__VIRTUALVIEWPORT__)){
- jpf.xmldb.clearVirtualDataset(this.xmlRoot);
- this.reload();
-
- return;
- }*/
-
- (function sortNodes(xmlNode, htmlParent) {
- var sNodes = _self.$sort.apply(
- jpf.xmldb.getArrayFromNodelist(xmlNode.selectNodes(_self.traverse)));
-
- for (var i = 0; i < sNodes.length; i++) {
- if (_self.isTreeArch || _self.$withContainer){
- var htmlNode = jpf.xmldb.findHTMLNode(sNodes[i], _self);
-
- if (!_self.$findContainer){
- throw new Error(jpf.formatErrorString(_self,
- "Sorting Nodes",
- "This component does not \
- implement _self.$findContainer"));
- }
-
- var container = _self.$findContainer(htmlNode);
-
- htmlParent.appendChild(htmlNode);
- if (!jpf.xmldb.isChildOf(htmlNode, container, true))
- htmlParent.appendChild(container);
-
- sortNodes(sNodes[i], container);
- }
- else
- htmlParent.appendChild(jpf.xmldb.findHTMLNode(sNodes[i], _self));
- }
- })(this.xmlRoot, this.oInt);
-
- return options;
- };
-
- /**
- * Change sorting from ascending to descending and vice verse.
- */
- this.toggleSortOrder = function(){
- return this.resort({"ascending" : !this.$sort.get().ascending}).ascending;
- };
-
- /**
- * Retrieves the current sort options
- *
- * @returns {Object} the current sort options.
- * Properties:
- * {String} order see {@link baseclass.multiselectbinding.binding.traverse.attribute.order}
- * {String} xpath see {@link baseclass.multiselectbinding.binding.traverse.attribute.sort}
- * {String} type see {@link baseclass.multiselectbinding.binding.traverse.attribute.data-type}
- * {String} method see {@link baseclass.multiselectbinding.binding.traverse.attribute.sort-method}
- * {Function} getNodes Function that retrieves a list of nodes.
- * {String} dateFormat see {@link baseclass.multiselectbinding.binding.traverse.attribute.date-format}
- * {Function} getValue Function that determines the string content based on an xml node as it's first argument.
- * @see baseclass.multiselectbinding.binding.traverse
- */
- this.getSortSettings = function(){
- return this.$sort.get();
- };
-
- /**
- * Gets a nodelist containing the xml data elements which are rendered by
- * this element (aka. traverse nodes, see {@link baseclass.multiselectbinding.binding.traverse}).
- *
- * @param {XMLElement} [xmlNode] the parent element on which the traverse query is applied.
- */
- this.getTraverseNodes = function(xmlNode){
- if (this.$sort) {
- var nodes = jpf.xmldb.getArrayFromNodelist((xmlNode || this.xmlRoot)
- .selectNodes(this.traverse));
- return this.$sort.apply(nodes);
- }
-
- return (xmlNode || this.xmlRoot).selectNodes(this.traverse);
- };
-
- /**
- * Gets the first xml data element which gets representation in this element
- * (aka. traverse nodes, see {@link baseclass.multiselectbinding.binding.traverse}).
- *
- * @param {XMLElement} [xmlNode] the parent element on which the traverse query is executed.
- * @return {XMLElement}
- */
- this.getFirstTraverseNode = function(xmlNode){
- if (this.$sort) {
- var nodes = jpf.xmldb.getArrayFromNodelist((xmlNode || this.xmlRoot)
- .selectNodes(this.traverse));
- return this.$sort.apply(nodes)[0];
- }
-
- return (xmlNode || this.xmlRoot).selectSingleNode(this.traverse);
- };
-
- /**
- * Gets the last xml data element which gets representation in this element
- * (aka. traverse nodes, see {@link baseclass.multiselectbinding.binding.traverse}).
- *
- * @param {XMLElement} [xmlNode] the parent element on which the traverse query is executed.
- * @return {XMLElement} the last xml data element
- * @see baseclass.multiselectbinding.binding.traverse
- */
- this.getLastTraverseNode = function(xmlNode){
- var nodes = this.getTraverseNodes(xmlNode || this.xmlRoot);//.selectNodes(this.traverse);
- return nodes[nodes.length-1];
- };
-
- /**
- * Determines whether an xml data element is a traverse node (see {@link baseclass.multiselectbinding.binding.traverse})
- *
- * @param {XMLElement} [xmlNode] the parent element on which the traverse query is executed.
- * @return {Boolean} whether the xml element is a traverse node.
- * @see baseclass.multiselectbinding.binding.traverse
- */
- this.isTraverseNode = function(xmlNode){
- /*
- Added optimization, only when an object has a tree architecture is it
- important to go up to the traverse parent of the xmlNode, else the node
- should always be based on the xmlroot of this component
- */
- var nodes = this.getTraverseNodes(this.isTreeArch
- ? this.getTraverseParent(xmlNode) || this.xmlRoot
- : this.xmlRoot);
- for (var i = 0; i < nodes.length; i++)
- if (nodes[i] == xmlNode)
- return true;
- return false;
- };
-
- /**
- * Gets the next traverse node (see {@link baseclass.multiselectbinding.binding.traverse}) to be selected
- * from a given traverse node. The method can do this in either direction and
- * also return the Nth node for this algorithm.
- *
- * @param {XMLElement} xmlNode the starting point for determining the next selection.
- * @param {Boolean} [up] the direction of the selection. Default is false.
- * @param {Integer} [count] the distance in number of nodes. Default is 1.
- * @return {XMLElement} the xml data element to be selected next.
- * @see baseclass.multiselectbinding.binding.traverse
- */
- this.getNextTraverseSelected = function(xmlNode, up, count){
- if (!xmlNode)
- xmlNode = this.selected;
- if (!count)
- count = 1;
-
- var i = 0;
- var nodes = this.getTraverseNodes(this.getTraverseParent(xmlNode) || this.xmlRoot);//.selectNodes(this.traverse);
- while (nodes[i] && nodes[i] != xmlNode)
- i++;
-
- var node = (up == null)
- ? nodes[i + count] || nodes[i - count]
- : (up ? nodes[i + count] : nodes[i - count]);
-
- return node || arguments[2] && (i < count || (i + 1) > Math.floor(nodes.length / count) * count)
- ? node
- : (up ? nodes[nodes.length-1] : nodes[0]);
- };
-
- /**
- * Gets the next traverse node (see {@link baseclass.multiselectbinding.binding.traverse}).
- * The method can do this in either direction and also return the Nth next node.
- *
- * @param {XMLElement} xmlNode the starting point for determining the next node.
- * @param {Boolean} [up] the direction. Default is false.
- * @param {Integer} [count] the distance in number of nodes. Default is 1.
- * @return {XMLElement} the next traverse node
- * @see baseclass.multiselectbinding.binding.traverse
- */
- this.getNextTraverse = function(xmlNode, up, count){
- if (!count)
- count = 1;
- if (!xmlNode)
- xmlNode = this.selected;
-
- var i = 0;
- var nodes = this.getTraverseNodes(this.getTraverseParent(xmlNode) || this.xmlRoot);//.selectNodes(this.traverse);
- while (nodes[i] && nodes[i] != xmlNode)
- i++;
-
- return nodes[i + (up ? -1 * count : count)];
- };
-
- /**
- * Gets the parent traverse node (see {@link baseclass.multiselectbinding.binding.traverse}). In some
- * cases the traverse rules has a complex form like 'children/item'. In those
- * cases the generated tree has a different structure from that of the xml
- * data. For these situations the xmlNode.parentNode property won't return
- * the traverse parent, this method will give you the right parent.
- *
- * @param {XMLElement} xmlNode the node for which the parent element will be determined.
- * @return {XMLElement} the parent node or null if none was found.
- * @see baseclass.multiselectbinding.binding.traverse
- */
- this.getTraverseParent = function(xmlNode){
- if (!xmlNode.parentNode || xmlNode == this.xmlRoot) return false;
-
- var x, id = xmlNode.getAttribute(jpf.xmldb.xmlIdTag);
- if (!id) {
- //return false;
- xmlNode.setAttribute(jpf.xmldb.xmlIdTag, "temp");
- id = "temp";
- }
-
- /*
- do {
- xmlNode = xmlNode.parentNode;
- if (xmlNode == this.xmlRoot)
- return false;
- if (this.isTraverseNode(xmlNode))
- return xmlNode;
- } while (xmlNode.parentNode);
- */
-
- //This is not 100% correct, but good enough for now
-
- //temp untill I fixed the XPath implementation
- if (jpf.isSafari) {
- var y = this.traverse.split("\|");
- for (var i = 0; i < y.length; i++) {
- x = xmlNode.selectSingleNode("ancestor::node()[("
- + y[i] + "/@" + jpf.xmldb.xmlIdTag + "='" + id + "')]");
- break;
- }
- } else {
- x = xmlNode.selectSingleNode("ancestor::node()[(("
- + this.traverse + ")/@" + jpf.xmldb.xmlIdTag + ")='"
- + id + "']");
- }
-
- if (id == "temp")
- xmlNode.removeAttribute(jpf.xmldb.xmlIdTag);
- return x;
- };
-
- /**
- * Set listeners, calls HTML creation methods and
- * initializes select and focus states of object.
- */
- this.$load = function(XMLRoot){
- //Add listener to XMLRoot Node
- jpf.xmldb.addNodeListener(XMLRoot, this);
-
- var length = this.getTraverseNodes(XMLRoot).length;
- if (!this.renderRoot && !length)
- return this.clearAllTraverse();
-
- //Traverse through XMLTree
- var nodes = this.$addNodes(XMLRoot, null, null, this.renderRoot);
-
- //Build HTML
- this.$fill(nodes);
-
- //Select First Child
- if (this.selectable) {
- var sel, bHasOffline = (typeof jpf.offline != "undefined");
- if (!this.firstLoad && bHasOffline && jpf.offline.state.enabled
- && jpf.offline.state.realtime) {
- sel = jpf.offline.state.get(this, "selection");
- this.firstLoad = true;
- }
-
- if (sel) {
- var selstate = jpf.offline.state.get(this, "selstate");
-
- if (sel.length == 0) {
- this.clearSelection();
- }
- else {
- for (var i = 0; i < sel.length; i++) {
- sel[i] = jpf.remote.xpathToXml(sel[i],
- this.xmlRoot);
- }
-
- if (selstate[1]) {
- var selected = jpf.remote
- .xpathToXml(selstate[1], this.xmlRoot);
- }
-
- this.selectList(sel, null, selected);
- }
-
- if (selstate[0]) {
- this.setIndicator(jpf.remote
- .xpathToXml(selstate[0], this.xmlRoot));
- }
- }
- else
- if (this.autoselect) {
- if (this.value) {
- var value = this.value;
- this.value = !this.value;
- this.setProperty("value", value);
- }
-
- if (!this.selected) {
- if (this.renderRoot)
- this.select(XMLRoot);
- else if (nodes.length)
- this.$selectDefault(XMLRoot);
- else
- this.setConnections();
- }
- }
- else {
- this.clearSelection(null, true);
- var xmlNode = this.renderRoot
- ? this.xmlRoot
- : this.getFirstTraverseNode(); //should this be moved to the clearSelection function?
- if (xmlNode)
- this.setIndicator(xmlNode);
- this.setConnections(null, "both");
- }
- }
-
- if (this.focussable)
- jpf.window.focussed == this ? this.$focus() : this.$blur();
-
- if (length != this.length)
- this.setProperty("length", length);
- };
-
- var selectTimer = {}, _self = this;
- var actionFeature = {
- "insert" : 127,//1111111
- "add" : 123,//1111011
- "remove" : 47, //0101111
- "redo-remove" : 79, //1001111
- "synchronize" : 127,//1111111
- "move-away" : 105,//1101001
- "move" : 77 //1001101
- };
-
- /**
- * Loops through parents of changed node to find the first
- * connected node. Based on the action it will change, remove
- * or update the representation of the data.
- *
- * @event xmlupdate Fires when xml of this element is updated.
- * object:
- * {String} action the action that was executed on the xml.
- * Possible values:
- * text a text node is set.
- * update an xml node is updated.
- * insert xml nodes are inserted.
- * add an xml node is added.
- * remove an xml node is removed (parent still set).
- * redo-remove an xml node is removed (parent not set).
- * synchronize unknown update.
- * move-away an xml node is moved (parent not set).
- * move an xml node is moved (parent still set).
- * {XMLElement} xmlNode the node that is subject to the update.
- * {Mixed} result the result.
- * {UndoObj} UndoObj the undo information.
- */
- this.$xmlUpdate = function(action, xmlNode, listenNode, UndoObj, lastParent){
- if (!this.xmlRoot)
- return; //@todo think about purging cache when xmlroot is removed
-
- var result, startNode = xmlNode, length;
- if (!listenNode)
- listenNode = this.xmlRoot;
-
- if (action == "redo-remove") {
- lastParent.appendChild(xmlNode); //ahum, i'm not proud of this one
- var traverseNode = this.isTraverseNode(xmlNode);
- lastParent.removeChild(xmlNode);
-
- if (!traverseNode)
- xmlNode = lastParent;
- }
-
- //Get First ParentNode connected
- do {
- if (action == "add" && this.isTraverseNode(xmlNode)
- && startNode == xmlNode)
- break; //@todo Might want to comment this out for adding nodes under a traversed node
-
- if (xmlNode.getAttribute(jpf.xmldb.xmlIdTag)) {
- var htmlNode = this.getNodeFromCache(
- xmlNode.getAttribute(jpf.xmldb.xmlIdTag)
- + "|" + this.uniqueId);
-
- if (htmlNode
- && (startNode != xmlNode || xmlNode == this.xmlRoot)
- && actionFeature[action] & 1)
- action = "update";
-
- if (xmlNode == listenNode) {
- if (xmlNode == this.xmlRoot && action != "insert")
- return;
- break;
- }
-
- if (htmlNode && actionFeature[action] & 2
- && !this.isTraverseNode(xmlNode))
- action = "remove"; //@todo why not break here?
-
- if (!htmlNode && actionFeature[action] & 4
- && this.isTraverseNode(xmlNode)){
- action = "add";
- break;
- }
-
- if (htmlNode || action == "move")
- break;
- }
- else if (actionFeature[action] & 8 && this.isTraverseNode(xmlNode)){
- action = "add";
- break;
- }
-
- if (xmlNode == listenNode) break;
- xmlNode = xmlNode.parentNode;
- }
- while(xmlNode && xmlNode.nodeType != 9);
-
- /**
- * @todo Think about not having this code here
- */
- if (this.hasFeature(__VIRTUALVIEWPORT__)) {
- if(!this.$isInViewport(xmlNode)) //xmlNode is a traversed node
- return;
- }
-
- //if(xmlNode == listenNode && !action.match(/add|synchronize|insert/))
- // return; //deleting nodes in parentData of object
-
- var foundNode = xmlNode;
- if (xmlNode && xmlNode.nodeType == 9)
- xmlNode = startNode;
-
- if (action == "replacechild"
- && (UndoObj ? UndoObj.args[0] == this.xmlRoot : !this.xmlRoot.parentNode)) {
- return this.load(UndoObj ? UndoObj.args[1] : listenNode); //Highly doubtfull this is exactly right...
- }
-
- //Action Tracker Support - && xmlNode correct here??? - UndoObj.xmlNode works but fishy....
- if (UndoObj && xmlNode && !UndoObj.xmlNode)
- UndoObj.xmlNode = xmlNode;
-
- //Check Move -- if value node isn't the node that was moved then only perform a normal update
- if (action == "move" && foundNode == startNode) {
- //if(!htmlNode) alert(xmlNode.getAttribute("id")+"|"+this.uniqueId);
- var isInThis = jpf.xmldb.isChildOf(this.xmlRoot, xmlNode.parentNode, true);
- var wasInThis = jpf.xmldb.isChildOf(this.xmlRoot, UndoObj.extra.parent, true);
-
- //Move if both previous and current position is within this object
- if (isInThis && wasInThis)
- this.$moveNode(xmlNode, htmlNode);
- else if (isInThis) //Add if only current position is within this object
- action = "add";
- else if (wasInThis) //Remove if only previous position is within this object
- action = "remove";
- }
- else if (action == "move-away") {
- var goesToThis = jpf.xmldb.isChildOf(this.xmlRoot, UndoObj.extra.parent, true);
- if (!goesToThis)
- action = "remove";
- }
-
- //Remove loading message
- if (this.$removeClearMessage && this.$setClearMessage) {
- if (this.getFirstTraverseNode())
- this.$removeClearMessage();
- else
- this.$setClearMessage(this.emptyMsg, "empty")
- }
-
- //Check Insert
- if (action == "insert" && (this.isTreeArch || xmlNode == this.xmlRoot)) {
- if (this.hasLoadStatus(xmlNode) && this.$removeLoading)
- this.$removeLoading(htmlNode);
-
- if (this.oInt.firstChild && !jpf.xmldb.getNode(this.oInt.firstChild)) {
- //Appearantly the content was cleared
- this.oInt.innerHTML = "";
-
- if (!this.renderRoot) {
- length = this.getTraverseNodes().length;
- if (!length)
- this.clearAllTraverse();
- }
- }
-
- result = this.$addNodes(xmlNode, (this.$getParentNode
- ? this.$getParentNode(htmlNode)
- : htmlNode), true, false);//this.isTreeArch??
-
- this.$fill(result);
-
- if (this.selectable && !this.xmlRoot.selectSingleNode(this.traverse))
- jpf.console.warn("No traversable nodes were found for "
- + this.name + " [" + this.tagName + "]\n\
- Traverse Rule : " + this.traverse);
-
- if (this.selectable && (length === 0 || !this.xmlRoot.selectSingleNode(this.traverse)))
- return;
- }
- else if (action == "add") {// || !htmlNode (Check Add)
- //var parentHTMLNode = this.getCacheItemByHtmlId(xmlNode.getAttribute(jpf.xmldb.xmlIdTag)+"|"+this.uniqueId);
- //xmlNode.parentNode == this.xmlRoot ? this.oInt :
- var parentHTMLNode = xmlNode.parentNode == this.xmlRoot
- ? this.oInt
- : this.getNodeFromCache(xmlNode.parentNode.getAttribute(
- jpf.xmldb.xmlIdTag) + "|" + this.uniqueId); //This code should use getTraverseParent()
-
- //this.getCacheItem(xmlNode.parentNode.getAttribute(jpf.xmldb.xmlIdTag))
-
- //This should be moved into a function (used in setCache as well)
- if (!parentHTMLNode)
- parentHTMLNode = this.getCacheItem(xmlNode.parentNode.getAttribute(jpf.xmldb.xmlIdTag)
- || (xmlNode.parentNode.getAttribute(jpf.xmldb.xmlDocTag)
- ? "doc" + xmlNode.parentNode.getAttribute(jpf.xmldb.xmlDocTag)
- : false))
- || this.oInt; //This code should use getTraverseParent()
-
- //Only update if node is in current representation or in cache
- if (parentHTMLNode || jpf.xmldb.isChildOf(this.xmlRoot, xmlNode)) {
- parentHTMLNode = (this.$findContainer && parentHTMLNode
- ? this.$findContainer(parentHTMLNode)
- : parentHTMLNode) || this.oInt;
-
- result = this.$addNodes(xmlNode, parentHTMLNode, true, true,
- this.getNodeByXml(this.getNextTraverse(xmlNode)));
-
- if (parentHTMLNode)
- this.$fill(result);
- }
- }
- else if ((action == "remove") && (!xmlNode || foundNode == xmlNode && xmlNode.parentNode)) { //Check Remove
- if (!xmlNode)
- return;
-
- //Remove HTML Node
- if (htmlNode)
- this.$deInitNode(xmlNode, htmlNode);
- else if (xmlNode == this.xmlRoot) {
- return this.load(null, null, null,
- !this.dataParent || !this.dataParent.autoselect);
- }
- }
- else if (htmlNode) {
- this.$updateNode(xmlNode, htmlNode);
-
- //Transaction 'niceties'
- if (action == "replacechild" && this.hasFeature(__MULTISELECT__)
- && this.selected && xmlNode.getAttribute(jpf.xmldb.xmlIdTag)
- == this.selected.getAttribute(jpf.xmldb.xmlIdTag)) {
- this.selected = xmlNode;
- }
-
- //if(action == "synchronize" && this.autoselect) this.reselect();
- }
- else if (action == "redo-remove") { //Check Remove of the data (some ancestor) that this component is bound on
- var testNode = this.xmlRoot;
- while (testNode && testNode.nodeType != 9)
- testNode = testNode.parentNode;
-
- if (!testNode) {
- //Set Component in listening state until data becomes available again.
- var model = this.getModel(true);
-
- if (!model)
- throw new Error(jpf.formatErrorString(0, this,
- "Setting change notifier on component",
- "Component without a model is listening for changes",
- this.$jml));
-
- return model.loadInJmlNode(this, model.getXpathByJmlNode(this));
- }
- }
-
- //For tree based nodes, update all the nodes up
- var pNode = xmlNode ? xmlNode.parentNode : lastParent;
- if (this.isTreeArch && pNode && pNode.nodeType == 1) {
- do {
- var htmlNode = this.getNodeFromCache(pNode.getAttribute(
- jpf.xmldb.xmlIdTag) + "|" + this.uniqueId);
-
- if (htmlNode)
- this.$updateNode(pNode, htmlNode);
- }
- while ((pNode = this.getTraverseParent(pNode)) && pNode.nodeType == 1);
- }
-
- //Make sure the selection doesn't become corrupted
- if (actionFeature[action] & 32 && this.selectable
- && startNode == xmlNode
- && (action != "insert" || xmlNode == this.xmlRoot)) {
-
- clearTimeout(selectTimer.timer);
- // Determine next selection
- if (action == "remove" && xmlNode == this.selected
- || xmlNode == selectTimer.nextNode)
- selectTimer.nextNode = this.getDefaultNext(xmlNode);
-
- //@todo Fix this by putting it after xmlUpdate when its using a timer
- selectTimer.timer = setTimeout(function(){
- _self.$checkSelection(selectTimer.nextNode);
- selectTimer.nextNode = null;
- });
- }
-
- //Set dynamic properties that relate to the changed content
- if (actionFeature[action] & 64) {
- if (!length)
- length = this.xmlRoot.selectNodes(this.traverse).length;
- if (length != this.length)
- this.setProperty("length", length);
- }
-
- //Let's signal components that are waiting for xml to appear (@todo what about clearing the signalXmlUpdate)
- if (this.signalXmlUpdate && actionFeature[action] & 16) {
- var uniqueId;
- for (uniqueId in this.signalXmlUpdate) {
- if (parseInt(uniqueId) != uniqueId) continue; //safari_old stuff
-
- var o = jpf.lookup(uniqueId);
- if (!this.selected) continue;
-
- var xmlNode = this.selected.selectSingleNode(o.dataParent.xpath);
- if (!xmlNode) continue;
-
- o.load(xmlNode);
- }
- }
-
- this.dispatchEvent("xmlupdate", {
- action : action,
- xmlNode: xmlNode,
- result : result,
- UndoObj: UndoObj
- });
- };
-
- /**
- * Loop through NodeList of selected Traverse Nodes
- * and check if it has representation. If it doesn't
- * representation is created via $add().
- */
- this.$addNodes = function(xmlNode, parent, checkChildren, isChild, insertBefore){
- if (!this.traverse) {
- throw new Error(jpf.formatErrorString(1060, this,
- "adding Nodes for load",
- "No traverse SmartBinding rule was specified. This rule is \
- required for a " + this.tagName + " component.", this.$jml));
- }
-
- var htmlNode, lastNode;
- isChild = (isChild && (this.renderRoot && xmlNode == this.xmlRoot
- || this.isTraverseNode(xmlNode)));
- var nodes = isChild ? [xmlNode] : this.getTraverseNodes(xmlNode);//.selectNodes(this.traverse);
- var loadChildren = nodes.length && (this.bindingRules || {})["insert"]
- ? this.applyRuleSetOnNode("insert", xmlNode)
- : false;
-
- for (var i = 0; i < nodes.length; i++) {
- if (nodes[i].nodeType != 1) continue;
-
- if (checkChildren)
- htmlNode = this.getNodeFromCache(nodes[i].getAttribute(jpf.xmldb.xmlIdTag)
- + "|" + this.uniqueId);
-
- if (!htmlNode) {
- //Retrieve DataBind ID
- var Lid = jpf.xmldb.nodeConnect(this.documentId, nodes[i], null, this);
-
- //Add Children
- var beforeNode = isChild ? insertBefore : (lastNode ? lastNode.nextSibling : null);//(parent || this.oInt).firstChild);
- var parentNode = this.$add(nodes[i], Lid, isChild ? xmlNode.parentNode : xmlNode,
- beforeNode ? parent || this.oInt : parent, beforeNode,
- !beforeNode && i==nodes.length-1);//Should use getTraverParent
-
- //Exit if component tells us its done with rendering
- if (parentNode === false) {
- //Tag all needed xmlNodes for future reference
- for (var i = i; i < nodes.length; i++)
- jpf.xmldb.nodeConnect(this.documentId, nodes[i],
- null, this);
- break;
- }
-
- //Parse Children Recursively -> optimize: don't check children that can't exist
- //if(this.isTreeArch) this.$addNodes(nodes[i], parentNode, checkChildren);
- }
-
- if (checkChildren)
- lastNode = htmlNode;// ? htmlNode.parentNode.parentNode : null;
- }
-
- return nodes;
- };
-
- //Trigger Databinding Connections
- this.addEventListener("beforeselect", function(e){
- var combinedvalue = null;
-
- if (this.indicator == this.selected || e.list && e.list.length > 1
- && this.getConnections().length) {
- //Multiselect databinding handling... [experimental]
- if (e.list && e.list.length > 1 && this.getConnections().length) {
- var oEl = this.xmlRoot.ownerDocument.createElement(this.selected.tagName);
- var attr = {};
-
- //Fill basic nodes
- var nodes = e.list[0].attributes;
- for (var j = 0; j < nodes.length; j++)
- attr[nodes[j].nodeName] = nodes[j].nodeValue;
-
- //Remove nodes
- for (var i = 1; i < e.list.length; i++) {
- for (prop in attr) {
- if (typeof attr[prop] != "string") continue;
-
- if (!e.list[i].getAttributeNode(prop))
- attr[prop] = undefined;
- else if(e.list[i].getAttribute(prop) != attr[prop])
- attr[prop] = "";
- }
- }
-
- //Set attributes
- for (prop in attr) {
- if (typeof attr[prop] != "string") continue;
- oEl.setAttribute(prop, attr[prop]);
- }
-
- //missing is childnodes... will implement later when needed...
-
- oEl.setAttribute(jpf.xmldb.xmlIdTag, this.uniqueId);
- jpf.MultiSelectServer.register(oEl.getAttribute(jpf.xmldb.xmlIdTag),
- oEl, e.list, this);
- jpf.xmldb.addNodeListener(oEl, jpf.MultiSelectServer);
-
- combinedvalue = oEl;
- }
- }
-
- this.$chained = true;
- if (!this.dataParent || !this.dataParent.parent.$chained) {
- var _self = this;
- setTimeout(function(){
- _self.setConnections(combinedvalue || _self.selected);
- delete _self.$chained;
- }, 10);
- }
- else {
- this.setConnections(combinedvalue || this.selected);
- delete this.$chained;
- }
- });
-
- this.addEventListener("afterdeselect", function(){
- var _self = this;
- setTimeout(function(){
- _self.setConnections(null);
- }, 10);
- });
-
- /**
- * @allowchild item, choices
- * @define item xml element which is rendered by this element.
- * @attribute {String} value the value that the element gets when this element is selected.
- * @attribute {String} icon the url to the icon used in the representation of this node.
- * @attribute {String} image the url to the image used in the representation of this node.
- * @allowchild [cdata], label
- * @define choices container for item nodes which receive presentation. This element is part of the XForms specification. It is not necesary for the javeline markup language.
- * @allowchild item
- */
- this.$loadInlineData = function(x){
- if (!$xmlns(x, "item", jpf.ns.jml).length)
- return jpf.JmlParser.parseChildren(x, null, this);
-
- var parent = x;
-
- if (x.getAttribute("model")) {
- throw new Error(jpf.formatErrorString(0, this,
- "Loading inline data",
- "Found model attribute set. This will conflict with loading\
- the inline data. Please remove it. If you would like to set\
- the model to receive the selection value, please set the \
- select-model attribute.", x));
- }
-
- var prefix = jpf.findPrefix(x, jpf.ns.jml);
-
- x.ownerDocument.setProperty("SelectionNamespaces", "xmlns:"
- + prefix + "='" + jpf.ns.jpf + "'");
-
- //@todo think about using setProperty for this, for consistency (at the price of speed)
- this.icon = "@icon";
- this.image = "@image";
- this.caption = "label/text()|text()|@caption";//|@value
- this.valuerule = "value/text()|@value|text()";
- this.traverse = prefix + ":item";
-
- this.load(x);
- };
-
- var timer;
- this.$handleBindingRule = function(value, f, prop){
- if (!value)
- this[prop] = null;
-
- if (this.xmlRoot && !timer && !jpf.isParsing) {
- timer = setTimeout(function(){
- _self.reload();
- timer = null;
- });
- }
- };
-
- /**
- * @attribute {String} traverse the xpath statement that determines which
- * xml data elements are rendered by this element. See
- * {@link baseclass.multiselectbinding.binding.traverse} for more information.
- * Example:
- * <code>
- * <j:label>Country</j:label>
- * <j:dropdown
- * model = "mdlCountries"
- * traverse = "country"
- * value = "@value"
- * caption = "text()">
- * </j:dropdown>
- *
- * <j:model id="mdlCountries">
- * <countries>
- * <country value="USA">USA</country>
- * <country value="GB">Great Brittain</country>
- * <country value="NL">The Netherlands</country>
- * ...
- * </countries>
- * </j:model>
- * </code>
- * @see baseclass.multiselectbinding.binding.traverse
- */
- this.$propHandlers["traverse"] =
-
- /**
- * @attribute {String} caption the xpath statement that determines from
- * which xml node the caption is retrieved.
- * Example:
- * <code>
- * <j:list caption="text()" traverse="item" />
- * </code>
- * @see binding.caption
- */
- this.$propHandlers["caption"] =
-
- /**
- * @attribute {String} valuerule the xpath statement that determines from
- * which xml node the value is retrieved.
- * Example:
- * <code>
- * <j:list valuerule="@value" traverse="item" />
- * </code>
- * @see binding.value
- */
- this.$propHandlers["valuerule"] =
-
- /**
- * @attribute {String} icon the xpath statement that determines from
- * which xml node the icon url is retrieved.
- * Example:
- * <code>
- * <j:list icon="@icon" traverse="item" />
- * </code>
- * @see binding.icon
- */
- this.$propHandlers["icon"] =
-
- /**
- * @attribute {String} tooltip the xpath statement that determines from
- * which xml node the tooltip text is retrieved.
- * Example:
- * <code>
- * <j:list tooltip="text()" traverse="item" />
- * </code>
- * @see binding.tooltip
- */
- this.$propHandlers["tooltip"] =
-
- /**
- * @attribute {String} select the xpath statement that determines whether
- * this node is selectable.
- * Example:
- * <code>
- * <j:list select="self::node()[not(@disabled='1')]" traverse="item" />
- * </code>
- * @see binding.select
- */
- this.$propHandlers["select"] = this.$handleBindingRule;
-};
-
- - -/*FILEHEAD(/var/lib/jpf/src/core/node/virtualviewport.js)SIZE(-1077090856)TIME(1238933673)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-var __VIRTUALVIEWPORT__ = 1 << 19;
-
-
-/**
- * Baseclass adding Virtual Viewport features to this Element.
- *
- * @experimental This code has never been run.
- * @constructor
- * @baseclass
- * @private
- *
- * @author Ruben Daniels & Mike de Boer
- * @version %I%, %G%
- * @since 1.0
- */
-jpf.VirtualViewport = function(){
- this.$regbase = this.$regbase | __VIRTUALVIEWPORT__;
-
- jpf.setStyleClass(this.oExt, "virtual");
-
- this.$deInitNode = function(xmlNode, htmlNode){
- /*
- Not the htmlNode is deleted, but the viewport is rerendered from this node on.
- If viewport is too high either the render starting point is adjusted and
- a complete rerender is requested, or the last empty elements are hidden
- */
- this.viewport.redraw();//very unoptimized
- };
-
- this.$moveNode = function(xmlNode, htmlNode){
- /*
- Do a remove when removed from current viewport
- Do an add when moved to current viewport
- Do a redraw from the first of either when both in viewport
- */
- this.viewport.redraw();//very unoptimized
- };
-
- this.emptyNode = jpf.xmldb.getXml("<empty />");
- this.$addEmpty = this.$add;
- this.$add = function(xmlNode, Lid, xmlParentNode, htmlParentNode, beforeNode){
- //find new slot
- var htmlNode = this.$findNode(null, Lid);
-
- if(!htmlNode)
- return;
-
- //execute update
- this.$updateNode(xmlNode, htmlNode);//, noModifier);
- };
-
- this.$fill = function(){
-
- };
-
- this.clear = function(nomsg, do_event){
- if (this.clearSelection)
- this.clearSelection(null, !do_event);
-
- if (!nomsg)
- this.$setClearMessage(this.emptyMsg);
- else if(this.$removeClearMessage)
- this.$removeClearMessage();
-
- this.documentId = this.xmlRoot = this.cacheID = null;
-
- this.viewport.cache = [];
- this.viewport.prepare();
- this.viewport.cache = null;
- };
-
- var _self = this;
- this.viewport = {
- offset : 0,
- limit : 15,
- length : 0,
- sb : new jpf.scrollbar(this.pHtmlNode),
- cache : null,
-
- inited : false,
- draw : function(){
- this.inited = true;
- var limit = this.limit; this.limit = 0;
- this.resize(limit, true);
- },
-
- redraw : function(){
- this.change(this.offset);
- },
-
- // set id's of xml to the viewport
- prepare : function(){
- if (!this.inited)
- this.draw();
-
- var nodes = _self.getTraverseNodes();
- if (!nodes)
- return;
-
- var docId = jpf.xmldb.getXmlDocId(_self.xmlRoot);
- var hNodes = _self.oInt.childNodes;
- for (var j = 0, i = 0; i < hNodes.length; i++) {
- if (hNodes[i].nodeType != 1) continue;
-
- hNodes[i].style.display = j >= nodes.length ? "none" : "block"; //Will ruin tables & lists
-
- jpf.xmldb.nodeConnect(docId, nodes[j], hNodes[i], _self);
- j++;
- }
- },
-
- /**
- * @note This function only supports single dimension items (also no grid, like thumbnails)
- */
- resize : function(limit, updateScrollbar){
- this.cache = null;
-
- //Viewport shrinks
- if (limit < this.limit) {
- var nodes = _self.oInt.childNodes;
- for (var i = 0; i < nodes.length; i++) {
- if (nodes[i].nodeType != 1) continue;
- _self.oInt.removeChild(nodes[i]);
- if(--this.limit == limit) break;
- }
- }
- //Viewport grows
- else if (limit > this.limit) {
- for (var i = this.limit; i < limit; i++) {
- _self.$addEmpty(_self.emptyNode, "", _self.xmlRoot, _self.oInt);
- }
- }
- else return;
-
- this.limit = limit;
-
- if (updateScrollbar)
- this.sb.update();
- },
-
-
- /**
- * @todo This method should be optimized by checking if there is
- * overlap between the new offset and the old one
- */
- change : function(offset, limit, updateScrollbar){
- this.cache = null;
- var diff = offset - this.offset;
- var oldLimit = this.limit;
- if (diff*diff >= this.limit*this.limit) //there is no overlap
- diff = 0;
- this.offset = offset;
-
- if (diff > 0) { //get last node before resize
- var lastNode = _self.oInt.lastChild;
- if (lastNode.nodeType != 1) lastNode = lastNode.previousSibling;
- }
-
- if (limit && this.limit != limit)
- this.resize(limit, updateScrollbar);
- else if (updateScrollbar)
- this.sb.update();
-
- //this.viewport.prepare();
-
- //Traverse through XMLTree
- //var nodes = this.$addNodes(this.xmlRoot, this.oInt, null, this.renderRoot);
- var nodes = _self.getTraverseNodes();
- if (!nodes)
- return;
-
- var docId = jpf.xmldb.getXmlDocId(_self.xmlRoot);
- var hNodes = _self.oInt.childNodes;
-
- //remove nodes from the beginning
- if (diff > 0) {
- var xmlNode, htmlNode, xmlPos = oldLimit - diff, len = hNodes.length;
- for (var j = 0, i = 0; j < diff && i < len; i++) {
- htmlNode = _self.oInt.firstChild;
- if (htmlNode.nodeType == 1) {
- j++;
- xmlNode = nodes[xmlPos++];
- //htmlNode.style.display = j >= nodes.length ? "none" : "block"
- jpf.xmldb.nodeConnect(docId, xmlNode, htmlNode, _self);
- _self.$updateNode(xmlNode, htmlNode);//, noModifier);
- }
-
- _self.oInt.appendChild(htmlNode);
- }
-
- //var lastNode = nodes[oldLimit - diff - 1]
- }
- //remove nodes from the end
- else if (diff < 0) {
- diff = diff * -1;
- var xmlNode, htmlNode, xmlPos = 0; //should be adjusted for changing limit
- for (var j = 0, i = hNodes.length-1; j < diff && i >= 0; i++) {
- htmlNode = _self.oInt.lastChild;
- if (htmlNode.nodeType == 1) {
- j++;
- xmlNode = nodes[xmlPos++];
- //htmlNode.style.display = j >= nodes.length ? "none" : "block"
- jpf.xmldb.nodeConnect(docId, xmlNode, htmlNode, _self);
- _self.$updateNode(xmlNode, htmlNode);//, noModifier);
- }
-
- _self.oInt.insertBefore(htmlNode, _self.oInt.firstChild);
- }
- }
- //Recalc all nodes
- else {
- var xmlNode, htmlNode, len = hNodes.length;
- for (var j = 0, i = 0; i < len; i++) {
- htmlNode = hNodes[i];
- if (htmlNode.nodeType == 1) {
- xmlNode = nodes[j++];
- jpf.xmldb.nodeConnect(docId, xmlNode, htmlNode, _self);
- _self.$updateNode(xmlNode, htmlNode);//, noModifier);
- }
- }
- }
-
- //Build HTML
- //_self.$fill(nodes);
-
- /*if (_self.$selected) {
- _self.$deselect(_self.$selected);
- _self.$selected = null;
- }
-
- if (_self.selected && _self.$isInViewport(_self.selected))
- _self.select(_self.selected);*/
- }
- };
-
- var timer;
- this.viewport.sb.realtime = false;//!jpf.isIE;
- this.viewport.sb.attach(this.oInt, this.viewport, function(timed, pos){
- var vp = _self.viewport;
-
- if (vp.sb.realtime || !timed)
- vp.change(Math.round((vp.length - vp.limit) * pos), vp.limit, false);
- else {
- clearTimeout(timer);
- timer = setTimeout(function(){
- vp.change(Math.round((vp.length - vp.limit) * pos), vp.limit, false);
- }, 300);
- }
- })
-
- this.$isInViewport = function(xmlNode, struct){
- var marker = xmlNode.selectSingleNode("preceding-sibling::j_marker");
- var start = marker ? marker.getAttribute("end") : 0;
-
- if(!struct && this.viewport.offset + this.viewport.limit < start + 1)
- return false;
-
- var position = start;
- var nodes = (marker || xmlNode).selectNodes("following-sibling::"
- + this.traverse.split("|").join("following-sibling::"));
-
- for (var i = 0; i < nodes.length; i++) {
- ++position;
- if (nodes[i] == xmlNode)
- break;
- }
-
- if(struct) struct.position = position;
-
- if(this.viewport.offset > position
- || this.viewport.offset + this.viewport.limit < position)
- return false;
-
- return true;
- };
-
- this.scrollTo = function(xmlNode, last){
- var sPos = {};
- this.$isInViewport(xmlNode, sPos);
- this.viewport.change(sPos.position + (last ? this.viewport.limit-1 : 0));
- };
-
- /**
- * @todo this one should be optimized
- */
- this.getFirstTraverseNode = function(xmlNode){
- return this.getTraverseNodes(xmlNode)[0];
- };
-
- var xmlUpdate = this.$xmlUpdate;
- this.$xmlUpdate = function(){
- this.viewport.cache = null;
- this.viewport.length = this.xmlRoot.selectNodes(this.traverse).length; //@todo fix this for virtual length
- this.viewport.sb.update();
- xmlUpdate.apply(this, arguments);
- };
-
- this.$load = function(XMLRoot){
- //Add listener to XMLRoot Node
- jpf.xmldb.addNodeListener(XMLRoot, this);
-
- //Reserve here a set of nodeConnect id's and add them to our initial marker
- //Init virtual dataset here
-
- if (!this.renderRoot && !this.getTraverseNodes(XMLRoot).length)
- return this.clearAllTraverse(this.loadingMsg);
-
- //Initialize virtual dataset if load rule exists
- if (this.bindingRules["load"])
- jpf.xmldb.createVirtualDataset(XMLRoot);
-
- //Prepare viewport
- this.viewport.cache = null;
- this.viewport.length = this.xmlRoot.selectNodes(this.traverse).length; //@todo fix this for virtual length
- this.viewport.sb.update();
- this.viewport.prepare();
-
- //Traverse through XMLTree
- var nodes = this.$addNodes(XMLRoot, null, null, this.renderRoot);
-
- //Build HTML
- //this.$fill(nodes);
-
- //Select First Child
- if (this.selectable) {
- if (this.autoselect) {
- if (nodes.length)
- this.$selectDefault(XMLRoot);
- else
- this.setConnections();
- }
- else {
- this.clearSelection(null, true);
- var xmlNode = this.getFirstTraverseNode(); //should this be moved to the clearSelection function?
- if (xmlNode)
- this.setIndicator(xmlNode);
- this.setConnections(null, "both");
- }
- }
-
- if (this.$focussable)
- jpf.window.hasFocus(this) ? this.$focus() : this.$blur();
- };
-
- this.$loadSubData = function(){}; //We use the same process for subloading, it shouldn't be done twice
-
- /**
- * @example <j:load get="call:getCategory(start, length, ascending)" total="@total" />
- */
- this.$loadPartialData = function(marker, start, length){
- //We should have a queing system here, disabled the check for now
- //if (this.hasLoadStatus(xmlRootNode)) return;
-
- var loadNode, rule = this.getNodeFromRule("load", xmlRootNode, false, true);
- var sel = (rule && rule.getAttribute("select"))
- ? rule.getAttribute("select")
- : ".";
-
- if (rule && (loadNode = xmlRootNode.selectSingleNode(sel))) {
- this.setLoadStatus(xmlRootNode, "loading");
-
- var mdl = this.getModel(true);
- if (!mdl)
- throw new Error("Could not find model");
-
- if (!rule.getAttribute("total")) {
- throw new Error(jpf.formatErrorString(this, "Loading data", "Error in load rule. Missing total xpath. Expecting <j:load total='xpath' />"))
- }
-
- mdl.insertFrom(rule.getAttribute("get"), loadNode, {
- documentId : this.documentId, //or should xmldb find this itself
- marker : marker,
- start : start,
- length : length,
- insertPoint : this.xmlRoot,
- jmlNode : this
- ,ascending : this.$sort ? this.$sort.get().ascending : true
- },
- function(xmlNode){
- _self.setConnections(_self.xmlRoot);
-
- var length = parseInt(jpf.getXmlValue(xmlNode,
- rule.getAttribute("total")));
-
- if (_self.viewport.length != length) {
- _self.viewport.length = length;
-
- jpf.xmldb.createVirtualDataset(_self.xmlRoot,
- _self.viewport.length, _self.documentId);
- }
- });
- }
- };
-
- //Consider moving these functions to the xmldatabase selectByXpath(xpath, from, length);
- function fillList(len, list, from){
- for (var i = 0; i < len; i++)
- list.push(_self.documentId + "|" + (from+i));
- }
-
- function buildList(markers, markerId, distance, xml) {
- var vlen = this.viewport.limit;
- var marker, nodes, start, list = [];
-
- //Count from 0
- if (markerId == -1) {
- nodes = xml.selectNodes(_self.traverse);
- start = 0;
- marker = markers[0];
- markerid = 0;
- }
- else {
- //Count back from end of marker
- if (distance < 0) {
- fillList(Math.abs(distance), list,
- parseInt(marker.getAttribute("reserved")) + parseInt(marker.getAttribute("end"))
- - parseInt(marker.getAttribute("start")) + distance);
-
- distance = 0;
- _self.$loadPartialData(marker);
-
- if (list.length == vlen)
- return list;
- }
-
- nodes = markers[markerId].selectNodes("following-sibling::"
- + this.traverse.split("|").join("following-sibling::"));
- start = markers[markerId].getAttribute("end");
- marker = markers[++markerId];
- }
-
- do {
- //Add found nodes
- var loop = Math.min(marker.getAttribute("start") - start, vlen);//, nodes.length
- for (var i = distance; i < loop; i++)
- list.push(nodes[i]);
-
- if (list.length == vlen)
- break;
-
- //Add empty nodes
- var mlen = parseInt(marker.getAttribute("end")) - parseInt(marker.getAttribute("start"));
- fillList(Math.min(mlen, vlen - list.length), list, parseInt(marker.getAttribute("reserved")));
-
- //Add code here to trigger download of this missing info
- _self.$loadPartialData(marker);
-
- start = parseInt(marker.getAttribute("end"));
- marker = markers[++markerId];
- distance = 0;
- }
- while (list.length < vlen && marker);
-
- _self.viewport.cache = list;
- return list;
- }
-
- this.getTraverseNodes = function(xmlNode){
- if (!this.xmlRoot)
- return;
-
- if (this.viewport.cache)
- return this.viewport.cache;
-
- var start = this.viewport.offset;
- var end = start + this.viewport.limit + 1;
-
- //caching statement here
-
- var markers = (xmlNode || this.xmlRoot).selectNodes("j_marker");
-
- //Special case for fully loaded virtual dataset
- if (!markers.length) {
- var list = (xmlNode || this.xmlRoot).selectNodes("("
- + this.traverse + ")[position() >= " + start
- + " and position() < " + (end) + "]");
-
- return this.$sort ? this.$sort.apply(list) : list;
- }
-
- for (var i = 0; i < markers.length; i++) {
- //Looking for marker that (partially) exceeds viewport's current position
- if (markers[i].getAttribute("end") < start) {
- //If this is the last marker, count from here
- if (i == markers.length - 1)
- return buildList(markers, i, start - markers[i].getAttribute("end"),
- (xmlNode || this.xmlRoot));
-
- continue;
- }
-
- //There is overlap AND begin is IN marker
- if (markers[i].getAttribute("start") - end <= 0
- && start >= markers[i].getAttribute("start"))
- return buildList(markers, i, start - markers[i].getAttribute("end"),
- (xmlNode || this.xmlRoot));
-
- //Marker is after viewport, there is no overlap
- else if (markers[i-1]) //Lets check the previous marker, if there is one
- return buildList(markers, i-1, start - markers[i-1].getAttribute("end"),
- (xmlNode || this.xmlRoot));
-
- //We have to count from the beginning
- else
- return buildList(markers, -1, start, (xmlNode || this.xmlRoot));
- }
- };
-
- this.addEventListener("keydown", function(e){
- var key = e.keyCode;
- var ctrlKey = e.ctrlKey;
- var shiftKey = e.shiftKey;
-
- if (!this.indicator) return;
-
- function selScroll(xmlNode, down){
- if(!_self.$isInViewport(xmlNode))
- _self.scrollTo(xmlNode, down);
-
- if (ctrlKey)
- _self.setIndicator(xmlNode);
- else
- _self.select(xmlNode, null, shiftKey);
- }
-
- switch (key) {
- case 13:
- this.choose(this.$selected);
- break;
- case 32:
- this.select(this.indicator, true);
- break;
- case 46:
- //DELETE
- if(this.disableremove) return;
-
- this.remove(null, true);
- break;
- case 38:
- //UP
- var node = this.getNextTraverseSelected(this.indicator
- || this.selected, false, items);
-
- if (node) selScroll(node);
- break;
- case 40:
- //DOWN
- var node = this.getNextTraverseSelected(this.indicator
- || this.selected, true, items);
-
- if (node) selScroll(node, true);
- break;
- case 33:
- //PGUP
- var node = this.getNextTraverseSelected(this.indicator
- || this.selected, false, this.viewport.limit);
-
- if (!node)
- node = this.getFirstTraverseNode();
-
- if (node) selScroll(node);
- break;
- case 34:
- //PGDN
- var node = this.getNextTraverseSelected(this.indicator
- || this.selected, true, this.nodeCount-1);
-
- if (!node)
- node = this.getLastTraverseNode();
-
- if (node) selScroll(node, true);
- break;
- case 36:
- //HOME
- var node = this.getFirstTraverseNode();
- if (node) selScroll(node);
- break;
- case 35:
- //END
- var node = this.getLastTraverseNode();
- if (node) selScroll(node);
- break;
- default:
- /*if (key == 65 && ctrlKey) {
- this.selectAll();
- }
- else if(this.bindingRules["caption"]){
- //this should move to a onkeypress based function
- if(!this.lookup || new Date().getTime()
- - this.lookup.date.getTime() > 300)
- this.lookup = {
- str : "",
- date : new Date()
- };
-
- this.lookup.str += String.fromCharCode(key);
-
- var nodes = this.getTraverseNodes();
- for (var i = 0; i < nodes.length; i++) {
- if(this.applyRuleSetOnNode("caption", nodes[i])
- .substr(0, this.lookup.str.length).toUpperCase()
- == this.lookup.str) {
- this.scrollTo(nodes[i], true);
- this.select(nodes[i]);
- return;
- }
- }
-
- return;
- }*/
- break;
- };
-
- //this.lookup = null;
- return false;
- }, true);
-
-
- //Init
- this.caching = false; //for now, because the implications are unknown
-};
- - -/*FILEHEAD(/var/lib/jpf/src/core/node/presentation.js)SIZE(-1077090856)TIME(1238944816)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - -var __PRESENTATION__ = 1 << 9; - - -/** - * @private - * @define skin - * @allowchild style, presentation - * @attribute src - */ -jpf.skins = { - skins : {}, - css : [], - events : ["onmousemove", "onmousedown", "onmouseup", "onmouseout", - "onclick", "ondragmove", "ondragstart"], - - /* *********** - Init - ************/ - Init: function(xmlNode, refNode, path){ - /* - get data from refNode || xmlNode - - name - - icon-path - - media-path - - all paths of the xmlNode are relative to the src attribute of refNode - all paths of the refNode are relative to the index.html - images/ is replaced if there is a refNode to the relative path from index to the skin + /images/ - */ - var name = (refNode ? refNode.getAttribute("id") : null) - || xmlNode.getAttribute("id"); - var base = (refNode ? refNode.getAttribute("src").match(/\//) || path : "") - ? (path || refNode.getAttribute("src")).replace(/\/[^\/]*$/, "") + "/" - : ""; - var mediaPath = (xmlNode.getAttribute("media-path") - ? jpf.getAbsolutePath(base || jpf.hostPath, xmlNode.getAttribute("media-path")) - : (refNode ? refNode.getAttribute("media-path") : null)); - var iconPath = (xmlNode.getAttribute("icon-path") - ? jpf.getAbsolutePath(base || jpf.hostPath, xmlNode.getAttribute("icon-path")) - : (refNode ? refNode.getAttribute("icon-path") : null)); - if (!name) - name = "default"; - - if (xmlNode.getAttribute("id")) - document.body.className += " " + xmlNode.getAttribute("id"); - - if (!this.skins[name] || name == "default") { - this.skins[name] = { - base : base, - name : name, - iconPath : (iconPath === null) ? "icons/" : iconPath, - mediaPath: (mediaPath === null) ? "images/" : mediaPath, - templates: {}, - originals: {}, - xml : xmlNode - } - } - if (!this.skins["default"]) - this.skins["default"] = this.skins[name]; - - var nodes = xmlNode.childNodes; - for (var i = nodes.length - 1; i >= 0; i--) { - if (nodes[i].nodeType != 1) - continue; - - //this.templates[nodes[i].tagName] = nodes[i]; - this.skins[name].templates[nodes[i].getAttribute("name")] = nodes[i]; - if (nodes[i].ownerDocument) - this.importSkinDef(nodes[i], base, name); - } - - this.purgeCss(mediaPath || base + "images/", iconPath || base + "icons/"); - }, - - /** - * This method loads a stylesheet from a url - * @param {String} filename Required The url to load the stylesheet from - * @param {String} title Optional Title of the stylesheet to load - * @method - */ - loadStylesheet: function(filename, title){ - with (o = document.getElementsByTagName("head")[0].appendChild(document.createElement("LINK"))) { - rel = "stylesheet"; - type = "text/css"; - href = filename; - title = title; - } - - return o; - }, - - /* *********** - Import - ************/ - importSkinDef: function(xmlNode, basepath, name){ - var i, l, nodes = $xmlns(xmlNode, "style", jpf.ns.jml), tnode, node; - for (i = 0, l = nodes.length; i < l; i++) { - node = nodes[i]; - - if (node.getAttribute("src")) - this.loadStylesheet(node.getAttribute("src").replace(/src/, basepath + "/src")); - else { - var test = true; - if (node.getAttribute("condition")) { - try { - test = eval(node.getAttribute("condition")); - } - catch (e) { - test = false; - } - } - - if (test) { - //#-ifndef __PROCESSED - tnode = node.firstChild; - while (tnode) { - this.css.push(tnode.nodeValue); - tnode = tnode.nextSibling; - } - /*#-else - this.css.push(nodes[i].firstChild.nodeValue); - #-endif*/ - } - } - } - - nodes = $xmlns(xmlNode, "alias", jpf.ns.jpf); - for (i = 0; i < nodes.length; i++) { - if (!nodes[i].firstChild) - continue; - this.skins[name].templates[nodes[i].firstChild.nodeValue.toLowerCase()] = xmlNode; - } - }, - - loadedCss : "", - purgeCss: function(imagepath, iconpath){ - if (!this.css.length) - return; - - var cssString = this.css.join("\n").replace(/images\//g, imagepath).replace(/icons\//g, iconpath); - jpf.importCssString(document, cssString); - - this.loadedCss += cssString; - - this.css = []; - }, - - loadCssInWindow : function(skinName, win, imagepath, iconpath){ - this.css = []; - var name = skinName.split(":"); - var skin = this.skins[name[0]]; - var template = skin.templates[name[1]]; - this.importSkinDef(template, skin.base, skin.name); - var cssString = this.css.join("\n").replace(/images\//g, imagepath).replace(/icons\//g, iconpath); - jpf.importCssString(win.document, cssString); - - this.css = []; - }, - - /* *********** - Retrieve - ************/ - setSkinPaths: function(skinName, jmlNode){ - skinName = skinName.split(":"); - var name = skinName[0]; - var type = skinName[1]; - - if (!this.skins[name]) { - throw new Error(jpf.formatErrorString(1076, null, - "Retrieving Skin", - "Could not find skin '" + name + "'", jmlNode.$jml)); - } - - jmlNode.iconPath = this.skins[name].iconPath; - jmlNode.mediaPath = this.skins[name].mediaPath; - }, - - getTemplate: function(skinName, cJml){ - skinName = skinName.split(":"); - var name = skinName[0]; - var type = skinName[1]; - - if (!this.skins[name]) { - throw new Error(jpf.formatErrorString(1077, null, - "Retrieving Template", - "Could not find skin '" + name + "'", cJml)); - } - - if (!this.skins[name].templates[type]) - return false; - - var skin = this.skins[name].templates[type]; - var originals = this.skins[name].originals[type]; - if (!originals) { - originals = this.skins[name].originals[type] = {}; - - if (!$xmlns(skin, "presentation", jpf.ns.jml)[0]) { - throw new Error(jpf.formatErrorString(1078, null, - "Retrieving Template", - "Missing presentation tag in '" + name + "'", cJml)); - } - - var nodes = $xmlns(skin, "presentation", jpf.ns.jml)[0].childNodes; - for (var i = 0; i < nodes.length; i++) { - if (nodes[i].nodeType != 1) continue; - originals[nodes[i].baseName || nodes[i][jpf.TAGNAME]] = nodes[i]; - } - } - - /*for (var item in originals) { - pNodes[item] = originals[item]; - }*/ - - return originals; - }, - - getCssString : function(skinName){ - return jpf.getXmlValue($xmlns(this.skins[skinName.split(":")[0]].xml, - "style", jpf.ns.jml)[0], "text()"); - }, - - changeSkinset : function(value){ - var node = jpf.document.documentElement; - while (node) { - if (node && node.nodeFunc == jpf.NODE_VISIBLE - && node.hasFeature(__PRESENTATION__) && !node.skinset) { - node.$propHandlers["skinset"].call(node, value);//$forceSkinChange - node.skinset = null; - } - - //Walk tree - if (node.firstChild || node.nextSibling) { - node = node.firstChild || node.nextSibling; - } - else { - do { - node = node.parentNode; - } while (node && !node.nextSibling) - - if (node) - node = node.nextSibling; - } - } - }, - - iconMaps : {}, - addIconMap : function(options){ - this.iconMaps[options.name] = options; - if (options.size) - options.width = options.height = options.size; - else { - if (!options.width) - options.width = 1; - if (!options.height) - options.height = 1; - } - }, - - setIcon : function(oHtml, strQuery, iconPath){ - if (!strQuery) { - oHtml.style.backgroundImage = ""; - return; - } - - if (oHtml.tagName.toLowerCase() == "img") { - oHtml.setAttribute("src", strQuery - ? (iconPath || "") + strQuery - : ""); - return; - } - - var parts = strQuery.split(":"); - var map = this.iconMaps[parts[0]]; - - if (map) { - var left, top, coords = parts[1].split(","); - if (map.type == "vertical") { - left = (coords[1] || 0) * map.width; - top = (coords[0] || 0) * map.height; - } - else { - left = (coords[0] || 0) * map.width; - top = (coords[1] || 0) * map.height; - } - - oHtml.style.backgroundImage = "url(" + (iconPath || "") - + map.src + ")"; - oHtml.style.backgroundPosition = ((-1 * left) - map.offset[0]) - + "px " + ((-1 * top) - map.offset[1]) + "px"; - } - else - - //Assuming image url - { - //@todo check here if it is really a url - - oHtml.style.backgroundImage = "url(" + (iconPath || "") - + strQuery + ")"; - } - } -}; - -/** - * Baseclass adding skinning features to this element. A skin is a description - * of how the element is rendered. In the web browser this is done using html - * elements and css. - * Remarks: - * The skin is set using the skin attribute. The skin of each element can be - * changed at run time. Other than just changing the look of an element, a skin - * change can help the user to perceive information in a different way. For - * example a list element has a default skin, but can also use the thumbnail - * skin to display thumbnails of the data elements. - * - * A skin for an element is always build up out of a standard set of parts. - * <code> - * <j:textbox name="textbox"> - * <j:alias> - * ... - * </j:alias> - * <j:style><![CDATA[ - * ... - * ]]></j:style> - * - * <j:presentation> - * <j:main> - * ... - * </j:main> - * ... - * </j:presentation> - * </j:textbox> - * </code> - * The alias contains a name that contains alternative names for the skin. The - * style tags contain the css. The main tag contains the html elements that are - * created when the component is created. Any other skin items are used to render - * other elements of the widget. In this reference guide you will find these - * skin items described on the pages of each widget. - * - * @constructor - * @baseclass - * @author Ruben Daniels - * @version %I%, %G% - * @since 0.5 - */ -jpf.Presentation = function(){ - var pNodes, originalNodes; - - this.$regbase = this.$regbase | __PRESENTATION__; - this.skinName = null; - var _self = this; - var skinTimer; - - /**** Properties and Attributes ****/ - - this.$supportedProperties.push("skin"); - /** - * @attribute {string} skinset Specifies the skinset where the skin for - * this element is found. If none is specified the skinset attribute - * of <j:appsettings /> is used. When not defined the default skinset - * is accessed. - * Example: - * <code> - * <j:list skinset="perspex" /> - * </code> - */ - this.$propHandlers["skinset"] = - - /** - * @attribute {string} skin Specifies the skin that defines the rendering - * of this element. When a skin is changed the full state of the - * element is kept including it's selection, all the - * jml attributes, loaded data, focus and disabled state. - * Example: - * <code> - * <j:list id="lstExample" skin="thumbnails" /> - * </code> - * Example: - * <code> - * lstExample.setAttribute("skin", "list"); - * </code> - */ - this.$propHandlers["skin"] = function(value){ - if (!this.$jmlLoaded) //If we didn't load a skin yet, this will be done when we attach to a parent - return; - - if (!skinTimer) { - clearTimeout(skinTimer); - skinTimer = setTimeout(function(){ - changeSkin.call(_self); - skinTimer = null; - }); - } - } - - /** - * @attribute {String} style css style properties applied to the this element. - */ - this.$propHandlers["style"] = function(value){ - if (!jpf.isParsing) - this.oExt.setAttribute("style", value); - } - - var oldClass; - /** - * @attribute {String} class css style class applied to the this element. - */ - this.$propHandlers["class"] = function(value){ - this.$setStyleClass(this.oExt, value, [oldClass || ""]) - } - - this.$forceSkinChange = function(skin, skinset){ - changeSkin.call(this, skin, skinset); - } - - function changeSkin(skin, skinset){ - clearTimeout(skinTimer); - - var skinName = (skinset || this.skinset || jpf.appsettings.skinset) - + ":" + (skin || this.skin || this.tagName); - - //Store selection - if (this.selectable) - var valueList = this.getSelection();//valueList; - - //Store needed state information - var oExt = this.oExt; - var beforeNode = oExt.nextSibling; - var id = this.oExt.getAttribute("id"); - var oldBase = this.baseCSSname; - - if (oExt.parentNode) - oExt.parentNode.removeChild(oExt); - - //@todo changing skin will leak A LOT, should call $destroy here, with some extra magic - if (this.$destroy) - this.$destroy(true); - - //Load the new skin - this.$loadSkin(skinName); - - //Draw - this.$draw(); - - if (id) - this.oExt.setAttribute("id", id); - - if (beforeNode) - this.oExt.parentNode.insertBefore(this.oExt, beforeNode); - - //Copy classes - var i, l, newclasses = [], - classes = (oExt.className || "").splitSafe("\s+"); - for (i = 0; i < classes; i++) { - if (classes[i] && classes[i] != oldBase) - newclasses.push(classes[i].replace(oldBase, this.baseCSSname)); - } - jpf.setStyleClass(this.oExt, newclasses.join(" ")); - - //Copy events - var en, ev = jpf.skins.events; - for (i = 0, l = ev.length; i < l; i++) { - en = ev[i]; - if (typeof oExt[en] == "function" && !this.oExt[en]) - this.oExt[en] = oExt[en]; - } - - //Copy css state (dunno if this is best) - this.oExt.style.left = oExt.style.left; - this.oExt.style.top = oExt.style.top; - this.oExt.style.width = oExt.style.width; - this.oExt.style.height = oExt.style.height; - this.oExt.style.right = oExt.style.right; - this.oExt.style.bottom = oExt.style.bottom; - this.oExt.style.zIndex = oExt.style.zIndex; - this.oExt.style.position = oExt.style.position; - this.oExt.style.display = oExt.style.display; - - //Widget specific - if (this.$loadJml) - this.$loadJml(this.$jml); - - //DragDrop - if (this.hasFeature(__DRAGDROP__)) { - if (document.elementFromPointAdd) { - document.elementFromPointRemove(oExt); - document.elementFromPointAdd(this.oExt); - } - } - - //Check disabled state - if (this.disabled) - this.$disable(); - - //Check focussed state - if (this.$focussable && jpf.window.focussed == this) - this.$focus(); - - //Reload data - if (this.hasFeature(__DATABINDING__) && this.xmlRoot) - this.reload(); - else - if (this.value) - this.$propHandlers["value"].call(this, this.value); - - //Set Selection - if (this.hasFeature(__MULTISELECT__)) { - if (this.selectable) - this.selectList(valueList, true); - } - - if (this.hasFeature(__ALIGNMENT__)) { - if (this.aData) - this.aData.oHtml = this.oExt; - - if (this.pData) { - this.pData.oHtml = this.oExt; - this.pData.pHtml = this.oInt; - - var nodes = this.pData.childNodes; - for (i = 0; i < nodes.length; i++) { - nodes[i].pHtml = this.oInt; //Should this be recursive?? - } - } - } - - if (this.draggable) - this.$propHandlers["draggable"].call(this, this.draggable); - if (this.resizable) - this.$propHandlers["resizable"].call(this, this.resizable); - - if (this.$skinchange) - this.$skinchange(); - - //Dispatch event - //this.dispatchEvent("skinchange"); - }; - - /**** Private methods ****/ - - this.$setStyleClass = jpf.setStyleClass; - - /** - * Initializes the skin for this element when none has been set up. - * - * @param {String} skinName required Identifier for the new skin (for example: 'default:List' or 'win'). - */ - this.$loadSkin = function(skinName){ - this.baseSkin = skinName || this.skinName || (this.skinset || this.$jml - && this.$jml.getAttribute("skinset") || jpf.appsettings.skinset) - + ":" + (this.skin || this.$jml - && this.$jml.getAttribute("skin") || this.tagName); - - if (this.skinName) { - this.$blur(); - this.baseCSSname = null; - } - - this.skinName = this.baseSkin; //Why?? - - pNodes = {}; //reset the pNodes collection - originalNodes = jpf.skins.getTemplate(this.skinName, this.$jml); - - if (!originalNodes) { - this.baseName = this.skinName = "default:" + this.tagName; - originalNodes = jpf.skins.getTemplate(this.skinName, this.$jml); - - if (!originalNodes) { - throw new Error(jpf.formatErrorString(1077, this, - "Presentation", - "Could not load skin: " + this.skinName, this.$jml)); - } - } - - if (originalNodes) - jpf.skins.setSkinPaths(this.skinName, this); - }; - - this.$getNewContext = function(type, jmlNode){ - if (type != type.toLowerCase()) { - throw new Error("Invalid layout node name ('" + type + "'). lowercase required"); - } - - if (!originalNodes[type]) { - throw new Error(jpf.formatErrorString(0, this, - "Getting new skin item", - "Missing node in skin description '" + type + "'")); - } - - pNodes[type] = originalNodes[type].cloneNode(true); - }; - - this.$hasLayoutNode = function(type){ - if (type != type.toLowerCase()) { - throw new Error("Invalid layout node name ('" + type + "'). lowercase required"); - } - - return originalNodes[type] ? true : false; - }; - - this.$getLayoutNode = function(type, section, htmlNode){ - if (type != type.toLowerCase()) { - throw new Error("Invalid layout node name ('" + type + "'). lowercase required"); - } - - var node = pNodes[type] || originalNodes[type]; - if (!node) { - if (!this.$dcache) - this.$dcache = {} - - if (!this.$dcache[type + "." + this.skinName]) { - this.$dcache[type + "." + this.skinName] = true; - jpf.console.info("Could not find node '" + type - + "' in '" + this.skinName + "'", "skin"); - } - return false; - } - - if (!section) - return jpf.getFirstElement(node); - - var textNode = node.selectSingleNode("@" + section); - if (!textNode) { - if (!this.$dcache) - this.$dcache = {} - - if (!this.$dcache[section + "." + this.skinName]) { - this.$dcache[section + "." + this.skinName] = true; - jpf.console.info("Could not find textnode '" + section - + "' in '" + this.skinName + "'", "skin"); - } - return null; - } - - return (htmlNode - ? jpf.xmldb.selectSingleNode(textNode.nodeValue, htmlNode) - : jpf.getFirstElement(node).selectSingleNode(textNode.nodeValue)); - }; - - this.$getOption = function(type, section){ - type = type.toLowerCase(); //HACK: lowercasing should be solved in the comps. - - //var node = pNodes[type]; - var node = pNodes[type] || originalNodes[type]; - if (!section) - return node;//jpf.getFirstElement(node); - var option = node.selectSingleNode("@" + section); - - return option ? option.nodeValue : ""; - }; - - this.$getExternal = function(tag, pNode, func, jml){ - if (!pNode) - pNode = this.pHtmlNode; - if (!tag) - tag = "main"; - if (!jml) - jml = this.$jml; - - tag = tag.toLowerCase(); //HACK: make components case-insensitive - - this.$getNewContext(tag); - var oExt = this.$getLayoutNode(tag); - if (jml && jml.getAttributeNode("style")) - oExt.setAttribute("style", jml.getAttribute("style")); - - if (jml && (jml.getAttributeNode("class") || jml.className)) { - this.$setStyleClass(oExt, - (oldClass = jml.getAttribute("class") || jml.className)); - } - - if (func) - func.call(this, oExt); - - oExt = jpf.xmldb.htmlImport(oExt, pNode); - oExt.host = this; - if (jml && jml.getAttribute("bgimage")) - oExt.style.backgroundImage = "url(" + jpf.getAbsolutePath( - this.mediaPath, jml.getAttribute("bgimage")) + ")"; - - - if (!this.baseCSSname) - this.baseCSSname = oExt.className.trim().split(" ")[0]; - - return oExt; - }; - - /**** Focus ****/ - this.$focus = function(){ - if (!this.oExt) - return; - - this.$setStyleClass(this.oFocus || this.oExt, this.baseCSSname + "Focus"); - }; - - this.$blur = function(){ - if (this.renaming) - this.stopRename(null, true); - - if (!this.oExt) - return; - - this.$setStyleClass(this.oFocus || this.oExt, "", [this.baseCSSname + "Focus"]); - }; - - if (jpf.hasCssUpdateScrollbarBug) { - this.$fixScrollBug = function(){ - if (this.oInt != this.oExt) - this.oFocus = this.oInt; - else { - this.oFocus = - this.oInt = - this.oExt.appendChild(document.createElement("div")); - - this.oInt.style.height = "100%"; - } - }; - } - - /**** Selection ****/ - if (this.hasFeature(__MULTISELECT__)) { - this.$select = function(o){ - if (this.renaming) - this.stopRename(null, true); - - if (!o || !o.style) - return; - return this.$setStyleClass(o, "selected"); - }; - - this.$deselect = function(o){ - if (this.renaming) { - this.stopRename(null, true); - - if (this.ctrlselect) - return false; - } - - if (!o) - return; - return this.$setStyleClass(o, "", ["selected", "indicate"]); - }; - - this.$indicate = function(o){ - if (this.renaming) - this.stopRename(null, true); - - if (!o) - return; - return this.$setStyleClass(o, "indicate"); - }; - - this.$deindicate = function(o){ - if (this.renaming) - this.stopRename(null, true); - - if (!o) - return; - return this.$setStyleClass(o, "", ["indicate"]); - }; - } - - /**** Caching ****/ - /* - this.$setClearMessage = function(msg){}; - this.$updateClearMessage = function(){} - this.$removeClearMessage = function(){};*/ -}; - - - -/*FILEHEAD(/var/lib/jpf/src/core/node/alignment.js)SIZE(-1077090856)TIME(1238944816)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-var __ALIGNMENT__ = 1 << 12;
-
-
-/**
- * Baseclass adding Alignment features to this Element. The element can be
- * alignment to each side of it's parent's rectangle. Multiple elements can
- * be aligned to the same side. These are then stacked. Layouts created using
- * alignment, with or without vbox/hbox elements can be stored in an external
- * xml format. These can then be loaded and saved for later use. Using this
- * technique it's possible to offer a layout manager to your users from within
- * your application. This layout manager could then allow the user to choose
- * from layouts and save new ones.
- * Example:
- * An Outlook like layout in JML
- * <code>
- * <j:toolbar align = "top-1" height = "40" />
- * <j:tree align = "left-splitter" width = "20%" />
- * <j:datagrid align = "right-splitter" height = "50%" />
- * <j:text align = "right" />
- * <j:statusbar align = "bottom-2" height = "20" />
- * </code>
- * Remarks:
- * This is one of three positioning methods.
- * See {@link element.grid}
- * See {@link baseclass.anchoring}
- *
- * @constructor
- * @baseclass
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.4
- */
-jpf.Alignment = function(){
- this.$regbase = this.$regbase | __ALIGNMENT__;
-
- var l = jpf.layout;
-
- /**
- * @attribute {Boolean} docking whether this element can function as a dockable section of the layout.
- */
- this.dock = false;
- this.dockable = false;
- this.$booleanProperties["dock"] = true;
- this.$booleanProperties["dockable"] = true;
- this.$supportedProperties.push("dock", "dockable");
-
- this.$propHandlers["width"] =
- this.$propHandlers["height"] = function(value){};
-
- /**** DOM Hooks ****/
- this.$domHandlers["remove"].push(remove);
- this.$domHandlers["reparent"].push(reparent);
-
- this.$hide = function(){
- this.oExt.style.display = "block";
- this.aData.prehide();
- this.purgeAlignment();
- };
-
- this.$show = function(){
- if (this.aData.preshow() !== false)
- this.oExt.style.display = "none";
- this.purgeAlignment();
- };
-
- /**
- * Turns the alignment features off.
- * @param {Boolean} [purge] whether alignment is recalculated right after setting the property.
- */
- //var lastPosition, jmlNode = this;
- this.disableAlignment = function(purge){
- if (!this.aData) return;
-
- remove.call(this);
- };
-
- /**
- * Turns the alignment features on.
- *
- */
- this.enableAlignment = function(purge){
- var buildParent = "vbox|hbox".indexOf(this.parentNode.tagName) == -1
- && !this.parentNode.pData;
-
- var layout = l.get(this.pHtmlNode, buildParent
- ? jpf.getBox(this.parentNode.margin || this.pHtmlNode.getAttribute("margin") || "")
- : null);
-
- if (buildParent) {
- this.parentNode.pData = l.parseXml(
- this.parentNode.$jml || jpf.getXml("<vbox />"),
- layout, "vbox", true);
-
- layout.root = this.parentNode.pData;
- }
-
- if (!this.aData)
- this.aData = l.parseXml(this.$jml, layout, this, true); //not recur?
-
- if (this.align || this.$jml.getAttribute("align")) {
- l.addAlignNode(this, layout.root);
-
- if (this.aData.hidden || this.$jml.getAttribute("visible") == "false")
- this.aData.prehide(true);
-
- if (!jpf.isParsing || jpf.parsingFinalPass) //buildParent &&
- this.purgeAlignment();
- }
- else
- {
- var pData = this.parentNode.aData || this.parentNode.pData;
- this.aData.stackId = pData.children.push(this.aData) - 1;
- this.aData.parent = pData;
- }
- };
-
- /**
- * Calculate the rules for this element and activates them.
- *
- */
- this.purgeAlignment = function(){
- var layout = l.get(this.pHtmlNode);
- l.queue(this.pHtmlNode, null, layout.root);
- };
-
- function remove(doOnlyAdmin){
- if (doOnlyAdmin)
- return;
-
- if (this.aData) {
- this.aData.remove();
- this.purgeAlignment();
-
- if (this.parentNode.pData && !this.parentNode.pData.children.length) {
- l.removeAll(this.parentNode.pData);
- this.parentNode.pData = null;
- }
-
- this.oExt.style.display = "none";
- }
- }
-
- //@todo support inserbefore for align templates
- function reparent(beforeNode, pNode, withinParent, oldParent){
- if (!this.$jmlLoaded)
- return;
-
- if (!withinParent && this.aData) {
- this.aData.pHtml = this.pHtmlNode;
- //this.aData = null;
- this.enableAlignment();
- }
- }
-
- //@todo problem with determining when aData.parent | also with weight and minwidth
- this.$addJmlLoader(function(){
- /**
- * @attribute {String} align the edge of the parent to which this element aligns. Possible values are a combination of: "left", "middle", "right", "top", "bottom" and "slider" and optionally a size.
- * Example:
- * <j:tree align="left-splitter-3" />
- * @attribute {String} lean the position of element when it is ambiguous.
- * Possible values:
- * right the element leans towards the right
- * bottom the element leans towards the bottom
- * @attribute {Number} edge the size of the edge of the space between this and the neighbour element to the right or top. If this attribute is smaller than the splitter attribute, the edge is the size of the splitter.
- * @attribute {Number} weight the factor (between 0 and 1) this element takes when no width is specified. The factor is calculated by doing (weight/totalweight) * space available in parent. Based on the parent being a vbox or hbox this attribute calculates either the element's width or height.
- * @attribute {Number} splitter the size of splitter in between this and the neighbour element to the right or top. When not specified the splitter is not displayed.
- * @attribute {Number} minwidth the minimal horizontal size of this element.
- * @attribute {Number} minheight the minimal vertical size of this element.
- */
- this.$supportedProperties.push("align", "lean", "edge", "weight",
- "splitter", "width", "height", "minwidth", "minheight");
-
- this.$propHandlers["align"] = function(value){
- this.aData.remove();
- this.aData.template = value;
- this.splitter = undefined;
- this.aData.edgeMargin = this.edge || 0;
- this.enableAlignment();
- };
-
- this.$propHandlers["lean"] = function(value){
- this.aData.isBottom = (value || "").indexOf("bottom") > -1;
- this.aData.isRight = (value || "").indexOf("right") > -1;
- this.purgeAlignment();
- };
-
- this.$propHandlers["edge"] = function(value){
- this.aData.edgeMargin = Math.max(this.aData.splitter || 0, value != "splitter" ? value : 0);
- this.aData.splitter = value == "splitter" ? 5 : false;
- this.purgeAlignment();
- };
-
- this.$propHandlers["weight"] = function(value){
- this.aData.weight = parseFloat(value);
- this.purgeAlignment();
- };
-
- this.$propHandlers["splitter"] = function(value){
- this.aData.splitter = value ? 5 : false;
- this.aData.edgeMargin = Math.max(this.aData.splitter || 0, this.edge || 0);
-
- if (!value && this.align && this.align.indexOf("-splitter"))
- this.align = this.aData.template = this.align.replace("-splitter", "");
-
- this.purgeAlignment();
- };
-
- this.$propHandlers["width"] = function(value){
- this.width = null; //resetting this property because else we can't reset, when we have a fast JIT we'll do setProperty in onresize
- this.aData.fwidth = value || false;
-
- if (this.aData.fwidth && this.aData.fwidth.indexOf("/") > -1) {
- this.aData.fwidth = eval(this.aData.fwidth);
- if (this.aData.fwidth <= 1)
- this.aData.fwidth = (this.aData.fwidth * 100) + "%";
- }
-
- this.purgeAlignment();
- };
-
- this.$propHandlers["height"] = function(value){
- this.height = null; //resetting this property because else we can't reset, when we have a fast JIT we'll do setProperty in onresize
- this.aData.fheight = String(value) || false;
-
- if (this.aData.fheight && this.aData.fheight.indexOf("/") > -1) {
- this.aData.fheight = eval(this.aData.fheight);
- if (this.aData.fheight <= 1)
- this.aData.fheight = (this.aData.fheight * 100) + "%";
- }
-
- this.purgeAlignment();
- };
-
- this.$propHandlers["minwidth"] = function(value){
- this.aData.minwidth = value;
- this.purgeAlignment();
- };
-
- this.$propHandlers["minheight"] = function(value){
- this.aData.minheight = value;
- this.purgeAlignment();
- };
- });
-
- this.$jmlDestroyers.push(function(){
- this.disableAlignment();
- });
-};
- - -/*FILEHEAD(/var/lib/jpf/src/core/node/validation.js)SIZE(-1077090856)TIME(1238950355)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - -var __VALIDATION__ = 1 << 6; - - -/** - * Baseclass adding validation to this element. - * Example: - * <code> - * <j:bar validgroup="vgExample"> - * <j:label>Number</j:label> - * <j:textbox required="true" min="3" max="10" invalidmsg="Invalid Entry;Please enter a number between 3 and 10" /> - * <j:label>Name</j:label> - * <j:textbox required="true" invalidmsg="Invalid Entry;Please enter your name" minlength="3" /> - * <j:label>Message</j:label> - * <j:textarea required="true" invalidmsg="Invalid Message;Please enter a message!" /> - * <j:button onclick="if(vgExample.isValid()) alert('valid!')">Validate</j:button> - * </j:bar> - * </code> - * - * @event invalid Fires when this component goes into an invalid state. - * - * @constructor - * @baseclass - * @author Ruben Daniels - * @version %I%, %G% - * @since 0.5 - */ -jpf.Validation = function(){ - this.isActive = true; - this.$regbase = this.$regbase | __VALIDATION__; - - /** - * Checks if this element's value is valid. - * - * @param {Boolean} [checkRequired] whether this check also adheres to the 'required' ruled. - * @return {Boolean} specifying whether the value is valid - * @see baseclass.validationgroup - * @see element.submitform - */ - this.isValid = function(checkRequired){ - var value = this.getValue(); - - if (checkRequired && this.required) { - if (!value || value.toString().trim().length == 0) { - this.validityState.$reset(); - this.validityState.valueMissing = true; - this.dispatchEvent("invalid", this.validityState); - - return false; - } - } - - this.validityState.$reset(); - var isValid = true; - if (value) { - for (var type in vIds) { - if (!eval(vRules[vIds[type]])) { - this.validityState.$set(type); - isValid = false; - } - } - } - - - if (!isValid) - this.dispatchEvent("invalid", this.validityState); - else { - this.validityState.valid = true; - isValid = true; - } - - return isValid; - }; - - this.validityState = { - valueMissing : false, - typeMismatch : false, - patternMismatch : false, - tooLong : false, - rangeUnderflow : false, - rangeOverflow : false, - stepMismatch : false, - customError : false, - valid : false, - - "$reset" : function(){ - for (var prop in this) { - if (prop.substr(0,1) == "$") return; - this[prop] = false; - } - }, - - "$set" : function(type) { - switch (type) { - case "min" : this.rangeUnderflow = true; break; - case "max" : this.rangeOverflow = true; break; - case "minlength" : this.tooShort = true; break; - case "maxlength" : this.tooLong = true; break; - case "pattern" : this.patternMismatch = true; break; - case "datatype" : this.typeMismatch = true; break; - case "notnull" : this.typeMismatch = true; break; - case "checkequal" : this.typeMismatch = true; break; - } - } - } - - this.setCustomValidity = function(message){ - //do stuff - } - - /** - * @private - * @todo This method should also scroll the element into view - */ - this.showMe = function(){ - var p = this.parentNode; - while (p) { - if (p.show) - p.show(); - p = p.parentNode; - } - }; - - /** - * Puts this element in the error state, optionally showing the - * error box if this element's is invalid. - * - * @param {Boolean} [ignoreReq] whether this element required check is turned on. - * @param {Boolean} [nosetError] whether the error box is displayed if this component does not validate. - * @param {Boolean} [force] whether this element in the error state and don't check if the element's value is invalid. - * @return {Boolean} boolean specifying whether the value is valid - * @see object.validationgroup - * @see element.submitform - * @method - */ - this.checkValidity = - this.validate = function(ignoreReq, nosetError, force){ - //if (!this.$validgroup) return this.isValid(); - - if (force || !this.isValid(!ignoreReq) && !nosetError) { - this.setError(); - return false; - } - else { - this.clearError(); - return true; - } - }; - - /** - * @private - */ - this.setError = function(value){ - if (!this.$validgroup) - this.$propHandlers["validgroup"].call(this, "vg" + this.parentNode.uniqueId); - - var errBox = this.$validgroup.getErrorBox(this); - - if (!this.$validgroup.allowMultipleErrors) - this.$validgroup.hideAllErrors(); - - errBox.setMessage(this.invalidmsg); - - jpf.setStyleClass(this.oExt, this.baseCSSname + "Error"); - this.showMe(); //@todo scroll refHtml into view - - errBox.display(this); - - if (this.hasFeature(__MULTISELECT__) && this.validityState.errorXml) - this.select(this.validityState.errorXml); - - if (jpf.window.focussed && jpf.window.focussed != this) - this.focus(null, {mouse:true}); //arguable... - }; - - /** - * @private - */ - this.clearError = function(value){ - if (this.$setStyleClass) - this.$setStyleClass(this.oExt, "", [this.baseCSSname + "Error"]); - - if (this.$validgroup) { - var errBox = this.$validgroup.getErrorBox(null, true); - if (!errBox || errBox.host != this) - return; - - errBox.hide(); - } - }; - - this.$jmlDestroyers.push(function(){ - if (this.$validgroup) - this.$validgroup.remove(this); - }); - - var vRules = ["true"]; - var vIds = {}; - /** - * Adds a string of javascript that validates this element. - */ - this.addValidationRule = function(rule){ - vRules.push(rule); - }; - - /** - * - * @attribute {Boolean} required whether a valid value for this element is required. - * @attribute {RegExp} pattern the pattern tested against the value of this element to determine it's validity. - * @attribute {String} datatype the datatype that the value of this element should adhere to. This can be any - * of a set of predefined types, or a simple type created by an XML Schema definition. - * Possible values: - * xsd:dateTime - * xsd:time - * xsd:date - * xsd:gYearMonth - * xsd:gYear - * xsd:gMonthDay - * xsd:gDay - * xsd:gMonth - * xsd:string - * xsd:boolean - * xsd:base64Binary - * xsd:hexBinary - * xsd:float - * xsd:decimal - * xsd:double - * xsd:anyURI - * xsd:integer - * xsd:nonPositiveInteger - * xsd:negativeInteger - * xsd:long - * xsd:int - * xsd:short - * xsd:byte - * xsd:nonNegativeInteger - * xsd:unsignedLong - * xsd:unsignedInt - * xsd:unsignedShort - * xsd:unsignedByte - * xsd:positiveInteger - * jpf:url - * jpf:website - * jpf:email - * jpf:creditcard - * jpf:expdate - * jpf:wechars - * jpf:phonenumber - * jpf:faxnumber - * jpf:mobile - * @attribute {Integer} min the minimal value for which the value of this element is valid. - * @attribute {Integer} max the maximum value for which the value of this element is valid. - * @attribute {Integer} minlength the minimal length allowed for the value of this element. - * @attribute {Integer} maxlength the maximum length allowed for the value of this element. - * @attribute {Boolean} notnull same as {@link baseclass.validation.attribute.required} but this rule is checked realtime when the element looses the focus, instead of at specific request (for instance when leaving a form page). - * @attribute {String} checkequal String specifying the id of the element to check if it has the same value as this element. - * @attribute {String} invalidmsg String specifying the message displayed when this element has an invalid value. Use a ; character to seperate the title from the message. - * @attribute {String} validgroup String specifying the identifier for a group of items to be validated at the same time. This identifier can be new. It is inherited from a JML node upwards. - */ - this.$addJmlLoader(function(x){ - //this.addEventListener(this.hasFeature(__MULTISELECT__) ? "onafterselect" : "onafterchange", onafterchange); - /* Temp disabled, because I don't understand it (RLD) - this.addEventListener("beforechange", function(){ - if (this.xmlRoot && jpf.xmldb.getBoundValue(this) === this.getValue()) - return false; - });*/ - - // Submitform - if (!this.form) { - //Set Form - var y = this.$jml; - do { - y = y.parentNode; - } - while (y && y.tagName && !y.tagName.match(/submitform|xforms$/) - && y.parentNode && y.parentNode.nodeType != 9); - - if (y && y.tagName && y.tagName.match(/submitform|xforms$/)) { - if (!y.tagName.match(/submitform|xforms$/)) - throw new Error(jpf.formatErrorString(1070, this, this.tagName, "Could not find Form element whilst trying to bind to it's Data.")); - if (!y.getAttribute("id")) - throw new Error(jpf.formatErrorString(1071, this, this.tagName, "Found Form element but the id attribute is empty or missing.")); - - this.form = eval(y.getAttribute("id")); - this.form.addInput(this); - } - } - - // validgroup - if (!this.form && !x.getAttribute("validgroup")) { - var vgroup = jpf.xmldb.getInheritedAttribute(x, "validgroup"); - if (vgroup) - this.$propHandlers["validgroup"].call(this, vgroup); - } - }); - - this.$booleanProperties["required"] = true; - this.$supportedProperties.push("validgroup", "required", "datatype", - "pattern", "min", "max", "maxlength", "minlength", "valid-test", - "notnull", "checkequal", "invalidmsg", "requiredmsg"); - - this.$fValidate = function(){ this.validate(true); }; - this.addEventListener("blur", this.$fValidate); - - this.$propHandlers["validgroup"] = function(value){ - //this.removeEventListener("blur", this.$fValidate); - if (value) { - var vgroup; - if (typeof value != "string") { - this.$validgroup = value.name; - vgroup = value; - } - else { - vgroup = jpf.nameserver.get("validgroup", value); - } - - this.$validgroup = vgroup || new jpf.ValidationGroup(value); - this.$validgroup.add(this); - - /* - @todo What about children, when created after start - See button login action - */ - } - else { - this.$validgroup.remove(this); - this.$validgroup = null; - } - }; - - this.$setRule = function(type, rule){ - var vId = vIds[type]; - - if (!rule) { - if (vId) - vRules[vId] = ""; - return; - } - - if (!vId) - vIds[type] = vRules.push(rule) - 1; - else - vRules[vId] = rule; - } - - this.$propHandlers["datatype"] = function(value){ - if (!value) - return this.$setRule("datatype"); - - this.$setRule("datatype", this.multiselect - ? "this.xmlRoot && jpf.XSDParser.checkType('" - + value + "', this.getTraverseNodes())" - : "jpf.XSDParser.matchType(value, '" + value + "')"); - //this.xmlRoot && jpf.XSDParser.checkType('" + value + "', this.xmlRoot) || !this.xmlRoot && - }; - - this.$propHandlers["pattern"] = function(value){ - if (!value) - return this.$setRule("pattern"); - - if (value.match(/^\/.*\/(?:[gim]+)?$/)) - this.reValidation = eval(value); - - this.$setRule("pattern", this.reValidation - ? "value.match(this.reValidation)" //RegExp - : "(" + value + ")"); //JavaScript - }; - - this.$propHandlers["min"] = function(value){ - this.$setRule("min", value - ? "parseInt(value) >= " + value - : null); - }; - - this.$propHandlers["max"] = function(value){ - this.$setRule("max", value - ? "parseInt(value) <= " + value - : null); - }; - - this.$propHandlers["maxlength"] = function(value){ - this.$setRule("maxlength", value - ? "value.toString().length <= " + value - : null); - }; - - this.$propHandlers["minlength"] = function(value){ - this.$setRule("minlength", value - ? "value.toString().length >= " + value - : null); - }; - - this.$propHandlers["notnull"] = function(value){ - this.$setRule("notnull", value - ? "value.toString().length > 0" - : null); - }; - - this.$propHandlers["checkequal"] = function(value){ - if (!this.required) - this.required = 2; - else if (!value && this.required == 2) - this.required = false; - - this.$setRule("checkequal", value - ? "!" + value + ".isValid() || " + value + ".getValue() == value" - : null); - }; - - this.$propHandlers["valid-test"] = function(value){ - var _self = this, rvCache = {}; - /** - * Removes the validation cache created by the valid-test rule. - */ - this.removeValidationCache = function(){ - rvCache = {}; - } - - this.$checkRemoteValidation = function(){ - var value = this.getValue(); - if(typeof rvCache[value] == "boolean") return rvCache[value]; - if(rvCache[value] == -1) return true; - rvCache[value] = -1; - - var instr = this.$jml.getAttribute('valid-test').split("=="); - jpf.getData(instr[0], this.xmlRoot, { - value : this.getValue() - }, function(data, state, extra){ - if (state != jpf.SUCCESS) { - if (state == jpf.TIMEOUT && extra.retries < jpf.maxHttpRetries) - return extra.tpModule.retry(extra.id); - else { - var commError = new Error(jpf.formatErrorString(0, _self, - "Validating entry at remote source", - "Communication error: \n\n" + extra.message)); - - if (_self.dispatchEvent("error", jpf.extend({ - error : commError, - state : status - }, extra)) !== false) - throw commError; - return; - } - } - - rvCache[value] = instr[1] ? data == instr[1] : jpf.isTrue(data); - - if(!rvCache[value]){ - if (!_self.hasFocus()) - _self.setError(); - } - else _self.clearError(); - }); - - return true; - } - - this.$setRule("valid-test", value - ? "this.$checkRemoteValidation()" - : null); - }; -}; - -/** - * Object allowing for a set of JML elements to be validated. an element that goes into an error state will - * show the errorbox. - * <code> - * <j:bar validgroup="vgForm"> - * <j:label>Phone number</j:label> - * <j:textbox id="txtPhone" - * required = "true" - * pattern = "(\d{3}) \d{4} \d{4}" - * invalidmsg = "Incorrect phone number entered" /> - * - * <j:label>Password</j:label> - * <j:textbox - * required = "true" - * mask = "password" - * minlength = "4" - * invalidmsg = "Please enter a password of at least four characters" /> - * </j:bar> - * </code> - * - * To check if the element has valid information entered, leaving the textbox - * (focussing another element) will trigger a check. Programmatically a check - * can be done using the following code: - * <code> - * txtPhone.validate(); - * - * //Or use the html5 syntax - * txtPhone.checkValidity(); - * </code> - * - * To check for the entire group of elements use the validation group. For only - * the first non-valid element the errorbox is shown. That element also receives - * focus. - * <code> - * vgForm.validate(); - * </code> - * - * @event validation Fires when the validation group isn't validated. - * - * @constructor - * - * @author Ruben Daniels - * @version %I%, %G% - * @since 0.9 - */ -jpf.ValidationGroup = function(name){ - jpf.makeClass(this); - - /** - * When set to true only visible elements are validated. Default is false. - * @type Boolean - */ - this.validateVisibleOnly = false; - - /** - * When set to true validation doesnt stop at the first invalid element. Default is false. - * @type Boolean - */ - this.allowMultipleErrors = false; - - this.childNodes = []; - this.add = function(o){ this.childNodes.push(o); }; - this.remove = function(o){ this.childNodes.remove(o); }; - - if (name) - jpf.setReference(name, this); - - this.name = name || "validgroup" + this.uniqueId; - jpf.nameserver.register("validgroup", this.name, this); - - /** - * Returns a string representation of this object. - */ - this.toString = function(){ - return "[Javeline Validation Group]"; - }; - - var errbox; //@todo think about making this global jpf.ValidationGroup.errbox - /** - * Gets the {@link element.errorbox} element used for a specified element. - * - * @param {JmlNode} o required JmlNode specifying the element for which the Errorbox should be found. If none is found, an Errobox is created. Use the {@link object.validationgroup.property.allowMultipleErrors} property to influence when Errorboxes are created. - * @param {Boolean} no_create - * @return {Errorbox} the found or created Errorbox; - */ - this.getErrorBox = function(o, no_create){ - if (this.allowMultipleErrors || !errbox && !no_create) { - errbox = new jpf.errorbox(null, "errorbox"); - errbox.pHtmlNode = o.oExt.parentNode; - var cNode = o.$jml.ownerDocument.createElement("errorbox"); - errbox.loadJml(cNode); - } - return errbox; - }; - - /** - * Hide all Errorboxes for the elements using this element as it's validation group. - * - */ - this.hideAllErrors = function(){ - if (errbox && errbox.host) - errbox.host.clearError(); - }; - - function checkValidChildren(oParent, ignoreReq, nosetError){ - var found; - //Per Element - for (var v, i = 0; i < oParent.childNodes.length; i++) { - var oEl = oParent.childNodes[i]; - - if (!oEl) - continue; - if (!oEl.disabled - && (!this.validateVisibleOnly && oEl.visible || !oEl.oExt || oEl.oExt.offsetHeight) - && (oEl.hasFeature(__VALIDATION__) && oEl.isValid && !oEl.isValid(!ignoreReq))) { - //|| !ignoreReq && oEl.required && (!(v = oEl.getValue()) || new String(v).trim().length == 0) - - if (!nosetError) { - if (!found) { - oEl.validate(true, null, true); - found = true; - if (!this.allowMultipleErrors) - return true; //Added (again) - } - else if (oEl.errBox && oEl.errBox.host == oEl) - oEl.errBox.hide(); - } - else if (!this.allowMultipleErrors) - return true; - } - if (oEl.canHaveChildren && oEl.childNodes.length) { - found = checkValidChildren.call(this, oEl, ignoreReq, nosetError) || found; - if (found && !this.allowMultipleErrors) - return true; //Added (again) - } - } - return found; - } - - /** - * Checks if (part of) the set of element's registered to this element are - * valid. When an element is found with an invalid value the error state can - * be set for that element. - * - * @param {Boolean} [ignoreReq] whether to adhere to the 'required' check. - * @param {Boolean} [nosetError whether to not set the error state of the element with an invalid value - * @param {JMLElement} [page] the page for which the children will be checked. When not specified all elements of this validation group will be checked. - * @return {Boolean} specifying whether the checked elements are valid. - * @method isValid, validate, checkValidity - */ - this.checkValidity = - this.validate = - this.isValid = function(ignoreReq, nosetError, page){ - var found = checkValidChildren.call(this, page || this, ignoreReq, - nosetError); - - if (page) { - try { - if (page.validation && !eval(page.validation)) { - alert(page.invalidmsg); - found = true; - } - } catch(e) { - throw new Error(jpf.formatErrorString(0, this, - "Validating Page", - "Error in javascript validation string of page: '" - + page.validation + "'", page.$jml)); - } - } - - //Global Rules - // - if (!found) - found = this.dispatchEvent("validation"); - - return !found; - }; -}; - - - -/*FILEHEAD(/var/lib/jpf/src/core/node/cache.js)SIZE(-1077090856)TIME(1239018215)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-var __CACHE__ = 1 << 2;
-
-
-/**
- * Baseclass adding caching features to databound elements. It takes care of
- * storing, retrieving and updating rendered data (in html form)
- * to overcome the waiting time while rendering the contents every time the
- * data is loaded.
- *
- * @constructor
- * @baseclass
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.4
- */
-jpf.Cache = function(){
- /* ********************************************************************
- PROPERTIES
- *********************************************************************/
- var cache = {};
- var subTreeCacheContext;
-
- this.caching = true;
- this.$regbase = this.$regbase | __CACHE__;
-
- /* ********************************************************************
- PUBLIC METHODS
- *********************************************************************/
-
- /**
- * Checks the cache for a cached item by ID. If the ID is found the
- * representation is loaded from cache and set active.
- *
- * @param {String} id the id of the cache element which is looked up.
- * @param {Object} xmlNode
- * @return {Boolean}
- * Possible values:
- * true the cache element is found and set active
- * false otherwise
- * @see baseclass.databinding.method.load
- */
- this.getCache = function(id, xmlNode){
- //Checking Current
- if (id == this.cacheID) return -1;
- /*
- Let's check if the requested source is actually
- a sub tree of an already rendered part
- */
- if (xmlNode && this.hasFeature(__MULTISELECT__)) {
- var cacheItem = this.getCacheItemByHtmlId(
- xmlNode.getAttribute(jpf.xmldb.xmlIdTag) + "|" + this.uniqueId);
- if (cacheItem && !cache[id]) {
- /*
- Ok so it is, let's borrow it for a while
- We can't clone it, because the updates will
- get ambiguous, so we have to put it back later
- */
- this.clear(true);
-
- var oHtml = this.getNodeFromCache(
- xmlNode.getAttribute(jpf.xmldb.xmlIdTag) + "|" + this.uniqueId);
- subTreeCacheContext = {
- oHtml : oHtml,
- parentNode : oHtml.parentNode,
- beforeNode : oHtml.nextSibling,
- cacheItem : cacheItem
- };
-
- this.documentId = jpf.xmldb.getXmlDocId(xmlNode);
- this.cacheID = id;
- this.xmlRoot = xmlNode;
-
- //Load html
- if (this.renderRoot)
- this.oInt.appendChild(oHtml);
- else {
- while (oHtml.childNodes.length)
- this.oInt.appendChild(oHtml.childNodes[0]);
- }
-
- return true;
- }
- }
-
- //Checking Cache...
- if (!cache[id]) return false;
-
- //Removing previous
- if (this.cacheID)
- this.clear(true);
-
- //Get Fragment and clear Cache Item
- var fragment = cache[id];
-
- this.documentId = fragment.documentId;
- this.cacheID = id;
- this.xmlRoot = fragment.xmlRoot;
-
- this.clearCacheItem(id);
-
- this.$setCurrentFragment(fragment);
-
- return true;
- };
-
- /**
- * Sets cache element and it's ID
- *
- * @param {String} id the id of the cache element to be stored.
- * @param {DocumentFragment} fragment the data to be stored.
- */
- this.setCache = function(id, fragment){
- if (!this.caching) return;
-
- cache[id] = fragment;
- };
-
- /**
- * Finds HTML presentation node in cache by ID
- *
- * @param {String} id the id of the HTMLElement which is looked up.
- * @return {HTMLElement} the HTMLElement found. When no element is found, null is returned.
- */
- this.getNodeFromCache = function(id){
- var node = this.$findNode(null, id);
- if (node) return node;
-
- for (var prop in cache) {
- if (cache[prop] && cache[prop].nodeType) {
- node = this.$findNode(cache[prop], id);
- if (node) return node;
- }
- }
-
- return null;
- };
-
- this.$findNode = function(cacheNode, id){
- if (!cacheNode)
- return this.pHtmlDoc.getElementById(id);
-
- return cacheNode.getElementById(id);
- };
-
- /**
- * Finds HTML presentation element in cache by xmlNode or xml id
- *
- * @param {mixed} xmlNode the xmlNode or id of the xmlNode that is represented by the HTMLElement which is looked up.
- * @return {HTMLElement} the HTMLElement found. When no element is found, null is returned.
- */
- this.getNodeByXml = function(xmlNode){
- return xmlNode
- ? (this.getNodeFromCache((typeof xmlNode == "object"
- ? xmlNode.getAttribute(jpf.xmldb.xmlIdTag)
- : xmlNode) + "|" + this.uniqueId))
- : null;
- };
-
- /**
- * Finds cache element by ID of HTMLElement in cache
- *
- * @param {String} id the id of the HTMLElement which is looked up.
- * @return {DocumentFragment} the cached element. When no object is found, null is returned.
- */
- this.getCacheItemByHtmlId = function(id){
- var node = this.$findNode(null, id);
- if (node) return this.oInt;
-
- for (var prop in cache) {
- if (cache[prop] && cache[prop].nodeType) {
- node = this.$findNode(cache[prop], id);
- if (node) return cache[prop];
- }
- }
-
- return null;
- };
-
- /**
- * Unloads data from this element and resets state displaying an empty message.
- * Empty message is set on the {@link baseclass.jmlelement.property.msg}.
- *
- * @param {Boolean} [nomsg] whether to display the empty message.
- * @param {Boolean} [doEvent] whether to sent select events.
- * @see baseclass.databinding.method.load
- */
- this.clear = function(nomsg, doEvent){
- if (this.clearSelection)
- this.clearSelection(null, !doEvent);
-
- if (this.caching) {
- /*
- Check if we borrowed an HTMLElement
- We should return it where it came from
-
- note: There is a potential that we can't find the exact location
- to put it back. We should then look at it's position in the xml.
- (but since I'm lazy it's not doing this right now)
- There might also be problems when removing the xmlroot
- */
- if (this.hasFeature(__MULTISELECT__)
- && subTreeCacheContext && subTreeCacheContext.oHtml) {
- if (this.renderRoot)
- subTreeCacheContext.parentNode.insertBefore(subTreeCacheContext.oHtml, subTreeCacheContext.beforeNode);
- else {
- while (this.oInt.childNodes.length)
- subTreeCacheContext.oHtml.appendChild(this.oInt.childNodes[0]);
- }
-
- this.documentId = this.xmlRoot = this.cacheID = subTreeCacheContext = null;
- }
- else{
- /* If the current item was loaded whilst offline, we won't cache
- * anything
- */
- if (this.loadedWhenOffline) {
- this.loadedWhenOffline = false;
- }
- else {
- // Here we cache the current part
- var fragment = this.$getCurrentFragment();
- if (!fragment) return;//this.$setClearMessage(this.emptyMsg);
-
- fragment.documentId = this.documentId;
- fragment.xmlRoot = this.xmlRoot;
- }
- }
- }
- else if (this.$clear)
- this.$clear();
- else
- this.oInt.innerHTML = "";
-
- if (typeof nomsg == "string") {
- var msgType = nomsg;
- nomsg = false;
- }
-
- if (!nomsg)
- this.$setClearMessage(msgType ? this[msgType + "Msg"] : this.emptyMsg, msgType || "empty");
- else if(this.$removeClearMessage)
- this.$removeClearMessage();
-
- if (this.caching && (this.cacheID || this.xmlRoot))
- this.setCache(this.cacheID || this.xmlRoot.getAttribute(jpf.xmldb.xmlIdTag) || "doc"
- + this.xmlRoot.getAttribute(jpf.xmldb.xmlDocTag), fragment);
-
- this.documentId = this.xmlRoot = this.cacheID = null;
-
- if (!nomsg && this.hasFeature(__MULTISELECT__)) //@todo this is all wrong
- this.setProperty("length", 0);
- };
-
- /**
- * @private
- */
- this.clearAllTraverse = function(msg, className){
- if (this.clearSelection)
- this.clearSelection(null, true);
-
- this.oInt.innerHTML = "";
- this.$setClearMessage(msg || this.emptyMsg, className || "empty");
- this.setConnections();
-
- this.setProperty("length", 0);
- };
-
- /**
- * Removes an item from the cache.
- *
- * @param {String} id the id of the HTMLElement which is looked up.
- * @param {Boolean} [remove] whether to destroy the Fragment.
- * @see baseclass.databinding.method.clear
- */
- this.clearCacheItem = function(id, remove){
- cache[id].documentId = cache[id].cacheID = cache[id].xmlRoot = null;
-
- if (remove)
- jpf.removeNode(cache[id]);
-
- cache[id] = null;
- };
-
- /**
- * Removes all items from the cache
- *
- * @see baseclass.databinding.method.clearCacheItem
- */
- this.clearAllCache = function(){
- for (var prop in cache) {
- if (cache[prop])
- this.clearCacheItem(prop, true);
- }
- };
-
- /**
- * Gets the cache item by it's id
- *
- * @param {String} id the id of the HTMLElement which is looked up.
- * @see baseclass.databinding.method.clearCacheItem
- */
- this.getCacheItem = function(id){
- return cache[id];
- };
-
- /**
- * Checks whether a cache item exists by the specified id
- *
- * @param {String} id the id of the cache item to check.
- * @see baseclass.databinding.method.clearCacheItem
- */
- this.isCached = function(id){
- return cache[id] || this.cacheID == id ? true : false;
- }
-
- /* ********************************************************************
- PRIVATE METHODS
- *********************************************************************/
-
- /**
- * @attribute {Boolean} caching whether caching is enabled for this element.
- */
- this.$booleanProperties["caching"] = true;
- this.$supportedProperties.push("caching");
-
- if (this.hasFeature(__MULTISELECT__))
- this.inherit(jpf.MultiselectCache);
-
- this.$jmlDestroyers.push(function(){
- //Remove all cached Items
- this.clearAllCache();
- });
-};
-
-
-/**
- * @constructor
- * @private
- */
-jpf.MultiselectCache = function(){
- this.$getCurrentFragment = function(){
- var fragment = this.oInt.ownerDocument.createDocumentFragment();
-
- while (this.oInt.childNodes.length) {
- fragment.appendChild(this.oInt.childNodes[0]);
- }
-
- return fragment;
- };
-
- this.$setCurrentFragment = function(fragment){
- this.oInt.appendChild(fragment);
-
- if (!jpf.window.hasFocus(this))
- this.blur();
- };
-
- this.$findNode = function(cacheNode, id){
- if (!cacheNode)
- return this.pHtmlDoc.getElementById(id);
-
- return cacheNode.getElementById(id);
- };
-
- var oEmpty;
- this.$setClearMessage = function(msg, className){
- if (!oEmpty) {
- this.$getNewContext("empty");
-
- var xmlEmpty = this.$getLayoutNode("empty");
- if (!xmlEmpty) return;
-
- oEmpty = jpf.xmldb.htmlImport(xmlEmpty, this.oInt);
- }
- else {
- this.oInt.appendChild(oEmpty);
- }
-
- var empty = this.$getLayoutNode("empty", "caption", oEmpty);
-
- if (empty)
- jpf.xmldb.setNodeValue(empty, msg || "");
-
- oEmpty.setAttribute("id", "empty" + this.uniqueId);
- jpf.setStyleClass(oEmpty, className, ["loading", "empty", "offline"]);
- };
-
- this.$updateClearMessage = function(msg, className) {
- if (!oEmpty || oEmpty.parentNode != this.oInt
- || oEmpty.className.indexOf(className) == -1)
- return;
-
- var empty = this.$getLayoutNode("empty", "caption", oEmpty);
- if (empty)
- jpf.xmldb.setNodeValue(empty, msg || "");
- }
-
- this.$removeClearMessage = function(){
- if (!oEmpty)
- oEmpty = document.getElementById("empty" + this.uniqueId);
- if (oEmpty && oEmpty.parentNode)
- oEmpty.parentNode.removeChild(oEmpty);
- };
-};
-
- - -/*FILEHEAD(/var/lib/jpf/src/core/node/jmlelement.js)SIZE(-1077090856)TIME(1239018215)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - -var __JMLNODE__ = 1 << 15; -var __VALIDATION__ = 1 << 6; - - -/** - * Baseclass for jml elements. - * - * @constructor - * @baseclass - * @author Ruben Daniels - * @version %I%, %G% - * @since 0.4 - * - * @event contextmenu Fires when the user requests a context menu. Either - * using the keyboard or mouse. - * bubbles: yes - * cancellable: Prevents the default contextmenu from appearing. - * object: - * {Number} x the x coordinate where the contextmenu is requested on. - * {Number} y the y coordinate where the contextmenu is requested on. - * {Event} htmlEvent the html event object that triggered this event from being called. - * @event focus Fires when this element receives focus. - * @event blur Fires when this element loses focus. - * @event keydown Fires when this element has focus and the user presses a key on the keyboard. - * cancellable: Prevents the default key action. - * bubbles: - * object: - * {Boolean} ctrlKey wether the ctrl key was pressed. - * {Boolean} shiftKey wether the shift key was pressed. - * {Boolean} altKey wether the alt key was pressed. - * {Number} keyCode which key was pressed. This is an ascii number. - * {Event} htmlEvent the html event object that triggered this event from being called. - */ -jpf.JmlElement = function(){ - - this.$regbase = this.$regbase | __JMLNODE__; - var _self = this; - - /**** Convenience functions for gui nodes ****/ - - if (this.nodeFunc == jpf.NODE_VISIBLE) { - - - /**** Geometry ****/ - - /** - * Sets the different between the left edge and the right edge of this - * element. Depending on the choosen layout method the unit can be - * pixels, a percentage or an expression. - * @param {Number} value the new width of this element. - */ - this.setWidth = function(value){ - this.setProperty("width", value); - }; - - /** - * Sets the different between the top edge and the bottom edge of this - * element. Depending on the choosen layout method the unit can be - * pixels, a percentage or an expression. - * @param {Number} value the new height of this element. - */ - this.setHeight = function(value){ - this.setProperty("height", value); - }; - - /** - * Sets the left position of this element. Depending on the choosen - * layout method the unit can be pixels, a percentage or an expression. - * @param {Number} value the new left position of this element. - */ - this.setLeft = function(value){ - this.setProperty("left", value); - }; - - /** - * Sets the top position of this element. Depending on the choosen - * layout method the unit can be pixels, a percentage or an expression. - * @param {Number} value the new top position of this element. - */ - this.setTop = function(value){ - this.setProperty("top", value); - }; - - this.$noAlignUpdate = false; - if (!this.show) - /** - * Makes the elements visible - */ - this.show = function(s){ - this.$noAlignUpdate = s; - this.setProperty("visible", true); - this.$noAlignUpdate = false; - }; - if (!this.hide) - /** - * Makes the elements invisible - */ - this.hide = function(s){ - this.$noAlignUpdate = s; - this.setProperty("visible", false); - this.$noAlignUpdate = false; - }; - - /** - * Retrieves the calculated width in pixels for this element - */ - this.getWidth = function(){ - return (this.oExt || {}).offsetWidth; - }; - - /** - * Retrieves the calculated height in pixels for this element - */ - this.getHeight = function(){ - return (this.oExt || {}).offsetHeight; - }; - - /** - * Retrieves the calculated left position in pixels for this element - * relative to the offsetParent. - */ - this.getLeft = function(){ - return (this.oExt || {}).offsetLeft; - }; - - /** - * Retrieves the calculated top position in pixels for this element - * relative to the offsetParent. - */ - this.getTop = function(){ - return (this.oExt || {}).offsetTop; - }; - - /**** Disabling ****/ - - /** - * Activates the functions of this element. - */ - this.enable = function(){ - this.setProperty("disabled", false); - }; - - /** - * Deactivates the functions of this element. - */ - this.disable = function(){ - this.setProperty("disabled", true); - }; - - /**** z-Index ****/ - - /** - * Moves this element to the lowest z ordered level. - */ - this.sendToBack = function(){ - this.setProperty("zindex", 0); - }; - - /** - * Moves this element to the highest z ordered level. - */ - this.bringToFront = function(){ - this.setProperty("zindex", jpf.all.length + 1); - }; - - /** - * Moves this element one z order level deeper. - */ - this.sendBackwards = function(){ - this.setProperty("zindex", this.zindex - 1); - }; - - /** - * Moves this element one z order level higher. - */ - this.bringForward = function(){ - this.setProperty("zindex", this.zindex + 1); - }; - - - /**** Focussing ****/ - - if (this.$focussable) { - /** - * Sets the position in the list that determines the sequence - * of elements when using the tab key to move between them. - * @param {Number} tabindex the position in the list - */ - this.setTabIndex = function(tabindex){ - jpf.window.$removeFocus(this); - jpf.window.$addFocus(this, tabindex); - }; - - /** - * Gives this element the focus. This means that keyboard events - * are send to this element. - */ - this.focus = function(noset, e, nofix){ - if (!noset) { - if (this.isWindowContainer) { - jpf.window.$focusLast(this, e, true); - } - else { - jpf.window.$focus(this, e); - - if (!nofix && jpf.hasFocusBug) - jpf.window.$focusfix(); - } - - return; - } - - if (this.$focus) - this.$focus(e); - - this.dispatchEvent("focus", { - srcElement : this, - bubbles : true - }); - }; - - /** - * Removes the focus from this element. - */ - this.blur = function(noset, e){ - if (jpf.popup.isShowing(this.uniqueId)) - jpf.popup.forceHide(); //This should be put in a more general position - - if (this.$blur) - this.$blur(e); - - if (!noset) - jpf.window.$blur(this); - - this.dispatchEvent("blur", { - srcElement : this, - bubbles : !e || !e.cancelBubble - }); - }; - - /** - * Determines whether this element has the focus - * @returns {Boolean} indicating whether this element has the focus - */ - this.hasFocus = function(){ - return jpf.window.focussed == this || this.isWindowContainer - && (jpf.window.focussed || {}).$focusParent == this; - }; - } - } - - /**** Load JML ****/ - - if (!this.hasFeature(__WITH_JMLDOM__)) - this.inherit(jpf.JmlDom); /** @inherits jpf.JmlDom */ - - /** - * @private - */ - this.loadJml = function(x, pJmlNode, ignoreBindclass, id){ - this.name = x.getAttribute("id"); - if (this.name) - jpf.setReference(this.name, this); - - if (!x) - x = this.$jml; - - if (this.parentNode || pJmlNode) - this.$setParent(this.parentNode || pJmlNode); - - this.$jml = x; - - //Drawing, Skinning, Positioning and Editing - if (this.nodeFunc != jpf.NODE_HIDDEN) { - - this.inherit(jpf.MultiLang); /** @inherits jpf.MultiLang */ - - if (this.$loadSkin) - this.$loadSkin(); - - if (this.$draw) - this.$draw(); - - if (id) - this.oExt.setAttribute("id", id); - - var pTagName = x.parentNode && x.parentNode[jpf.TAGNAME] || ""; - if (pTagName == "grid") { - this.inherit(jpf.Anchoring); - - this.$propHandlers["width"] = - this.$propHandlers["height"] = - this.$propHandlers["span"] = this.parentNode.$updateTrigger; - } - else - - if (x.getAttribute("align") - || x.parentNode && x.parentNode.nodeType == 1 - && "vbox|hbox".indexOf(pTagName) > -1) { //@todo temp - this.inherit(jpf.Alignment); /** @inherits jpf.Alignment */ - this.oExt.style.display = "none"; - this.enableAlignment(); - } - else - - if (this.$positioning != "basic") { - this.inherit(jpf.Anchoring); /** @inherits jpf.Anchoring */ - this.enableAnchoring(); - } - - if (this.visible === undefined && !x.getAttribute("visible")) - this.visible = true; - - this.$drawn = true; - } - else if (this.$draw) - this.$draw(); - - if (this.nodeFunc == jpf.NODE_VISIBLE) { - if (jpf.debug && this.oExt.nodeType) - this.oExt.setAttribute("uniqueId", this.uniqueId); - } - - if (!ignoreBindclass) { //Is this still needed? - if (!this.hasFeature(__DATABINDING__) && x.getAttribute("smartbinding")) { - this.inherit(jpf.DataBinding); - this.$xmlUpdate = this.$load = function(){}; - } - } - - /**** Properties and Attributes ****/ - - var offlineLookup; - if (typeof jpf.offline != "undefined" && jpf.offline.state.enabled) - offlineLookup = jpf.offline.state.getAll(this); - - //Parse all attributes - this.$noAlignUpdate = true; - var value, name, type, l, a, i, attr = x.attributes; - for (i = 0, l = attr.length; i < l; i++) { - a = attr[i]; - value = a.nodeValue; - name = a.nodeName; - - if (value && jpf.dynPropMatch.test(value)) { - jpf.JmlParser.stateStack.push({ - node : this, - name : name, - value : value - }); - } else - { - if (name == "disabled") { - jpf.JmlParser.stateStack.push({ - node : this, - name : name, - value : value - }); - } - - if (a.nodeName.indexOf("on") === 0) { - this.addEventListener(name, new Function('event', value)); - continue; - } - - if (offlineLookup) { - value = offlineLookup[name] || value - || this.defaults && this.defaults[name]; - delete offlineLookup[name]; - } - - if (this.$booleanProperties[name]) - value = jpf.isTrue(value); - - this[name] = value; - (this.$propHandlers && this.$propHandlers[name] - || jpf.JmlElement.propHandlers[name] || jpf.K).call(this, value) - } - } - - for (name in offlineLookup) { - value = offlineLookup[name]; - (this.$propHandlers && this.$propHandlers[name] - || jpf.JmlElement.propHandlers[name] || jpf.K).call(this, value); - } - - //Get defaults from the defaults tag in appsettings - if (jpf.appsettings.defaults[this.tagName]) { - d = jpf.appsettings.defaults[this.tagName]; - for (i = 0, l = d.length; i < l; i++) { - name = d[i][0], value = d[i][1]; - if (this[name] === undefined) { - if (this.$booleanProperties[name]) - value = jpf.isTrue(value); - - this[name] = value; - (this.$propHandlers && this.$propHandlers[name] - || jpf.JmlElement.propHandlers[name] || jpf.K) - .call(this, value, name); - } - } - } - - this.$noAlignUpdate = false; - - if (this.$focussable && this.focussable === undefined) - jpf.JmlElement.propHandlers.focussable.call(this); - - // isSelfLoading is set when JML is being inserted - if (this.$loadJml && !this.$isSelfLoading) - this.$loadJml(x); - - //Process JML Handlers - for (i = this.$jmlLoaders.length - 1; i >= 0; i--) - this.$jmlLoaders[i].call(this, x); - - this.$jmlLoaded = true; - - return this; - }; - - this.$handlePropSet = function(prop, value, force){ - if (!force && !this.hasFeature(__MULTISELECT__) && this.xmlRoot && this.bindingRules - && this.bindingRules[prop] && !this.ruleTraverse) { - return jpf.xmldb.setNodeValue(this.getNodeFromRule( - prop.toLowerCase(), this.xmlRoot, null, null, true), - value, !this.$onlySetXml); - } - - if (this.$booleanProperties[prop]) - value = jpf.isTrue(value); - - this[prop] = value; - - if(this.$onlySetXml) - return; - - return (this.$propHandlers && this.$propHandlers[prop] - || jpf.JmlElement.propHandlers[prop] - || jpf.K).call(this, value, force, prop); - }; - - /** - * Replaces the child jml elements with new jml. - * @param {mixed} jmlDefNode the jml to be loaded. This can be a string or a parsed piece of xml. - * @param {HTMLElement} oInt the html parent of the created jml elements. - * @param {JMLElement} oIntJML the jml parent of the created jml elements. - */ - this.replaceJml = function(jmlDefNode, oInt, oIntJML, isHidden){ - jpf.console.info("Remove all jml from element"); - - //Remove All the childNodes - for (var i = 0; i < this.childNodes.length; i++) { - var oItem = this.childNodes[i]; - var nodes = oItem.childNodes; - for (var k = 0; k < nodes.length; k++) - if (nodes[k].destroy) - nodes[k].destroy(); - - if (oItem.$jml && oItem.$jml.parentNode) - oItem.$jml.parentNode.removeChild(oItem.$jml); - - oItem.destroy(); - - if (oItem.oExt != this.oInt) - jpf.removeNode(oItem.oExt); - } - this.childNodes.length = 0; - this.oExt.innerHTML = ""; - - //Do an insertJml - this.insertJml(jmlDefNode, oInt, oIntJML, isHidden); - }; - - /** - * Inserts new jml into this element. - * @param {mixed} jmlDefNode the jml to be loaded. This can be a string or a parsed piece of xml. - * @param {HTMLElement} oInt the html parent of the created jml elements. - * @param {JMLElement} oIntJML the jml parent of the created jml elements. - */ - this.insertJml = function(jmlDefNode, oInt, oIntJml, isHidden){ - jpf.console.info("Loading sub jml from external source"); - - if (typeof jpf.offline != "undefined" && !jpf.offline.onLine) - return false; //it's the responsibility of the dev to check this - - var callback = function(data, state, extra){ - if (state != jpf.SUCCESS) { - var oError; - - oError = new Error(jpf.formatErrorString(1019, _self, - "Loading extra jml from datasource", - "Could not load JML from remote resource \n\n" - + extra.message)); - - if (extra.tpModule.retryTimeout(extra, state, _self, oError) === true) - return true; - - throw oError; - } - - jpf.console.info("Runtime inserting jml"); - - var jml = oIntJml || _self.$jml; - if (jml.insertAdjacentHTML) - jml.insertAdjacentHTML(jml.getAttribute("insert") || "beforeend", - (typeof data != "string" && data.length) ? data[0] : data); - else { - if (typeof data == "string") - data = jpf.xmldb.getXml("<j:jml xmlns:j='" - + jpf.ns.jml +"'>" + data + "</j:jml>"); - for (var i = data.childNodes.length - 1; i >= 0; i--) - jml.insertBefore(data.childNodes[i], jml.firstChild); - } - - jpf.JmlParser.parseMoreJml(jml, oInt || _self.oInt, _self, - (isHidden && (oInt || _self.oInt).style.offsetHeight) - ? true : false); - } - - if (typeof jmlDefNode == "string") { - //Process Instruction - if (jpf.datainstr[jmlDefNode]){ - return jpf.getData(jmlDefNode, null, { - ignoreOffline : true - }, callback); - } - //Jml string - else - jmlDefNode = jpf.xmldb.getXml(jmlDefNode); - } - - //Xml Node is assumed - return callback(jmlDefNode, jpf.SUCCESS); - }; - - if ( - this.hasFeature(__DATABINDING__) && - !this.hasFeature(__MULTISELECT__) && !this.change) { - - /** - * Changes the value of this element. - * @action - * @param {String} [string] the new value of this element. - */ - this.change = function(value){ - if (this.errBox && this.errBox.visible && this.isValid()) - this.clearError(); - - //Not databound - if ((!this.createModel || !this.$jml.getAttribute("ref")) && !this.xmlRoot) { - if (value === this.value - || this.dispatchEvent("beforechange", {value : value}) === false) - return; - - this.setProperty("value", value); - return this.dispatchEvent("afterchange", {value : value}); - } - - if (this.value === value) - return false; - - this.executeActionByRuleSet("change", this.mainBind, this.xmlRoot, value); - }; - } - - if (this.setValue && !this.clear) { - /** - * Clears the data loaded into this element resetting it's value. - */ - this.clear = function(nomsg){ - if (this.$setClearMessage) { - if (!nomsg) - this.$setClearMessage(this.emptyMsg, "empty"); - else if (this.$removeClearMessage) - this.$removeClearMessage(); - } - - //this.setValue("") - this.value = -99999; //force resetting - - this.$propHandlers && this.$propHandlers["value"] - ? this.$propHandlers["value"].call(this, "") - : this.setValue(""); - }; - } - - if (this.hasFeature(__DATABINDING__)) { - this.addEventListener("contextmenu", function(e){ - if (!this.contextmenus) return; - - var contextmenu; - var xmlNode = this.hasFeature(__MULTISELECT__) - ? this.selected - : this.xmlRoot; - - var i, isRef, sel, menuId; - for (var i = 0; i < this.contextmenus.length; i++) { - isRef = (typeof this.contextmenus[i] == "string"); - if (!isRef) - sel = "self::" + String(this.contextmenus[i].getAttribute("select")) - .split("|").join("self::"); - - if (isRef || xmlNode && xmlNode.selectSingleNode(sel || ".") - || !xmlNode && !sel) { - menuId = isRef - ? this.contextmenus[i] - : this.contextmenus[i].getAttribute("menu") - - if (!self[menuId]) { - throw new Error(jpf.formatErrorString(0, this, - "Showing contextmenu", - "Could not find contextmenu by name: '" + menuId + "'"), - this.$jml); - } - - self[menuId].display(e.x, e.y, null, this, xmlNode); - - e.returnValue = false;//htmlEvent. - e.cancelBubble = true; - break; - } - } - - //IE6 compatiblity - /* - @todo please test that disabling this is OK - if (!jpf.appsettings.disableRightClick) { - document.oncontextmenu = function(){ - document.oncontextmenu = null; - e.cancelBubble = true; - return false; - } - }*/ - }); - } - else { - this.addEventListener("contextmenu", function(e){ - if (!this.contextmenus) - return; - - var menuId = typeof this.contextmenus[0] == "string" - ? this.contextmenus[0] - : this.contextmenus[0].getAttribute("menu") - - if (!self[menuId]) { - throw new Error(jpf.formatErrorString(0, this, - "Showing contextmenu", - "Could not find contextmenu by name: '" + menuId + "'", - this.$jml)); - } - - self[menuId].display(e.x, e.y, null, this); - - e.returnValue = false;//htmlEvent. - e.cancelBubble = true; - }); - } -}; - -/** - * @for jpf.jmlNode - * @private - */ -jpf.JmlElement.propHandlers = { - /** - * @attribute {String} id the identifier of this element. When set this - * identifier is the name of the variable in javascript to access this - * element directly. This identifier is also the way to get a reference to - * this element using jpf.document.getElementById. - * Example: - * <code> - * <j:bar id="barExample" /> - * <j:script> - * alert(barExample); - * </j:script> - * </code> - */ - "id": function(value){ - if (this.name == value) - return; - - if (self[this.name] == this) - self[this.name] = null; - - jpf.setReference(value, this); - this.name = value; - }, - - /** - * @attribute {Boolean} focussable whether this element can receive the focus. - * The focussed element receives keyboard event.s - */ - "focussable": function(value){ - if (typeof value == "undefined") - this.focussable = true; - - if (this.focussable) { - jpf.window.$addFocus(this, this.tabindex - || this.$jml.getAttribute("tabindex")); - } - else { - jpf.window.$removeFocus(this); - } - }, - - /** - * @attribute {Number} zindex the z ordered layer in which this element is - * drawn. - */ - "zindex": function(value){ - this.oExt.style.zIndex = value; - }, - - /** - * @attribute {Boolean} visible whether this element is shown. - */ - "visible": function(value){ - if (this.tagName == "modalwindow") - return; // temp fix - - if (jpf.isFalse(value) || typeof value == "undefined") { - this.oExt.style.display = "none"; - - if (this.$hide && !this.$noAlignUpdate) - this.$hide(); - - if (jpf.window.focussed == this - || this.canHaveChildren - && jpf.xmldb.isChildOf(this, jpf.window.focussed, false)) { - if (jpf.appsettings.allowBlur) - this.blur(); - else - jpf.window.moveNext(); - } - } - else if (jpf.isTrue(value)) { - this.oExt.style.display = "block"; //Some form of inheritance detection - - if (this.$show && !this.$noAlignUpdate) - this.$show(); - - if (jpf.hasSingleRszEvent) - jpf.layout.forceResize();//this.oInt - } - }, - - /** - * @attribute {Boolean} disabled whether this element's functions are active. - * For elements that can contain other jpf.NODE_VISIBLE elements this - * attribute applies to all it's children. - */ - "disabled": function(value){ - //For child containers we only disable its children - if (this.canHaveChildren) { - //@todo Fix focus here first.. else it will jump whilst looping - - value = this.disabled = jpf.isTrue(value); - - function loopChildren(nodes){ - for (var node, i = 0, l = nodes.length; i < l; i++) { - node = nodes[i]; - if (node.nodeFunc == jpf.NODE_VISIBLE) { - if (value && node.disabled != -1) - node.$disabled = node.disabled || false; - node.setProperty("disabled", value ? -1 : null); - } - - if (node.childNodes.length) - loopChildren(node.childNodes); - } - } - loopChildren(this.childNodes); - - //this.disabled = undefined; - return; - } - - if (value == -1) { - value = true; - } - else if (typeof this.$disabled == "boolean") { - if (value === null) { - value = this.$disabled; - this.$disabled = null; - } - else { - this.$disabled = value || false; - return; - } - } - - if (jpf.isTrue(value)) { - this.disabled = false; - if (jpf.window.focussed == this) { - jpf.window.moveNext(true); //@todo should not include window - if (jpf.window.focussed == this) - this.$blur(); - } - - if (this.hasFeature(__PRESENTATION__)) - this.$setStyleClass(this.oExt, this.baseCSSname + "Disabled"); - - if (this.$disable) - this.$disable(); - - - this.disabled = true; - } - else { - if (this.hasFeature(__DATABINDING__) && jpf.appsettings.autoDisable - & !this.isBoundComplete()) - return false; - - this.disabled = false; - - if (jpf.window.focussed == this) - this.$focus(); - - if (this.hasFeature(__PRESENTATION__)) - this.$setStyleClass(this.oExt, null, [this.baseCSSname + "Disabled"]); - - if (this.$enable) - this.$enable(); - - } - }, - - "enabled" : function(value){ - this.setProperty("disabled", !value); - }, - - /** - * @attribute {Boolean} disable-keyboard whether this element receives - * keyboard input. This allows you to disable keyboard independently from - * focus handling. - */ - "disable-keyboard": function(value){ - this.disableKeyboard = jpf.isTrue(value); - }, - - /** - * @attribute {mixed} left the left position of this element. Depending - * on the choosen layout method the unit can be pixels, a percentage or an - * expression. - */ - "left": function(value){ - this.oExt.style.position = "absolute"; - this.oExt.style.left = value + "px"; - }, - - /** - * @attribute {mixed} top the top position of this element. Depending - * on the choosen layout method the unit can be pixels, a percentage or an - * expression. - */ - "top": function(value){ - this.oExt.style.position = "absolute"; - this.oExt.style.top = value + "px"; - }, - - /** - * @attribute {mixed} right the right position of this element. Depending - * on the choosen layout method the unit can be pixels, a percentage or an - * expression. - */ - "right": function(value){ - this.oExt.style.position = "absolute"; - this.oExt.style.right = value + "px"; - }, - - /** - * @attribute {mixed} bottom the bottom position of this element. Depending - * on the choosen layout method the unit can be pixels, a percentage or an - * expression. - */ - "bottom": function(value){ - this.oExt.style.position = "absolute"; - this.oExt.style.bottom = value + "px"; - }, - - /** - * @attribute {mixed} width the different between the left edge and the - * right edge of this element. Depending on the choosen layout method the - * unit can be pixels, a percentage or an expression. - */ - "width": function(value){ - this.oExt.style.width = Math.max(0, value - - jpf.getWidthDiff(this.oExt)) + "px"; - }, - - /** - * @attribute {mixed} height the different between the top edge and the - * bottom edge of this element. Depending on the choosen layout method the - * unit can be pixels, a percentage or an expression. - */ - "height": function(value){ - this.oExt.style.height = Math.max(0, - value - jpf.getHeightDiff(this.oExt)) + "px"; - }, - - "align": function(value){ - if (this.disableAnchoring) - this.disableAnchoring(); - - if (!this.hasFeature(__ALIGNMENT__)) { - this.inherit(jpf.Alignment); - this.oExt.style.display = "none"; - this.enableAlignment(); - } - }, - - /** - * @attribute {String} contextmenu the name of the menu element that will - * be shown when the user right clicks or uses the context menu keyboard - * shortcut. - * Example: - * <code> - * <j:menu id="mnuExample" /> - * - * <j:list contextmenu="mnuExample" /> - * <j:bar contextmenu="mnuExample" /> - * </code> - */ - "contextmenu": function(value){ - this.contextmenus = [value]; - }, - - "resizable": function(value){ - this.inherit(jpf.Interactive); - this.$propHandlers["resizable"].apply(this, arguments); - }, - - "draggable": function(value){ - this.inherit(jpf.Interactive); - this.$propHandlers["draggable"].apply(this, arguments); - }, - - /** - * @attribute {String} actiontracker the name of the actiontracker that - * is used for this element and it's children. If the actiontracker doesn't - * exist yet it is created. - * Example: - * In this example the list uses a different actiontracker than the two - * textboxes which determine their actiontracker based on the one that - * is defined on the bar. - * <code> - * <j:list actiontracker="newAT" /> - * - * <j:bar actiontracker="someAT"> - * <j:textbox /> - * <j:textbox /> - * </j:bar> - * </code> - */ - "actiontracker": function(value){ - if (!value) - this.$at = null; - else if (value.tagName == "actiontracker") - this.$at = value; - else { - this.$at = typeof value == "string" && self[value] - ? jpf.JmlParser.getActionTracker(value) - : jpf.setReference(value, - jpf.nameserver.register("actiontracker", - value, new jpf.actiontracker())); - } - }, - - /** - * @attribute {Boolean} center centers the window relative to it's parent's - * containing rect when shown. - */ - "transaction" : function(value){ - /** - * @inherits jpf.DataBinding - * @inherits jpf.Transaction - */ - if (!this.hasFeature(__DATABINDING__)) { - this.inherit(jpf.DataBinding); - this.smartBinding = true; - } - - if (!this.hasFeature(__TRANSACTION__)) - this.inherit(jpf.Transaction); - }, - - //Load subJML - /** - * @attribute {String} the data instruction that loads new jml as children - * of this element. - */ - "jml": function(value){ - //Clear?? - this.insertJml(value); - this.$isSelfLoading = true; - } - -}; - - -document.onkeydown = function(e){ - if (!e) e = event; - if (e.keyCode == 120 || e.ctrlKey && e.altKey && e.keyCode == 68) { - if (!jpf.debugwin.resPath) - jpf.debugwin.init(); - jpf.debugwin.activate(); - } -}; - - -/*FILEHEAD(/var/lib/jpf/src/core/node/jmldom.js)SIZE(-1077090856)TIME(1238944816)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-var __WITH_JMLDOM__ = 1 << 14;
-
-
-/**
- * Baseclass adding the Document Object Model (DOM) to this element. The DOM
- * is the primary method for accessing and manipulating an xml document. This
- * includes html documents and jml documents. Every element in the javeline
- * markup language can be manipulated using the W3C DOM. This means
- * that every element and attribute you can set in the xml format, can be
- * changed, set, removed reparented, etc runtime. This offers a great deal of
- * flexibility. Well known methods
- * from this specification are .appendChild .removeChild .setAttribute and
- * insertBefore to name a few. Javeline PlatForm aims to implement DOM1
- * completely and parts of DOM2. Which should be extended in the future to fully
- * implement DOM Level 2. For more information see http://www.w3.org/DOM/.
- * Example:
- * Javeline Markup Language
- * <code>
- * <j:window id="winExample" title="Example">
- * <j:button id="tstButton" />
- * </j:window>
- * </code>
- * Document Object Model in javascript
- * <code>
- * //The following line is only there for completeness sake. In fact jpf
- * //automatically adds a reference in javascript called winExample based
- * //on the is it has.
- * var winExample = jpf.document.getElementById("winExample");
- * winExample.setAttribute("icon", "icoFolder.gif");
- * winExample.setAttribute("left", "100");
- *
- * var lblNew = jpf.document.createElement("label");
- * winExample.appendChild(lblNew);
- * lblNew.setAttribute("caption", "Example");
- *
- * tstButton.setAttribute("caption", "Click me");
- * </code>
- * That would be the same as having the following jml:
- * <code>
- * <j:window id="winExample"
- * title = "Example"
- * icon = "icoFolder.gif"
- * left = "100">
- * <j:label caption="Example" />
- * <j:button id="tstButton" caption="Click me"/>
- * </j:window>
- * </code>
- * Remarks:
- * Because the W3C DOM is native to all modern browsers the internet is full
- * of tutorials and documentation for this API. If you need more information
- * it's a good idea to search for tutorials online.
- *
- * @constructor
- * @baseclass
- *
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.5
- */
-jpf.JmlDom = function(tagName, parentNode, nodeFunc, jml, content){
- /**
- * {Number} nodeType the type of node within the document.
- * Possible values:
- * jpf.NODE_ELEMENT
- * jpf.NODE_ATTRIBUTE
- * jpf.NODE_TEXT
- * jpf.NODE_CDATA_SECTION
- * jpf.NODE_ENTITY_REFERENCE
- * jpf.NODE_ENTITY
- * jpf.NODE_PROCESSING_INSTRUCTION
- * jpf.NODE_COMMENT
- * jpf.NODE_DOCUMENT
- * jpf.NODE_DOCUMENT_TYPE
- * jpf.NODE_DOCUMENT_FRAGMENT
- * jpf.NODE_NOTATION
- */
- this.nodeType = jpf.NODE_ELEMENT;
- this.$regbase = this.$regbase | __WITH_JMLDOM__;
-
- /**
- * {NodeList} childNodes containing all the child nodes of this element.
- */
- this.childNodes = [];
- var _self = this;
-
- if (!this.$domHandlers)
- this.$domHandlers = {"remove" : [], "insert" : [],
- "reparent" : [], "removechild" : []};
-
- /**
- * {JMLDocument} ownerDocument the document of this application
- */
- if (jpf.document)
- this.ownerDocument = jpf.document;
-
- if (tagName) {
- if (typeof tagName == "number") {
- if (tagName == jpf.NODE_DOCUMENT_FRAGMENT) {
- this.nodeType = jpf.NODE_DOCUMENT_FRAGMENT;
-
- this.hasFeature = function(){
- return false;
- }
- }
- }
- else {
-
- /**
- * {JmlNode} the parent in the tree of this element.
- */
- this.parentNode = parentNode;
- this.$jml = jml;
- /**
- * {Number} nodeFunc the function of this element
- * Possible values:
- * jpf.NODE_VISIBLE this element has a gui representation
- * jpf.NODE_HIDDEN this element does not display a gui
- */
- this.nodeFunc = nodeFunc;
-
- /**
- * {String} tagName the name of the class of this element
- */
- this.tagName = tagName;
-
- /**
- * {String} name the unique name of this element if any. This is set by the id attribute and is synonymous with the id property.
- */
- this.name = jml && jml.getAttribute("id");
-
- /**
- * {mixed} content special content for this object
- */
- this.content = content;
- }
- }
-
- /**
- * Appends an element to the end of the list of children of this element.
- * If the element was already a child of another element it is removed from
- * that parent before adding it this element.
- *
- * @param {JmlNode} jmlNode the element to insert as child of this element.
- * @return {JmlNode} the appended node
- * @method
- */
- this.appendChild =
-
- /**
- * Inserts an element before another element in the list of children of this
- * element. * If the element was already a child of another element it is
- * removed from that parent before adding it this element.
- *
- * @param {JmlNode} jmlNode the element to insert as child of this element.
- * @param {JmlNode} beforeNode the element which determines the insertion position of the element.
- * @return {JmlNode} the inserted node
- */
- this.insertBefore = function(jmlNode, beforeNode){
- if (!jmlNode || !jmlNode.nodeFunc || !jmlNode.hasFeature(__WITH_JMLDOM__)){
- throw new Error(jpf.formatErrorString(1072, this,
- "Insertbefore DOM operation",
- "Invalid argument passed. Expecting a JMLElement."));
- }
-
- if (jmlNode.nodeType == jpf.NODE_DOCUMENT_FRAGMENT) {
- var nodes = jmlNode.childNodes.slice(0);
- for (var i = 0, l = nodes.length; i < l; i++) {
- this.insertBefore(nodes[i], beforeNode);
- }
- return;
- }
-
- var isMoveWithinParent = jmlNode.parentNode == this;
- var oldParentHtmlNode = jmlNode.pHtmlNode;
- if (jmlNode.parentNode)
- jmlNode.removeNode(isMoveWithinParent);
- jmlNode.parentNode = this;
-
- var index;
- if (beforeNode) {
- index = this.childNodes.indexOf(beforeNode);
- if (index < 0) {
- throw new Error(jpf.formatErrorString(1072, this,
- "Insertbefore DOM operation",
- "Before node is not a child of the parent node specified"));
-
- return false;
- }
-
- jmlNode.nextSibling = beforeNode;
- jmlNode.previousSibling = beforeNode.previousSibling;
- beforeNode.previousSibling = jmlNode;
- if (jmlNode.previousSibling)
- jmlNode.previousSibling.nextSibling = jmlNode;
- }
-
- if (index)
- this.childNodes = this.childNodes.slice(0, index).concat(jmlNode,
- this.childNodes.slice(index));
- else {
- index = this.childNodes.push(jmlNode) - 1;
-
- jmlNode.nextSibling = null;
- if (index > 0) {
- jmlNode.previousSibling = this.childNodes[index - 1];
- jmlNode.previousSibling.nextSibling = jmlNode;
- }
- else
- jmlNode.previousSibling = null;
- }
-
- this.firstChild = this.childNodes[0];
- this.lastChild = this.childNodes[this.childNodes.length - 1];
-
- function triggerUpdate(){
- jmlNode.pHtmlNode = _self.canHaveChildren
- ? _self.oInt
- : document.body;
-
- //Signal Jml Node
- var i, callbacks = jmlNode.$domHandlers["reparent"];
- for (i = 0, l = callbacks.length; i < l; i++) {
- if (callbacks[i])
- callbacks[i].call(jmlNode, beforeNode,
- _self, isMoveWithinParent, oldParentHtmlNode);
- }
-
- //Signal myself
- callbacks = _self.$domHandlers["insert"];
- for (i = 0, l = callbacks.length; i < l; i++) {
- if (callbacks[i])
- callbacks[i].call(_self, jmlNode,
- beforeNode, isMoveWithinParent);
- }
-
- //@todo this is a hack, a good solution should be found
- var containsIframe = jmlNode.oExt.getElementsByTagName("iframe").length > 0;
- if (jmlNode.oExt && !jpf.isGecko && !containsIframe) {
- jmlNode.pHtmlNode.insertBefore(jmlNode.oExt,
- beforeNode && beforeNode.oExt || null);
- }
- }
-
- //If we're not loaded yet, just append us to the jml to be parsed
- if (!this.$jmlLoaded) {
- jmlNode.$reappendToParent = triggerUpdate;
-
- return;
- }
-
- triggerUpdate();
- };
-
- /**
- * Removes this element from the document hierarchy.
- *
- */
- this.removeNode = function(doOnlyAdmin){
- if (doOnlyAdmin && typeof doOnlyAdmin != "boolean") {
- throw new Error(jpf.formatErrorString(0, this,
- "Removing node from parent",
- "Invalid DOM Call. removeNode() does not take any arguments."));
- }
-
- if (!this.parentNode || !this.parentNode.childNodes)
- return;
-
- if (!this.parentNode.childNodes.contains(this)) {
- throw new Error(jpf.formatErrorString(0, this,
- "Removing node from parent",
- "The parameter Node is not a child of this Node.", this.$jml));
- }
-
- this.parentNode.childNodes.remove(this);
-
- //If we're not loaded yet, just remove us from the jml to be parsed
- if (this.$jmlLoaded && !jpf.isDestroying) {
- //this.parentNode.$jml.removeChild(this.$jml);
-
- if (this.oExt && this.oExt.parentNode)
- this.oExt.parentNode.removeChild(this.oExt);
-
- //Signal myself
- var i, l, callbacks = this.$domHandlers["remove"];
- if (callbacks) {
- for (i = 0, l = callbacks.length; i < l; i++) {
- callbacks[i].call(this, doOnlyAdmin);
- }
- }
-
- //Signal parent
- callbacks = (this.parentNode.$domHandlers || {})["removechild"];
- if (callbacks) {
- for (i = 0, l = callbacks.length; i < l; i++) {
- callbacks[i].call(this.parentNode, this, doOnlyAdmin);
- }
- }
- }
-
- if (this.parentNode.firstChild == this)
- this.parentNode.firstChild = this.nextSibling;
- if (this.parentNode.lastChild == this)
- this.parentNode.lastChild = this.previousSibling;
-
- if (this.nextSibling)
- this.nextSibling.previousSibling = this.previousSibling;
- if (this.previousSibling)
- this.previousSibling.nextSibling = this.nextSibling;
-
- this.pHtmlNode =
- this.parentNode =
- this.previousSibling =
- this.nextSibling = null;
-
- return this;
- };
-
- /**
- * Removes a child from the node list of this element.
- */
- this.removeChild = function(childNode) {
- if (!childNode || !childNode.nodeFunc) {
- throw new Error(jpf.formatErrorString(0, this,
- "Removing a child node",
- "Invalid Argument. removeChild() requires one argument of type JMLElement."));
- }
-
- childNode.removeNode();
- };
-
- /**
- * Returns a list of elements with the given tag name.
- * The subtree below the specified element is searched, excluding the
- * element itself.
- *
- * @method
- * @param {String} tagName the tag name to look for. The special string "*" represents any tag name.
- * @return {NodeList} containing any node matching the search string
- */
- this.getElementsByTagName = function(tagName, norecur){
- tagName = tagName.toLowerCase();
- for (var result = [], i = 0; i < this.childNodes.length; i++) {
- if (this.childNodes[i].tagName == tagName || tagName == "*")
- result.push(this.childNodes[i]);
- if (!norecur)
- result = result.concat(this.childNodes[i].getElementsByTagName(tagName));
- }
- return result;
- };
-
- /**
- * Clones this element, creating an exact copy of it but does not insert
- * it in the document hierarchy.
- * @param {Boolean} deep whether the element's are cloned recursively.
- * @return {JmlNode} the cloned element.
- */
- this.cloneNode = function(deep){
- var jml = this.serialize(true, true, !deep);
- return jpf.document.createElement(jml);
- };
-
- /**
- * Serializes this element to a string. The string created can be put into
- * a parser to recreate a copy of this node and it's children.
- * @return {String} the string representation of this element.
- */
- this.serialize = function(returnXml, skipFormat, onlyMe){
- var node = this.$jml.cloneNode(false);
- for (var name, i = 0; i < (this.$supportedProperties || []).length; i++) {
- name = this.$supportedProperties[i];
- if (this.getProperty(name) !== undefined)
- node.setAttribute(name, String(this.getProperty(name)).toString());
- }
-
- if (!onlyMe) {
- var l, nodes = this.childNodes;
- for (i = 0, l = nodes.length; i < l; i++) {
- node.appendChild(nodes[i].serialize(true));
- }
- }
-
- return returnXml
- ? node
- : (skipFormat
- ? node.xml || node.serialize()
- : jpf.formatXml(node.xml || node.serialize()));
- };
-
- /**
- * Sets an attribute on this element.
- * @param {String} name the name of the attribute to which the value is set
- * @param {String} value the new value of the attribute.
- */
- this.setAttribute = function(name, value) {
- if (this.$jml)
- this.$jml.setAttribute(name, (value || "").toString());
-
- if (name.indexOf("on") === 0) { //@todo this is bollocks. Should remove previous set onxxx
- this.addEventListener(name, typeof value == "string"
- ? new Function(value)
- : value);
- return;
- }
-
- if (this.nodeFunc == jpf.NODE_VISIBLE && !this.oExt)
- return;
-
- if (jpf.dynPropMatch.test(value))
- this.setDynamicProperty(name, value);
- else
- if (this.setProperty)
- this.setProperty(name, value);
- else
- this[name] = value;
- };
-
- /**
- * Removes an attribute from this element
- * @param {String} name the name of the attribute to remove.
- */
- this.removeAttribute = function(name){
- //Should deconstruct dynamic properties
-
- this.setProperty(name, null);
- };
-
- /**
- * Retrieves the value of an attribute of this element
- * @param {String} name the name of the attribute for which to return the value.
- * @return {String} the value of the attribute or null if none was found with the name specified.
- * @method
- */
- this.getAttribute = this.getProperty || function(name){
- return this[name];
- };
-
- /**
- * Retrieves the attribute node for a given name
- * @param {String} name the name of the attribute to find.
- * @return {JmlNode} the attribute node or null if none was found with the name specified.
- */
- this.getAttributeNode = function(name){
- return this.attributes.getNamedItem(name);
- }
-
- /**** Xpath support ****/
-
- /**
- * Queries the jml dom using the W3C xPath query language and returns a node
- * list. This is not an official API call but can be useful in certain cases.
- * see {@link core.jpf.object.document.method.evaluate}
- * @param {String} sExpr the xpath expression to query the jml DOM tree with.
- * @param {JmlNode} contextNode the element that serves as the starting point of the search. Defaults to this element.
- * @returns {NodeList} list of found nodes.
- */
- this.selectNodes = function(sExpr, contextNode){
- return jpf.XPath.selectNodes(sExpr,
- contextNode || (this.nodeType == 9 ? this.documentElement : this));
- };
-
- /**
- * Queries the jml dom using the W3C xPath query language and returns a single
- * node. This is not an official API call but can be useful in certain cases.
- * see {@link core.jpf.object.document.method.evaluate}
- * @param {String} sExpr the xpath expression to query the jml DOM tree with.
- * @param {JmlNode} contextNode the element that serves as the starting point of the search. Defaults to this element.
- * @returns {JmlNode} the first node that matches the query.
- */
- this.selectSingleNode = function(sExpr, contextNode){
- return jpf.XPath.selectNodes(sExpr,
- contextNode || (this.nodeType == 9 ? this.documentElement : this))[0];
- };
-
- /**** properties ****/
-
- /**
- * {NodeList} list of all attributes
- */
- this.attributes = {
- getNamedItem : function(name){
- return {
- nodeType : 2,
- nodeName : name,
- nodeValue : _self[name] || ""
- }
- },
- setNamedItem : function(node){
- if (!node || node.nodeType != 2) {
- throw new Error(jpf.formatError(0, _self,
- "Setting attribute",
- "Invalid node passed to setNamedItem"));
- }
-
- _self.setAttribute(node.name, node.value);
- },
- removeNamedItem : function(name){
- if (!_self[name]) {
- throw new Error(jpf.formatError(0, _self,
- "Removing attribute",
- "Attribute isn't set"));
- }
-
- _self.removeAttribute(name);
- },
- length : function(){
- return _self.$jml && _self.$jml.attributes.length
- || (_self.$supportedProperties || {length:0}).length; //@todo incorrect
- },
- item : function(i){
- if (_self.$jml && _self.$jml.attributes)
- return _self.$jml.attributes[i];
-
- var collection = _self.$supportedProperties;
- if (!collection[i])
- return false;
- return this.getNamedItem(collection[i]);
- }
- };
-
- this.nodeValue = "";
- this.namespaceURI = jpf.ns.jml;
-
- this.$setParent = function(pNode){
- if (pNode && pNode.childNodes.indexOf(this) > -1)
- return;
-
- this.parentNode = pNode;
- var nodes = this.parentNode.childNodes;
- var id = nodes.push(this) - 1;
-
- if (id === 0)
- this.parentNode.firstChild = this;
- else {
- var n = nodes[id - 1];
- if (n) {
- n.nextSibling = this;
- this.previousSibling = n || null;
- }
- this.parentNode.lastChild = this;
- }
- };
-
- if (this.parentNode && this.parentNode.hasFeature
- && this.parentNode.hasFeature(__WITH_JMLDOM__))
- this.$setParent(this.parentNode);
-};
- - -/*FILEHEAD(/var/lib/jpf/src/core/node/multiselect.js)SIZE(-1077090856)TIME(1238972565)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-var __MULTISELECT__ = 1 << 8;
-
-
-/**
- * Baseclass adding selection features to this element. This includes handling
- * for multiselect and several keyboard based selection interaction. It also
- * takes care of caret handling when multiselect is enabled.
- *
- * @constructor
- * @baseclass
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.5
- *
- * @inherits jpf.MultiselectBinding
- *
- * @binding select Determines wether the traverse node can be selected.
- * Example:
- * In this example the tree contains nodes that have a disabled flag set.
- * These nodes cannot be selected
- * <code>
- * <j:tree>
- * <j:bindings>
- * <j:select select="self::node()[not(@disabled)]" />
- * </j:bindings>
- * </j:tree>
- * </code>
- * @binding value Determines the way the value for the element is retrieved
- * from the selected node. The value property contains this value.
- * Example:
- * <code>
- * <j:dropdown onafterchange="alert(this.value)">
- * <j:bindings>
- * <j:caption select="text()" />
- * <j:value select="@value" />
- * <j:traverse select="item" />
- * </j:bindings>
- * <j:model>
- * <items>
- * <item value="#FF0000">red</item>
- * <item value="#00FF00">green</item>
- * <item value="#0000FF">blue</item>
- * </items>
- * </j:model>
- * </j:dropdown>
- * </code>
- */
-jpf.MultiSelect = function(){
- var noEvent;
- var selSmartbinding;
- var valueList = [];
- var selectedList = [];
- var _self = this;
-
- this.$regbase = this.$regbase|__MULTISELECT__;
-
- /**** Properties ****/
-
- /**
- * the last selected item of this element.
- * @type {XMLElement}
- */
- this.selected = null;
- this.$selected = null;
-
- /**
- * the xml element that has the caret.
- * @type {XMLElement}
- */
- this.indicator = null;
- this.$indicator = null;
-
- /**
- * wether to use a caret in the interaction of this element.
- * @type {Boolean}
- */
- this.useindicator = true;
-
-
- /**
- * Removes an xml data element from the data of this element.
- * Example:
- * A simple list showing products. This list is used in all following examples.
- * <code>
- * <j:list id="myList">
- * <j:bindings>
- * <j:caption select="@name" />
- * <j:value select="@id" />
- * <j:icon>{@type}.png</j:icon>
- * <j:traverse select="product" />
- * </j:bindings>
- * <j:model>
- * <products>
- * <product name="Soundblaster" type="audio" id="product10" />
- * <product name="Teapot" type="3d" id="product13" />
- * <product name="Coprocessor" type="chips" id="product15" />
- * <product name="Keyboard" type="input" id="product17" />
- * <product name="Diskdrive" type="storage" id="product20" />
- * </products>
- * </j:model>
- * </j:list>
- * </code>
- * Example:
- * This example selects a product by it's value and then removes the
- * selection.
- * <code>
- * myList.setValue("product20");
- * myList.remove();
- * </code>
- * Example:
- * This example gets a product by it's value and then removes it.
- * <code>
- * var xmlNode = myList.findXmlNodeByValue("product20");
- * myList.remove(xmlNode);
- * </code>
- * Example:
- * This example retrieves all nodes from a list. All items with a length
- * greater than 10 are singled out and removed.
- * <code>
- * var list = myList.getTraverseNodes(); //get all nodes from a list.
- * var removeList = [];
- * for (var i = 0; i < list.length; i++) {
- * if (list[i].getAttribute("length") > 10)
- * removeList.push(list[i]);
- * }
- * myList.remove(removeList); //remove the list of nodes
- * </code>
- * Remarks:
- * Another way to trigger this method is by using the action attribute on a
- * button.
- * <code>
- * <j:button action="remove" target="myList">Remove item</j:button>
- * </code>
- * Using the action methodology you can let the original data source
- * (usually the server) know that the user removed an item.
- * <code>
- * <j:actions>
- * <j:remove set="url:remove_product.php?id={@id}" />
- * </j:actions>
- * </code>
- * For undo this action should be extended and the server should maintain a
- * copy of the deleted item.
- * <code>
- * <j:actions>
- * <j:remove set="url:remove_product.php?id={@id}">
- * <j:undo set="url:undo_remove_product.php?id={@id}" />
- * </j:remove>
- * </j:actions>
- * </code>
- * @action
- * @param {mixed} [nodeList] the data element(s) to be removed. If none are specified, the current selection is removed.
- * Possible values:
- * {NodeList} the xml data elements to be removed.
- * {XMLElement} the data element to be removed.
- * @return {Boolean} specifies if the removal succeeded
- */
- this.remove = function(nodeList){
- //Use the current selection if no xmlNode is defined
- if (!nodeList)
- nodeList = valueList;
-
- //If we're an xml node let's convert
- if (nodeList.nodeType)
- nodeList = [nodeList];
-
- //If there is no selection we'll exit, nothing to do
- if (!nodeList || !nodeList.length)
- return;
-
- //We're not removing the XMLRoot, that would be suicide ;)
- if (nodeList.contains(this.xmlRoot)) {
- throw new Error(jpf.formatErrorString(0,
- "Removing nodes",
- "You are trying to delete the xml root of this \
- component. This is not allowed."));
- }
-
- var rValue;
- if (nodeList.length > 1 && (!this.actionRules
- || this.actionRules["removegroup"] || !this.actionRules["remove"])) {
- rValue = this.executeAction("removeNodeList", nodeList,
- "removegroup", nodeList[0]);
- }
- else {
- for (var i = 0; i < nodeList.length; i++) {
- rValue = this.executeAction("removeNode",
- [nodeList[i]], "remove", nodeList[i], null, null, true);
- if (rValue === false)
- return false;
- }
- }
-
- return rValue;
- };
-
- /**
- * Adds an xml data element to the data of this element.
- * Example:
- * A simple list showing products. This list is used in all following examples.
- * <code>
- * <j:list id="myList">
- * <j:bindings>
- * <j:caption select="@name" />
- * <j:value select="@id" />
- * <j:icon>{@type}.png</j:icon>
- * <j:traverse select="product" />
- * </j:bindings>
- * <j:model>
- * <products>
- * <product name="Soundblaster" type="audio" id="product10" />
- * <product name="Teapot" type="3d" id="product13" />
- * <product name="Coprocessor" type="chips" id="product15" />
- * <product name="Keyboard" type="input" id="product17" />
- * <product name="Diskdrive" type="storage" id="product20" />
- * </products>
- * </j:model>
- * </j:list>
- * </code>
- * Example:
- * This example adds a product to this element.
- * selection.
- * <code>
- * myList.add('<product name="USB drive" type="storage" />');
- * </code>
- * Example:
- * This example copy's the selected product, changes it's name and then
- * adds it. After selecting the new node the user is offered a rename input
- * box.
- * <code>
- * var xmlNode = jpf.xmldb.copy(myList.selected);
- * xmlNode.setAttribute("name", "New product");
- * myList.add(xmlNode);
- * myList.select(xmlNode);
- * myList.startRename();
- * </code>
- * Remarks:
- * Another way to trigger this method is by using the action attribute on a
- * button.
- * <code>
- * <j:button action="add" target="myList">Add new product</j:button>
- * </code>
- * Using the action methodology you can let the original data source
- * (usually the server) know that the user added an item.
- * <code>
- * <j:actions>
- * <j:add set="rpc:comm.addProduct({.})" />
- * </j:actions>
- * </code>
- * For undo this action should be extended as follows.
- * <code>
- * <j:actions>
- * <j:add set="url:add_product.php?id={.}">
- * <j:undo set="url:remove_product.php?id={@id}" />
- * </j:add>
- * </j:actions>
- * </code>
- * In some cases the server needs to create the new product before it's
- * added. This is done as follows.
- * <code>
- * <j:actions>
- * <j:add get="rpc:comm.createNewProduct()" />
- * </j:actions>
- * </code>
- * Alternatively the template for the addition can be provided as a child of
- * the action rule.
- * <code>
- * <j:actions>
- * <j:add set="url:add_product.php?id={.}">
- * <product name="USB drive" type="storage" />
- * </j:add>
- * </j:actions>
- * </code>
- * @action
- * @param {XMLElement} [xmlNode] the xml data element which is added. If none is specified the action will use the action rule to try to retrieve a new node to add.
- * @param {XMLElement} [pNode] the parent node of the added xml data element.
- * @param {XMLElement} [beforeNode] the position where the xml element should be inserted.
- * @return {XMLElement} the added xml data element or false on failure.
- */
- this.add = function(xmlNode, pNode, beforeNode){
- var node;
-
- if (this.actionRules) {
- if (xmlNode && xmlNode.nodeType)
- node = this.getNodeFromRule("add", xmlNode, true);
- else if (typeof xmlNode == "string") {
- if (xmlNode.trim().charAt(0) == "<") {
- xmlNode = jpf.getXml(xmlNode);
- node = this.getNodeFromRule("add", xmlNode, true);
- }
- else {
- var rules = this.actionRules["add"];
- for (var i = 0, l = rules.length; i < l; i++) {
- if (rules[i].getAttribute("type") == xmlNode) {
- xmlNode = null;
- node = rules[i];
- break;
- }
- }
- }
- }
-
- if (!node && this.actionRules["add"])
- node = this.actionRules["add"][0];
- }
- else
- node = null;
-
- var bHasOffline = (typeof jpf.offline != "undefined");
- if (bHasOffline && !jpf.offline.canTransact())
- return false;
-
- if (bHasOffline && !jpf.offline.onLine && (!xmlNode || !node.getAttribute("get")))
- return false;
-
- var refNode = this.isTreeArch ? this.selected || this.xmlRoot : this.xmlRoot;
- var jmlNode = this; //PROCINSTR
- var callback = function(addXmlNode, state, extra){
- if (state != jpf.SUCCESS) {
- var oError;
-
- oError = new Error(jpf.formatErrorString(1032, jmlNode,
- "Loading xml data",
- "Could not add data for control " + jmlNode.name
- + "[" + jmlNode.tagName + "] \nUrl: " + extra.url
- + "\nInfo: " + extra.message + "\n\n" + xmlNode));
-
- if (extra.tpModule.retryTimeout(extra, state, jmlNode, oError) === true)
- return true;
-
- throw oError;
- }
-
- if (typeof addXmlNode != "object")
- addXmlNode = jpf.getXmlDom(addXmlNode).documentElement;
- if (addXmlNode.getAttribute(jpf.xmldb.xmlIdTag))
- addXmlNode.setAttribute(jpf.xmldb.xmlIdTag, "");
-
- var actionNode = jmlNode.getNodeFromRule("add", jmlNode.isTreeArch
- ? jmlNode.selected
- : jmlNode.xmlRoot, true, true);
- if (!pNode) {
- if (actionNode && actionNode.getAttribute("parent")) {
- pNode = jmlNode.xmlRoot
- .selectSingleNode(actionNode.getAttribute("parent"));
- }
- else {
- pNode = jmlNode.isTreeArch
- ? jmlNode.selected || jmlNode.xmlRoot
- : jmlNode.xmlRoot
- }
- }
-
- if (!pNode)
- pNode = jmlNode.xmlRoot;
-
- if (jpf.isSafari && pNode.ownerDocument != addXmlNode.ownerDocument)
- addXmlNode = pNode.ownerDocument.importNode(addXmlNode, true); //Safari issue not auto importing nodes
-
- if (jmlNode.executeAction("appendChild",
- [pNode, addXmlNode, beforeNode], "add", addXmlNode) !== false
- && jmlNode.autoselect)
- jmlNode.select(addXmlNode);
-
- return addXmlNode;
- }
-
- if (xmlNode)
- return callback(xmlNode, jpf.SUCCESS);
- else {
- if (!node) {
- throw new Error(jpf.formatErrorString(0, this,
- "Executing add action",
- "Missing add action defined in action rules. Unable to \
- perform action."));
- }
-
- if (node.getAttribute("get"))
- return jpf.getData(node.getAttribute("get"), refNode, null, callback)
- else if (node.firstChild) {
- var node = jpf.getNode(node, [0]);
- if (jpf.supportNamespaces && node.namespaceURI == jpf.ns.xhtml) {
- node = jpf.getXml(node.xml.replace(/xmlns\=\"[^"]*\"/g, ""));
- //@todo import here for webkit?
- }
- else node = node.cloneNode(true);
-
- return callback(node, jpf.SUCCESS);
- }
- }
-
- return addXmlNode;
- };
-
- if (!this.setValue) {
- /**
- * Sets the value of this element.The value
- * corresponds to an item in the list of loaded data elements. This
- * element will receive the selection. If no data element is found, the
- * selection is cleared.
- *
- * @param {String} value the new value for this element.
- * @param {Boolean} disable_event
- * @see baseclass.multiselect.method.getValue
- */
- this.setValue = function(value, disable_event){
- noEvent = disable_event;
- this.setProperty("value", value);
- noEvent = false;
- };
- }
-
- /**
- * Retrieves an xml data element that has a value that corresponds to the
- * string that is searched on.
- * @param {String} value the value to match.
- */
- this.findXmlNodeByValue = function(value){
- var nodes = this.getTraverseNodes();
- var bindSet = this.bindingRules && this.bindingRules[this.mainBind]
- ? this.mainBind
- : (this.valuerule ? "value" : "caption");
-
- for (var i = 0; i < nodes.length; i++) {
- if (this.applyRuleSetOnNode(bindSet, nodes[i]) == value)
- return nodes[i];
- }
- };
-
- if (!this.getValue) {
- /**
- * Retrieves the value of this element. This is the value of the
- * first selected data element.
- * @see #setValue
- */
- this.getValue = function(xmlNode){
- if (!this.bindingRules && !this.caption)
- return false;
-
- if (!this.caption && !this.bindingRules[this.mainBind] && !this.bindingRules["caption"])
- throw new Error(jpf.formatErrorString(1074, this,
- "getValue Method",
- "Could not find default value bind rule for this control."));
-
- if (!this.multiselect && !this.xmlRoot && selSmartbinding && selSmartbinding.xmlRoot)
- return selSmartbinding.applyRuleSetOnNode(selSmartbinding.mainBind,
- selSmartbinding.xmlRoot, null, true);
-
- return this.applyRuleSetOnNode(this.mainBind, xmlNode || this.selected, null, true)
- || this.applyRuleSetOnNode("caption", xmlNode || this.selected, null, true);
-
- };
- }
- /**
- * Sets the second level SmartBinding for Multilevel Databinding.
- * For more information see {@link baseclass.multilevelbinding}
- *
- * @return {SmartBinding}
- * @see baseclass.multiselect.method.getSelectionBindClass
- * @private
- */
- this.$setMultiBind = function(smartbinding, part){
- if (!selSmartbinding)
- selSmartbinding = new jpf.MultiLevelBinding(this);
-
- selSmartbinding.setSmartBinding(smartbinding, part);
-
- this.dispatchEvent("initselbind", {smartbinding : selSmartbinding});
- };
-
- /**
- * Gets the {@link baseclass.multilevelbinding} for this element.
- * @return {MultiLevelBinding} the {@link baseclass.multilevelbinding} for this element.
- */
- this.getMultibinding = function(){
- return selSmartbinding;
- }
- /**
- * Gets the second level SmartBinding for Multilevel Databinding.
- * For more information see {@link baseclass.multilevelbinding}
- *
- * @return {SmartBinding}
- * @see baseclass.multiselect.method.setSelectionBindClass
- * @private
- */
- this.$getMultiBind = function(){
- return (selSmartbinding
- || (selSmartbinding = new jpf.MultiLevelBinding(this)));
- };
-
- /**
- * Select the current selection again.
- *
- * @todo Add support for multiselect
- */
- this.reselect = function(){
- if (this.selected) this.select(this.selected, null, this.ctrlselect,
- null, true);//no support for multiselect currently.
- };
-
- /**
- * Selects a single, or set of {@info TraverseNodes "Traverse Nodes"}.
- * The selection can be visually represented in this element.
- *
- * @param {mixed} xmlNode the identifier to determine the selection.
- * Possible values:
- * {XMLElement} the xml data element to be used in the selection as a start/end point or to toggle the selection on the node.
- * {HTMLElement} the html element node used as visual representation of data node. Used to determine the xml data element for selection.
- * {String} the value of the xml data element to be select.
- * @param {Boolean} [ctrlKey] whether the Ctrl key was pressed
- * @param {Boolean} [shiftKey] whether the Shift key was pressed
- * @param {Boolean} [fakeselect] whether only visually a selection is made
- * @param {Boolean} [force] whether reselect is forced.
- * @param {Boolean} [noEvent] whether to not call any events
- * @return {Boolean} whether the selection could be made
- *
- * @event beforeselect Fires before a selection is made
- * object:
- * {XMLElement} xmlNode the xml data element that will be selected.
- * {HTMLElement} htmlNode the html element that visually represents the xml data element.
- * @event afterselect Fires after a selection is made
- * object:
- * {XMLElement} xmlNode the xml data element that was selected.
- * {HTMLElement} htmlNode the html element that visually represents the xml data element.
- */
- var buffered = null;
- this.select = function(xmlNode, ctrlKey, shiftKey, fakeselect, force, noEvent){
- if (!this.selectable || this.disabled) return;
-
- if (this.ctrlselect && !shiftKey)
- ctrlKey = true;
-
- // Selection buffering (for async compatibility)
- if (!this.xmlRoot) {
- buffered = [arguments, this.autoselect];
- this.autoselect = true;
- return;
- }
-
- if (buffered) {
- var x = buffered;
- buffered = null;
- if (this.autoselect)
- this.autoselect = x[1];
- return this.select.apply(this, x[0]);
- }
-
- var htmlNode;
-
- /* **** Type Detection *****/
- if (!xmlNode) {
- throw new Error(jpf.formatErrorString(1075, this,
- "Making a selection",
- "No selection was specified"))
-
- return false;
- }
-
- if (typeof xmlNode != "object") {
- var str = xmlNode;
- xmlNode = jpf.xmldb.getNodeById(xmlNode);
-
- //Select based on the value of the xml node
- if (!xmlNode) {
- xmlNode = this.findXmlNodeByValue(str);
- if (!xmlNode) {
- this.clearSelection(null, noEvent);
- return;
- }
- }
- }
-
- if (!xmlNode.style)
- htmlNode = this.caching
- ? this.getNodeFromCache(xmlNode.getAttribute(
- jpf.xmldb.xmlIdTag) + "|" + this.uniqueId)
- : document.getElementById(xmlNode.getAttribute(
- jpf.xmldb.xmlIdTag) + "|" + this.uniqueId); //IE55
- else {
- var id = (htmlNode = xmlNode).getAttribute(jpf.xmldb.htmlIdTag);
- while (!id && htmlNode.parentNode)
- id = (htmlNode = htmlNode.parentNode).getAttribute(
- jpf.xmldb.htmlIdTag);
-
- xmlNode = jpf.xmldb.getNodeById(id, this.xmlRoot);
- }
-
- if(this.dispatchEvent('beforeselect', {
- xmlNode : xmlNode,
- htmlNode : htmlNode,
- ctrlKey : ctrlKey,
- shiftKey : shiftKey,
- captureOnly : noEvent
- }) === false)
- return false;
-
- /**** Selection ****/
-
- var lastIndicator = this.indicator;
- this.indicator = xmlNode;
-
- //Multiselect with SHIFT Key.
- if (shiftKey && this.multiselect) {
- var range = this.$calcSelectRange(valueList[0] || lastIndicator,
- xmlNode);
-
- if (this.$indicator)
- this.$deindicate(this.$indicator);
-
- this.selectList(range);
-
- this.$selected =
- this.$indicator = this.$indicate(htmlNode);
- }
- else if (ctrlKey && this.multiselect) { //Multiselect with CTRL Key.
- //Node will be unselected
- if (valueList.contains(xmlNode)) {
- if (!fakeselect) {
- selectedList.remove(htmlNode);
- valueList.remove(xmlNode);
- }
-
- if (this.selected == xmlNode) {
- var ind = this.$indicator;
- this.clearSelection(true, true);
- this.$deindicate(ind);
-
- if (valueList.length && !fakeselect) {
- //this.$selected = selectedList[0];
- this.selected = valueList[0];
- }
- }
- else
- this.$deselect(htmlNode, xmlNode);
-
- if (htmlNode != this.$indicator)
- this.$deindicate(this.$indicator);
-
- this.$selected =
- this.$indicator = this.$indicate(htmlNode);
- }
- // Node will be selected
- else {
- if (this.$indicator)
- this.$deindicate(this.$indicator);
- this.$indicator = this.$indicate(htmlNode);
-
- this.$selected = this.$select(htmlNode);
- this.selected = xmlNode;
-
- if (!fakeselect) {
- selectedList.push(htmlNode);
- valueList.push(xmlNode);
- }
- }
- }
- else if (htmlNode && selectedList.contains(htmlNode) && fakeselect) //Return if selected Node is htmlNode during a fake select
- return;
- else { //Normal Selection
- if (!force && htmlNode && this.$selected == htmlNode
- && valueList.length <= 1 && !this.reselectable
- && selectedList.contains(htmlNode))
- return;
-
- if (this.$selected)
- this.$deselect(this.$selected);
- if (this.$indicator)
- this.$deindicate(this.$indicator);
- if (this.selected)
- this.clearSelection(null, true);
-
- this.$indicator = this.$indicate(htmlNode, xmlNode);
- this.$selected = this.$select(htmlNode, xmlNode);
- this.selected = xmlNode;
-
- selectedList.push(htmlNode);
- valueList.push(xmlNode);
- }
-
- if (this.delayedselect && (typeof ctrlKey == "boolean")){
- var jNode = this;
- setTimeout(function(){
- jNode.dispatchEvent("afterselect", {
- list : valueList,
- xmlNode : xmlNode,
- captureOnly : noEvent
- });
- }, 10);
- }
- else
- this.dispatchEvent("afterselect", {
- list : valueList,
- xmlNode : xmlNode,
- captureOnly : noEvent
- });
-
- return true;
- };
-
- /**
- * Choose a selected item. This is done by double clicking on the item or
- * pressing the Enter key.
- *
- * @param {mixed} xmlNode the identifier to determine the selection.
- * Possible values:
- * {XMLElement} the xml data element to be choosen.
- * {HTMLElement} the html element node used as visual representation of data node. Used to determine the xml data element.
- * {String} the value of the xml data element to be choosen.
- * @event beforechoose Fires before a choice is made.
- * object:
- * {XMLElement} xmlNode the xml data element that was choosen.
- * @event afterchoose Fires after a choice is made.
- * object:
- * {XMLElement} xmlNode the xml data element that was choosen.
- */
- this.choose = function(xmlNode){
- if (!this.selectable || this.disabled) return;
-
- if (this.dispatchEvent("beforechoose", {xmlNode : xmlNode}) === false)
- return false;
-
- if (xmlNode && !xmlNode.style)
- this.select(xmlNode);
-
- if (this.hasFeature(__DATABINDING__)
- && this.dispatchEvent("afterchoose", {xmlNode : this.selected}) !== false)
- this.setConnections(this.selected, "choice");
- };
-
- /**
- * Removes the selection of one or more selected nodes.
- *
- * @param {Boolean} [singleNode] whether to only deselect the indicated node
- * @param {Boolean} [noEvent] whether to not call any events
- * @event beforedeselect before a choice is made
- * object:
- * {XMLElement} xmlNode the xml data element that will be deselected.
- * @event afterdeselect after a choice is made
- * object:
- * {XMLElement} xmlNode the xml data element that is deselected.
- */
- this.clearSelection = function(singleNode, noEvent){
- if (!this.selectable || this.disabled)
- return;
-
- var clSel = singleNode ? this.selected : valueList;
- if (!noEvent && this.dispatchEvent("beforedeselect", {
- xmlNode : clSel
- }) === false)
- return false;
-
- var htmlNode;
- if (this.selected) {
- htmlNode = this.caching
- ? this.getNodeFromCache(this.selected.getAttribute(
- jpf.xmldb.xmlIdTag) + "|" + this.uniqueId)
- : document.getElementById(this.selected.getAttribute(
- jpf.xmldb.xmlIdTag) + "|" + this.uniqueId); //IE55
- this.$deselect(htmlNode);
- }
-
- //if(this.$selected) this.$deselect(this.$selected);
- this.$selected = this.selected = null;
-
- if (!singleNode) {
- for (var i = valueList.length - 1; i >= 0; i--) {
- htmlNode = this.caching
- ? this.getNodeFromCache(valueList[i].getAttribute(
- jpf.xmldb.xmlIdTag) + "|" + this.uniqueId)
- : document.getElementById(valueList[i].getAttribute(
- jpf.xmldb.xmlIdTag) + "|" + this.uniqueId); //IE55
- this.$deselect(htmlNode);
- }
- //for(var i=selectedList.length-1;i>=0;i--) this.$deselect(selectedList[i]);
- selectedList = [];
- valueList = [];
- }
-
- if (this.indicator) {
- htmlNode = this.caching
- ? this.getNodeFromCache(this.indicator.getAttribute(
- jpf.xmldb.xmlIdTag) + "|" + this.uniqueId)
- : document.getElementById(this.indicator.getAttribute(
- jpf.xmldb.xmlIdTag) + "|" + this.uniqueId); //IE55
-
- this.$selected =
- this.$indicator = this.$indicate(htmlNode);
- }
-
- if (!noEvent) {
- this.dispatchEvent("afterdeselect", {xmlNode : clSel});
-
- if (this.value)
- this.setProperty("value", "");
- }
- };
-
- /**
- * Selects a set of items
- *
- * @param {Array} xmlNodeList the xml data elements that will be selected.
- */
- //@todo I think there are missing events here?
- this.selectList = function(xmlNodeList, noEvent, selected){
- if (!this.selectable || this.disabled) return;
-
- if (this.dispatchEvent("beforeselect", {
- xmlNode : selected,
- captureOnly : noEvent
- }) === false)
- return false;
-
- this.clearSelection(null, true);
-
- for (var sel, i=0;i<xmlNodeList.length;i++) {
- if (!xmlNodeList[i] || xmlNodeList[i].nodeType != 1) continue; //@todo fix select state in unserialize after removing
- var xmlNode = xmlNodeList[i];
-
- //Type Detection
- if (typeof xmlNode != "object")
- xmlNode = jpf.xmldb.getNodeById(xmlNode);
- if (!xmlNode.style)
- htmlNode = this.$findNode(null, xmlNode.getAttribute(
- jpf.xmldb.xmlIdTag) + "|" + this.uniqueId); //IE55
- else {
- htmlNode = xmlNode;
- xmlNode = jpf.xmldb.getNodeById(htmlNode.getAttribute(
- jpf.xmldb.htmlIdTag));
- }
-
- if (!xmlNode) {
- jpf.console.warn("Component : " + this.name + " ["
- + this.tagName + "]\nMessage : xmlNode whilst selecting a list of xmlNodes could not be found. Ignoring.")
- continue;
- }
-
- //Select Node
- if (htmlNode) {
- if (!sel && selected == htmlNode)
- sel = htmlNode;
-
- this.$select(htmlNode);
- selectedList.push(htmlNode);
- }
- valueList.push(xmlNode);
- }
-
- this.$selected = sel || selectedList[0];
- this.selected = selected || valueList[0];
-
- this.dispatchEvent("afterselect", {
- list : valueList,
- xmlNode : this.selected,
- captureOnly : noEvent
- });
- };
-
- /**
- * Sets the caret on an item to indicate to the user that the keyboard
- * actions are done relevant to that item. Using the keyboard
- * a user can change the position of the indicator using the Ctrl and arrow
- * keys while not making a selection. When making a selection with the mouse
- * or keyboard the indicator is always set to the selected node. Unlike a
- * selection there can be only one indicator item.
- *
- * @param {mixed} xmlNode the identifier to determine the indicator.
- * Possible values:
- * {XMLElement} the xml data element to be set as indicator.
- * {HTMLElement} the html element node used as visual representation of data node. Used to determine the xml data element.
- * {String} the value of the xml data element to be set as indicator.
- * @event indicate Fires when an item becomes the indicator.
- */
- this.setIndicator = function(xmlNode){
- if (!xmlNode) {
- if (this.$indicator)
- this.$deindicate(this.$indicator);
- this.indicator =
- this.$indicator = null;
- return;
- }
-
- /* **** Type Detection *****/
- var htmlNode;
- if (typeof xmlNode != "object")
- xmlNode = jpf.xmldb.getNodeById(xmlNode);
- if (!xmlNode.style)
- htmlNode = this.caching
- ? this.getNodeFromCache(xmlNode.getAttribute(
- jpf.xmldb.xmlIdTag) + "|" + this.uniqueId)
- : document.getElementById(xmlNode.getAttribute(
- jpf.xmldb.xmlIdTag) + "|" + this.uniqueId); //IE55
- else {
- var id = (htmlNode = xmlNode).getAttribute(jpf.xmldb.htmlIdTag);
- while (!id && htmlNode.parentNode)
- id = (htmlNode = htmlNode.parentNode).getAttribute(
- jpf.xmldb.htmlIdTag);
-
- xmlNode = jpf.xmldb.getNodeById(id);
- }
-
- if (this.$indicator)
- this.$deindicate(this.$indicator);
- this.indicator = xmlNode;
- this.$indicator = this.$indicate(htmlNode);
-
- this.dispatchEvent("indicate");
- };
-
- /**
- * @private
- */
- this.setTempSelected = function(xmlNode, ctrlKey, shiftKey){
- clearTimeout(this.timer);
-
- if (ctrlKey || this.ctrlselect) {
- if (this.$tempsel) {
- this.select(this.$tempsel);
- this.$tempsel = null;
- }
-
- this.setIndicator(xmlNode);
- }
- else if (shiftKey){
- if (this.$tempsel) {
- this.$deselect(this.$tempsel);
- this.$tempsel = null;
- }
-
- this.select(xmlNode, null, shiftKey);
- }
- else if (!this.bufferselect) {
- this.select(xmlNode);
- }
- else {
- var id = jpf.xmldb.getID(xmlNode, this);
-
- this.$deselect(this.$tempsel || this.$selected);
- this.$deindicate(this.$tempsel || this.$indicator);
- this.$tempsel = this.$indicate(document.getElementById(id));
- this.$select(this.$tempsel);
-
- this.timer = setTimeout(function(){
- _self.selectTemp();
- }, 400);
- }
- };
-
- /**
- * @private
- */
- this.selectTemp = function(){
- if (!this.$tempsel)
- return;
-
- clearTimeout(this.timer);
- this.select(this.$tempsel);
- this.$tempsel = null;
- this.timer = null;
- };
-
- /**
- * Selects all the {@info TraverseNodes "Traverse Nodes"} of this element
- *
- */
- this.selectAll = function(){
- if (!this.multiselect || !this.selectable
- || this.disabled || !this.$selected)
- return;
-
- var nodes = this.getTraverseNodes();
- //this.select(nodes[0]);
- //this.select(nodes[nodes.length-1], null, true);
- this.selectList(nodes);
- };
-
- /**
- * Retrieves an array or a document fragment containing all the selected
- * xml data elements from this element.
- *
- * @param {Boolean} [xmldoc] whether the method should return a document fragment.
- * @return {mixed} the selection of this element.
- */
- this.getSelection = function(xmldoc){
- var i, r;
- if (xmldoc) {
- r = this.xmlRoot
- ? this.xmlRoot.ownerDocument.createDocumentFragment()
- : jpf.getXmlDom().createDocumentFragment();
- for (i = 0; i < valueList.length; i++)
- jpf.xmldb.clearConnections(r.appendChild(
- valueList[i].cloneNode(true)));
- }
- else
- for (r = [], i = 0; i < valueList.length; i++)
- r.push(valueList[i]);
-
- return r;
- };
-
- /**
- * Selects the next xml data element to be selected.
- *
- * @param {XMLElement} xmlNode the context data element.
- * @param {Boolean} isTree
- */
- this.defaultSelectNext = function(xmlNode, isTree){
- var next = this.getNextTraverseSelected(xmlNode);
- //if(!next && xmlNode == this.xmlRoot) return;
-
- //Why not use this.isTreeArch ??
- if (next || !isTree)
- this.select(next ? next : this.getTraverseParent(xmlNode));
- else
- this.clearSelection(null, true);
- };
-
- /**
- * Selects the next xml data element when available.
- */
- this.selectNext = function(){
- var xmlNode = this.getNextTraverse();
- if (xmlNode)
- this.select(xmlNode);
- };
-
- /**
- * Selects the previous xml data element when available.
- */
- this.selectPrevious = function(){
- var xmlNode = this.getNextTraverse(null, -1);
- if (xmlNode)
- this.select(xmlNode);
- };
-
- /**
- * @private
- */
- this.getDefaultNext = function(xmlNode, isTree){
- var next = this.getNextTraverseSelected(xmlNode);
- //if(!next && xmlNode == this.xmlRoot) return;
-
- return (next && next != xmlNode)
- ? next
- : (isTree
- ? this.getTraverseParent(xmlNode)
- : null); //this.getFirstTraverseNode()
- };
-
- /**
- * Determines whether a node is selected.
- *
- * @param {XMLElement} xmlNode The xml data element to be checked.
- * @return {Boolean} whether the element is selected.
- */
- this.isSelected = function(xmlNode){
- if (!xmlNode) return false;
-
- for (var i = 0; i < valueList.length; i++) {
- if (valueList[i] == xmlNode)
- return true;
- }
-
- return false;
- };
-
- /**
- * This function checks whether the current selection is still correct.
- * Selection can become invalid when updates to the underlying data
- * happen. For instance when a selected node is removed.
- */
- this.$checkSelection = function(nextNode){
- if (valueList.length > 1) {
- //Fix selection if needed
- for (var lst = [], i = 0, l = valueList.length; i < l; i++) {
- if (jpf.xmldb.isChildOf(this.xmlRoot, valueList[i]))
- lst.push(valueList[i]);
- }
-
- if (lst.length > 1) {
- this.selectList(lst);
- if(this.indicator
- && !jpf.xmldb.isChildOf(this.xmlRoot, this.indicator)) {
- this.setIndicator(nextNode || this.selected);
- }
- return;
- }
- else if (lst.length) {
- //this.clearSelection(null, true); //@todo noEvents here??
- nextNode = lst[0];
- }
- }
-
- if (!nextNode) {
- if (this.selected
- && !jpf.xmldb.isChildOf(this.xmlRoot, this.selected)) {
- nextNode = this.getFirstTraverseNode();
- }
- else if(this.selected && this.indicator
- && !jpf.xmldb.isChildOf(this.xmlRoot, this.indicator)) {
- this.setIndicator(this.selected);
- }
- else if (!this.selected){
- nextNode = this.xmlRoot
- ? this.getFirstTraverseNode()
- : null;
- }
- else {
- return; //Nothing to do
- }
- }
-
- if (nextNode) {
- if (this.autoselect) {
- this.select(nextNode);
- }
- else {
- if (!this.multiselect)
- this.clearSelection();
- this.setIndicator(nextNode);
- }
- }
- else
- this.clearSelection();
-
- //if(action == "synchronize" && this.autoselect) this.reselect();
- };
-
- /**
- * @attribute {Boolean} [multiselect] whether the user may select multiple items. Default is true, false for j:dropdown
- * @attribute {mixed} [autoselect]
- * Possible values:
- * {Boolean} whether a selection is made after data is loaded. Default is true, false for j:Dropdown.
- * {String}
- * Possible values:
- * all all items are selected after data is loaded.
- * @attribute {Boolean} [selectable] whether this element can receive a selection.
- * @attribute {Boolean} [ctrlselect] whether the user makes a selection as if it was holding the Ctrl key.
- * @attribute {Boolean} [allowdeselect] whether the user can remove the selection of an element.
- * @attribute {Boolean} [reselectable] whether selected nodes can be selected again such that the select events are called.
- * @attribute {String} [default] the value that this component has when no selection is made, or no value is loaded.
- */
- this.selectable = true;
- if (this.ctrlselect === undefined)
- this.ctrlselect = false;
- if (this.multiselect === undefined)
- this.multiselect = true;
- if (this.autoselect === undefined)
- this.autoselect = true;
- if (this.delayedselect === undefined)
- this.delayedselect = true;
- if (this.allowdeselect === undefined)
- this.allowdeselect = true;
- this.reselectable = false;
-
- this.$booleanProperties["selectable"] = true;
- //this.$booleanProperties["ctrlselect"] = true;
- this.$booleanProperties["multiselect"] = true;
- this.$booleanProperties["autoselect"] = true;
- this.$booleanProperties["delayedselect"] = true;
- this.$booleanProperties["allowdeselect"] = true;
- this.$booleanProperties["reselectable"] = true;
-
- this.$supportedProperties.push("selectable", "ctrlselect", "multiselect",
- "autoselect", "delayedselect", "allowdeselect", "reselectable",
- "value", "default");
-
- this.$propHandlers["value"] = function(value){
- if (!this.bindingRules && !this.caption || !this.xmlRoot)
- return;
-
- if (!this.caption && !this.bindingRules["caption"]
- && !this.bindingRules[this.mainBind] && !this.caption)
- throw new Error(jpf.formatErrorString(1074, this,
- "Setting the value of this component",
- "Could not find default value bind rule for this control."))
-
- if (jpf.isNot(value))
- return this.clearSelection(null, noEvent);
-
- if (!this.xmlRoot)
- return this.select(value);
-
- var xmlNode = this.findXmlNodeByValue(value);
- if (xmlNode)
- this.select(xmlNode, null, null, null, null, noEvent);
- else
- return this.clearSelection(null, noEvent);
- };
-
- this.$propHandlers["allowdeselect"] = function(value){
- if (value) {
- var _self = this;
- this.oInt.onmousedown = function(e){
- if (!e) e = event;
- if (e.ctrlKey || e.shiftKey)
- return;
-
- var srcElement = e.srcElement || e.target;
- if (_self.allowdeselect && (srcElement == this
- || srcElement.getAttribute(jpf.xmldb.htmlIdTag)))
- _self.clearSelection(); //hacky
- }
- }
- else {
- this.oInt.onmousedown = null;
- }
- };
-
- this.$propHandlers["ctrlselect"] = function(value){
- if (value != "enter")
- this.ctrlselect = jpf.isTrue(value);
- }
-
- function fAutoselect(){this.selectAll();}
- this.$propHandlers["autoselect"] = function(value){
- if (value == "all" && this.multiselect) {
- this.addEventListener("afterload", fAutoselect);
- }
- else {
- this.removeEventListener("afterload", fAutoselect);
- }
- };
-
- this.$propHandlers["multiselect"] = function(value){
- if (!value && valueList.length > 1) {
- this.select(this.selected);
- }
-
- if (value)
- this.bufferselect = false; //@todo doesn't return to original value
- };
-
- // Select Bind class
- this.addEventListener("beforeselect", function(e){
- if (this.applyRuleSetOnNode("select", e.xmlNode, ".") === false)
- return false;
- }, true);
-
- this.addEventListener("afterselect", function (e){
- if (this.bindingRules && (this.bindingRules["value"]
- || this.bindingRules["caption"]) || this.caption) {
- this.value = this.applyRuleSetOnNode(this.bindingRules && this.bindingRules["value"] || this.valuerule
- ? "value"
- : "caption", e.xmlNode);
-
- //@todo this will also set the xml again - actually I don't think so because of this.value == value;
- this.setProperty("value", this.value);
- }
-
- if (this.sellength != valueList.length)
- this.setProperty("sellength", valueList.length);
-
- if (typeof jpf.offline != "undefined" && jpf.offline.state.enabled
- && jpf.offline.state.realtime) { //@todo please optimize
- for (var sel = [], i = 0; i < valueList.length; i++)
- sel.push(jpf.remote.xmlToXpath(valueList[i], null, true));
-
- jpf.offline.state.set(this, "selection", sel);
- fSelState.call(this);
- }
- }, true);
-
- function fSelState(){
- if (typeof jpf.offline != "undefined" && jpf.offline.state.enabled
- && jpf.offline.state.realtime) {
- jpf.offline.state.set(this, "selstate",
- [this.indicator
- ? jpf.remote.xmlToXpath(this.indicator, null, true)
- : "",
- this.selected
- ? jpf.remote.xmlToXpath(this.selected, null, true)
- : ""]);
- }
- }
-
- this.addEventListener("indicate", fSelState);
-};
-
-/**
- * @private
- */
-jpf.MultiSelectServer = {
- /**
- * @private
- */
- objects : {},
-
- /**
- * @private
- */
- register : function(xmlId, xmlNode, selList, jNode){
- if (!this.uniqueId)
- this.uniqueId = jpf.all.push(this) - 1;
-
- this.objects[xmlId] = {
- xml : xmlNode,
- list : selList,
- jNode : jNode
- };
- },
-
- $xmlUpdate : function(action, xmlNode, listenNode, UndoObj){
- if (action != "attribute") return;
-
- var data = this.objects[xmlNode.getAttribute(jpf.xmldb.xmlIdTag)];
- if (!data) return;
-
- var nodes = xmlNode.attributes;
-
- for (var j = 0; j < data.list.length; j++) {
- //data[j].setAttribute(UndoObj.name, xmlNode.getAttribute(UndoObj.name));
- jpf.xmldb.setAttribute(data.list[j], UndoObj.name,
- xmlNode.getAttribute(UndoObj.name));
- }
-
- //jpf.xmldb.synchronize();
- }
-};
-
- - -/*FILEHEAD(/var/lib/jpf/src/core/node/transaction.js)SIZE(-1077090856)TIME(1238944816)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-var __TRANSACTION__ = 1 << 3;
-
-
-/**
- * Baseclass adding transaction features to this element. A transaction is a
- * set of changes to data which are treated as one change. When one of the
- * changes in the set fails, all the changes will be cancelled. In the case of
- * a gui this is mostly relevant when a user decides to cancel after
- * making several changes. A good example are the well known property windows
- * with an ok, cancel and apply button.
- *
- * When a user edits data, for instance user information, all the changes are
- * seen as one edit and put on the undo stack as a single action. Thus clicking
- * undo will undo the entire transaction, not just the last change done by that
- * user in the edit window. Transaction support both optimistic and pessimistic
- * locking. For more information on the latter see the first example below.
- * Example:
- * This example shows a list with one item. When double clicked on the item
- * a window shows that allows the user to edit the properties of this item.
- * When the window is closed the changes are committed to the xml data. If the
- * user presses cancel the changes are discarded. By pressing the 'add new item'
- * button the same window appears which allows the user to add a new item. All
- * changes made by the user are also sent to the original data source via
- * rpc calls. When the user starts editing an existing item a lock is requested.
- * This is not necesary for transaction support, but this example shows that it
- * is possible. When the lock fails the window will close. By hooking the
- * 'lockfail' event the user can be notified of the reason. For more information
- * see {@link term.locking}.
- * <code>
- * <j:list id="lstItems" onafterchoose="winEdit.show()">
- * <j:bindings>
- * <j:caption select="name" />
- * <j:icon value="icoItem.png" />
- * <j:traverse select="item" />
- * </j:bindings>
- * <j:actions>
- * <j:add set="url:save.php?xml={.}">
- * <item name="New Item" />
- * </j:add>
- * <j:update
- * set="url:save.php?xml={.}"
- * lock="url:lock.php?id={@id}" />
- * </j:actions>
- * <j:model>
- * <items>
- * <item name="test" subject="subject">
- * message
- * </item>
- * </items>
- * </j:model>
- * </j:list>
- *
- * <j:button onclick="winMail.begin('add');">add new item</j:button>
- *
- * <j:window id="winEdit"
- * transaction = "true"
- * model = "#lstItems"
- * title = "Edit this message">
- * <j:label>Name</j:label>
- * <j:textbox ref="@name" required="true"
- * invalidmsg="Please enter your name" />
- *
- * <j:label>Subject</j:label>
- * <j:textbox ref="@subject" />
- *
- * <j:label>Message</j:label>
- * <j:textarea ref="text()" min-length="100" />
- *
- * <j:button action="ok" default="true">OK</j:button>
- * <j:button action="cancel">Cancel</j:button>
- * <j:button action="apply"
- * disabled="{!winEdit.undolength}">Apply</j:button>
- * </j:window>
- * </code>
- *
- * @constructor
- * @baseclass
- *
- * @event transactionconflict Fires when data in a transaction is being updated by an external process.
- *
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.8.9
- */
-jpf.Transaction = function(){
- this.$regbase = this.$regbase|__TRANSACTION__;
- var _self = this;
-
- var addParent, transactionNode, originalNode, inTransaction, lastAction;
-
- this.$supportedProperties.push("autoshow");
-
- /**
- * @attribute {Boolean} autoshow whether this element is shown when an transaction begins.
- */
- this.$booleanProperties["autoshow"] = true;
-
- /**
- * Commits a started transaction. This will trigger an update or add action.
- * forked copy of template data.
- *
- * @todo check what's up with actiontracker usage...
- * @bug when a commit is cancelled using the onbeforecommit event, the
- * state of the element becomes undefined.
- */
- this.commit = function(){
- if (!inTransaction)
- return false;
-
- if (this.$validgroup && !this.$validgroup.isValid())
- return false;
-
- var returnValue = true;
- if (!this.$at.undolength) {
- this.$at.purge();
- inTransaction = false;
-
- this.load(originalNode);
-
- returnValue = false;
- }
- else {
- jpf.console.info("Committing transaction on " + this.tagName + "[" + this.name + "]");
-
- this.$at.reset();//purge();
- inTransaction = false;
-
- if (lastAction == "add") {
- //Use ActionTracker :: this.xmlData.selectSingleNode("DataBinding/@select") ? o.xmlRoot : o.selected
- if (transactionSubject.executeAction("appendChild",
- [addParent, transactionNode], "add", transactionNode)) {
- transactionSubject.select(transactionNode);
- }
-
- transactionSubject = null;
- }
- else {
- //Use ActionTracker
- //getTraverseParent(o.selected) || o.xmlRoot
- var at = this.$at;
- this.$at = this.dataParent
- ? this.dataParent.parent.getActionTracker()
- : null;//self[this.$jml.getAttribute("actiontracker")];//this.dataParent.parent.getActionTracker();
-
- transactionSubject.executeAction("replaceNode", [originalNode, transactionNode],
- "update", transactionNode);
-
- this.$at = at;
-
- //this.load(transactionNode);
- }
- }
-
- transactionNode = null;
- addParent = null;
- originalNode = null;
-
- if (this.autoshow) {
- if (this.autoshow == -1)
- this.autoshow = true;
- else
- this.hide();
- }
-
- return returnValue;
- };
-
- /**
- * Rolls back the started transaction.
- */
- this.rollback = function(noLoad){
- if (!inTransaction)
- return;
-
- jpf.console.info("Rolling back transaction on " + this.tagName + "[" + this.name + "]");
-
- if (this.$at) {
- if (this.rpcMode == "realtime")
- this.$at.undo(-1);
-
- this.$at.reset();
- }
- //this.xmldb.reset();
-
- transactionNode = null; //prevent from restarting the transaction in load
- addParent = null;
-
- //Cleanup
- if (!noLoad)
- this.load(originalNode);
-
- this.$stopAction(lastAction, true);
-
- originalNode = null;
- inTransaction = false;
-
- if (this.autoshow) {
- if (this.autoshow == -1)
- this.autoshow = true;
- else
- this.hide();
- }
- };
-
- /**
- * Starts a transaction for this element. This is either an add or update.
- * @param {String} strAction the type of transaction to start
- * Possible values:
- * add the transaction is started to add a new data element.
- * update the transaction is started to update an existing data element.
- * @param {XMLElement} xmlNode
- * @param {JMLElement} dataParent
- */
- this.begin = function(strAction, xmlNode, dataParent){
- if (inTransaction) {
- /*throw new Error(jpf.formatErrorString(0, this,
- "Starting Transaction",
- "Cannot start a transaction without committing or rolling \
- back previously started transaction.", this.oldRoot));*/
-
- jpf.console.warn("Rolling back transaction, while starting a new one");
-
- if (this.autoshow)
- this.autoshow = -1;
- this.rollback();
- }
-
- jpf.console.info("Beginning transaction on " + this.tagName + "[" + this.name + "]");
-
- //Add should look at dataParent and take selection or xmlRoot
- //winMail.dataParent.parent.xmlRoot
-
- lastAction = strAction;
-
- if (!lastAction) {
- lastAction = this.xmlRoot && "update" || "add";
- /*this.actionRules && (this.actionRules.add
- ? "add"
- : (this.actionRules.update
- ? "update"
- : null)) || this.xmlRoot && "update";*/
- }
-
- if (!lastAction) {
- throw new Error(jpf.formatErrorString(0, this,
- "Starting Transaction",
- "Could not determine wether to add or update."));
- }
-
- //Determines the actiontracker to integrate the grouped action into
- if (dataParent)
- dataParent.connect(this);
-
- if (xmlNode && lastAction == "update") {
- this.xmlRoot = xmlNode;
- //inTransaction = -1; //Prevent load from triggering a new transaction
- //this.load(xmlNode);
- }
-
- /*
- * @todo:
- * create actiontracker based on data id, destroy actiontracker on cancel/commit - thus being able to implement editor feature natively
- * Multiple transactions can exist at the same time in the same container, but on different data
- * .cancel(xmlNode) .apply(xmlNode)
- * .list(); // returns a list of all started transactions
- * Add undo/redo methods to winMultiEdit
- * Route undolength/redolength properties
- * Setting replaceat="start" or replaceat="end"
- */
- if (!this.$at) {
- this.$at = new jpf.actiontracker();
- var propListen = function(name, oldvalue, newvalue){
- _self.setProperty(name, newvalue);
- };
- this.$at.watch("undolength", propListen);
- this.$at.watch("redolength", propListen);
- }
-
- transactionNode = null;
- addParent = null;
- originalNode = this.xmlRoot;
-
- if (typeof jpf.offline != "undefined" && !jpf.offline.canTransact())
- return false;
-
- inTransaction = true;
- function begin(){
- if (!transactionNode) {
- throw new Error(jpf.formatErrorString(0, this,
- "Starting transaction",
- "Missing transaction node. Cannot start transaction. \
- This error is unrecoverable."));
- }
-
- this.inTransaction = -1;
- this.load(transactionNode);
- this.inTransaction = true;
-
- if (this.disabled)
- this.enable();
-
- if (this.autoshow) {
- if (this.autoshow == -1)
- this.autoshow = true;
- else
- this.show();
- }
- }
-
- //Determine data parent
- var node, dataParent = this.dataParent
- && this.dataParent.parent || this;
-
- //Add
- if (lastAction == "add") {
- //Check for add rule on data parent
- var actionRules = dataParent.actionRules;
- if (actionRules) {
- if (xmlNode && xmlNode.nodeType)
- node = dataParent.getNodeFromRule("add", xmlNode, true);
- else if (typeof xmlNode == "string") {
- if (xmlNode.trim().charAt(0) == "<") {
- xmlNode = jpf.getXml(xmlNode);
- node = dataParent.getNodeFromRule("add", xmlNode, true);
- }
- else {
- var rules = actionRules["add"];
- for (var i = 0, l = rules.length; i < l; i++) {
- if (rules[i].getAttribute("type") == xmlNode) {
- xmlNode = null;
- node = rules[i];
- break;
- }
- }
- }
- }
-
- if (!node && actionRules["add"])
- node = actionRules["add"][0];
- }
- else
- node = null;
-
- if (!node) { // || !node[0]
- throw new Error(jpf.formatErrorString(0, this,
- "Starting transaction",
- "Missing add rule for transaction"));
- }
-
- if (typeof jpf.offline != "undefined" && !jpf.offline.onLine
- && !node.getAttribute("get"))
- return false;
-
- //Run the add code (copy from multiselect) but don't add until commit
- var refNode = this.isTreeArch ? this.selected || this.xmlRoot : this.xmlRoot;
- var callback = function(addXmlNode, state, extra){
- if (state != jpf.SUCCESS) {
- var oError;
-
- oError = new Error(jpf.formatErrorString(1032, dataParent,
- "Loading xml data",
- "Could not add data for control " + dataParent.name
- + "[" + dataParent.tagName + "] \nUrl: " + extra.url
- + "\nInfo: " + extra.message + "\n\n" + xmlNode));
-
- if (extra.tpModule.retryTimeout(extra, state, dataParent, oError) === true)
- return true;
-
- throw oError;
- }
-
- if (typeof addXmlNode != "object")
- addXmlNode = jpf.getXmlDom(addXmlNode).documentElement;
- if (addXmlNode.getAttribute(jpf.xmldb.xmlIdTag))
- addXmlNode.setAttribute(jpf.xmldb.xmlIdTag, "");
-
- if (!dataParent.$startAction("add", addXmlNode, _self.rollback))
- return false;
-
- var actionNode = dataParent.getNodeFromRule("add", dataParent.isTreeArch
- ? dataParent.selected
- : dataParent.xmlRoot, true, true);
-
- if (actionNode && actionNode.getAttribute("parent")) {
- addParent = dataParent.xmlRoot
- .selectSingleNode(actionNode.getAttribute("parent"));
- }
- else {
- addParent = dataParent.isTreeArch
- ? dataParent.selected || dataParent.xmlRoot
- : dataParent.xmlRoot
- }
-
- if (!addParent)
- addParent = dataParent.xmlRoot;
-
- if (jpf.isSafari && addParent.ownerDocument != addXmlNode.ownerDocument)
- addXmlNode = addParent.ownerDocument.importNode(addXmlNode, true); //Safari issue not auto importing nodes
-
- transactionNode = addXmlNode;
- transactionSubject = dataParent;
- begin.call(_self);
- }
-
- if (xmlNode)
- return callback(xmlNode, jpf.SUCCESS);
- else {
- if (!node) {
- throw new Error(jpf.formatErrorString(0, this,
- "Executing add action",
- "Missing add action defined in action rules. Unable to \
- perform action."));
- }
-
- if (node.getAttribute("get"))
- return jpf.getData(node.getAttribute("get"), refNode, null, callback)
- else if (node.firstChild) {
- var node = jpf.getNode(node, [0]);
- if (jpf.supportNamespaces && node.namespaceURI == jpf.ns.xhtml) {
- node = jpf.getXml(node.xml.replace(/xmlns\=\"[^"]*\"/g, ""));
- //@todo import here for webkit?
- }
- else node = node.cloneNode(true);
-
- return callback(node, jpf.SUCCESS);
- }
- }
- }
-
- //Update
- else {
- if (!dataParent.$startAction(lastAction, this.xmlRoot, this.rollback))
- return false;
-
- transactionSubject = dataParent;
- transactionNode = originalNode.cloneNode(true);//xmldb.clearConnections(this.xmlRoot.cloneNode(true));
- //xmlNode.removeAttribute(xmldb.xmlIdTag);
-
- //@todo rename listening attributes
-
- begin.call(this);
- }
- };
-
- //No need to restart the transaction when the same node is loaded
- this.addEventListener("beforeload", function(e){
- if (originalNode == e.xmlNode)
- return false;
-
- if (inTransaction == -1)
- return;
-
- if (inTransaction) {
- if (transactionNode && e.xmlNode != transactionNode) {
- if (this.autoshow)
- this.autoshow = -1;
-
- this.rollback(true);
- }
- else return;
- }
-
- if (this.autoshow)
- this.autoshow = -1;
-
- this.begin("update", e.xmlNode);
-
- return false;
- });
-
- //hmm really?
- //@todo what to do here? check original cloned node???
- /*this.addEventListener("xmlupdate", function(e){
- if (inTransaction) {
- this.dispatchEvent("transactionconflict", {
- action : e.action,
- xmlNode: e.xmlNode,
- UndoObj: e.UndoObj,
- bubbles : true
- });
- }
- });*/
-
- //@todo add when not update???
- this.watch("visible", function(id, oldval, newval){
- if (!this.xmlRoot || oldval == newval)
- return;
-
- if (newval) {
- if (!inTransaction)
- this.begin();
- }
- else {
- if (inTransaction)
- this.rollback();
- }
- });
-
- //Init
- if (!this.$jml || !this.$jml.getAttribute("validgroup")) {
- this.$validgroup = new jpf.ValidationGroup();
- this.$validgroup.add(this);
- }
-
- //autoset model="#id-or-generated-id"
- if (this.$jml) {
- if (!this.$model) {
- this.model = -1;
- if (this.$jml.getAttribute("model"))
- this.setProperty("model", this.$jml.getAttribute("model"));
- this.$modelIgnoreOnce = true;
- }
-
- if (!this.name)
- this.setAttribute("id", "trAutoName" + this.uniqueId);
- this.$jml.setAttribute("model", "#" + this.name);
- }
-
- if (typeof this.autoshow == "undefined" && (this.tagName == "modalwindow"
- || this.tagName == "window"))
- this.autoshow = true;
-};
-
- - -/*FILEHEAD(/var/lib/jpf/src/core/node/rename.js)SIZE(-1077090856)TIME(1238944816)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - -var __RENAME__ = 1 << 10; - - -/** - * Baseclass adding rename features to this element. Rename is triggered by - * pressing F2 on an item or by clicking once on an already selected item. This - * will show an input element in place where the user can change the name of the - * item to a new one. When the caption is changed the xml data element is - * changed accordingly. - * Example: - * This example shows a list containing products. Only products that have the - * editable attribute set to 1 can be renamed by the user. - * <code> - * <j:list model="url:/cgi-bin/products.cgi"> - * <j:bindings> - * <j:caption select="@name" /> - * <j:traverse select="product" /> - * </j:bindings> - * <j:actions> - * <j:rename - * select = "product[@editable='1']" - * set = "rpc:comm.update('product', {@id}, {@name})" /> - * </j:actions> - * </j:list> - * </code> - * - * @event stoprename Fires when a rename action is cancelled. - * - * @constructor - * @baseclass - * @author Ruben Daniels - * @version %I%, %G% - * @since 0.5 - */ -jpf.Rename = function(){ - this.$regbase = this.$regbase|__RENAME__; - - this.canrename = true; - var renameSubject = null; - var renameTimer = null; - var lastCursor; - - /** - * @attribute {Boolean} rename whether the user can rename items in this element. - */ - this.$booleanProperties["canrename"] = true; - this.$booleanProperties["autorename"] = true; - this.$supportedProperties.push("canrename", "autorename"); - - this.$propHandlers["autorename"] = function(value){ - if (value) { - this.reselectable = true; - this.bufferselect = false; - this.addEventListener("afterselect", $afterselect); - this.addEventListener("keydown", $keydown); - } - else { - this.removeEventListener("afterselect", $afterselect); - this.removeEventListener("keydown", $keydown); - } - } - - var _self = this; - function $afterselect(){ - setTimeout(function(){ - if (_self.hasFocus()) - _self.startRename(); - }, 20); - } - - function $keydown(e){ - if (!this.renaming && e.isCharacter()) - this.startRename(); - } - - this.$isContentEditable = function(e){ - if (this.renaming && this.autorename) - return true; - } - - /** - * Changes the data presented as the caption of a specified xml data element. - * If none is specified the indicated node is used. - * - * @action - * @param {XMLElement} xmlNode the element to change the caption of. - * @param {String} value the value to set as the caption of the xml data element. - */ - this.rename = function(xmlNode, value){ - if (!xmlNode) - xmlNode = this.indicator || this.selected; - - if (!xmlNode) return; - - this.executeActionByRuleSet("rename", "caption", xmlNode, value); - }; - - /** - * Starts the rename process with a delay, allowing for cancellation when - * necesary. Cancellation is necesary for instance, when double click was - * intended or a dragdrop operation. - * - */ - this.startDelayedRename = function(e, time){ - if (e && (e.button == 2 || e.ctrlKey || e.shiftKey)) - return; - - clearTimeout(renameTimer); - renameTimer = setTimeout('jpf.lookup(' - + this.uniqueId + ').startRename()', time || 400); - }; - - /** - * Starts the rename process by displaying an input box at the position - * of the item that can be renamed by the user. - * - */ - this.startRename = function(force, startEmpty){ - if (!force && (this.renaming || !this.canrename - || !this.$startAction("rename", this.indicator - || this.selected, this.stopRename))) - return false; - - if (!this.hasFocus()) - this.focus(null, null, true); - - clearTimeout(renameTimer); - - var elCaption = this.$getCaptionElement - ? this.$getCaptionElement() - : this.$indicator || this.$selected; - - if (!elCaption) - return this.stopRename(); - - this.renaming = true; - renameSubject = this.indicator || this.selected; - - var wdt = elCaption.offsetWidth; - lastCursor = elCaption.style.cursor; - elCaption.style.cursor = "text"; - elCaption.parentNode.replaceChild(this.oTxt, elCaption); - elCaption.host = this; - - if (jpf.isTrue(this.$getOption("main", "scalerename"))) { - var diff = jpf.getWidthDiff(this.oTxt); - this.oTxt.style.width = (wdt - diff) + "px"; - } - - this.replacedNode = elCaption; - var xmlNode = this.$getCaptionXml - ? this.$getCaptionXml(renameSubject) - : this.getNodeFromRule("caption", renameSubject); - - this.oTxt[jpf.hasContentEditable ? "innerHTML" : "value"] = startEmpty || !xmlNode - ? "" - : (xmlNode.nodeType >= 2 && xmlNode.nodeType <= 4 - ? unescape(decodeURI(xmlNode.nodeValue)) - : (jpf.xmldb.isOnlyChild(xmlNode.firstChild, [3,4]) - ? jpf.xmldb.getNodeValue(xmlNode) - : this.applyRuleSetOnNode("caption", renameSubject))) || ""; - - this.oTxt.unselectable = "Off"; - this.oTxt.host = this; - - //this.oTxt.focus(); - this.oTxt.focus(); - this.oTxt.select(); - }; - - /** - * Stop renaming process and change the data according to the set value. - * Cancel the renaming process without changing data. - * - */ - this.stopRename = function(contextXml, success){ - clearTimeout(renameTimer); - - if (!this.renaming || contextXml && contextXml != renameSubject - || !this.replacedNode) - return false; - - if (this.oTxt.parentNode && this.oTxt.parentNode.nodeType == 1) - this.oTxt.parentNode.replaceChild(this.replacedNode, this.oTxt); - - this.renaming = false; - - if (this.replacedNode) { - this.replacedNode.style.cursor = lastCursor || ""; - this.replacedNode.host = null; - } - - if (!success) { - this.dispatchEvent("stoprename"); - this.$stopAction("rename"); - } - else { - this.replacedNode.innerHTML = this.oTxt[jpf.hasContentEditable - ? "innerHTML" - : "value"]; - - //this.$selected.innerHTML = this.oTxt.innerHTML; - this.rename(renameSubject, - this.oTxt[jpf.hasContentEditable ? "innerHTML" : "value"] - .replace(/<.*?nobr>/gi, "")); - } - - if (!this.renaming) { - renameSubject = null; - this.replacedNode = null; - this.oTxt.style.width = ""; - } - - return true; - }; - - this.addEventListener("keydown", function(e){ - var key = e.keyCode; - - if (this.renaming) { - if (key == 27 || key == 13) { - this.stopRename(null, key == 13 && !this.$autocomplete); - return false; - } - - return; - } - - //F2 - if (key == 113) { - if (this.$tempsel) - this.selectTemp(); - - if (this.indicator != this.selected) { - if (this.multiselect || this.isSelected(this.indicator)) { - this.selected = this.indicator; - this.$selected = this.$indicator; - } - else - this.select(this.indicator, true); - } - - this.startRename(); - - return false; - } - }, true); - - if (!(this.oTxt = this.pHtmlDoc.getElementById("txt_rename"))) { - if (jpf.hasContentEditable) { - this.oTxt = this.pHtmlDoc.createElement("DIV"); - this.oTxt.contentEditable = true; - if (jpf.isIE6) - this.oTxt.style.width = "1px"; - //this.oTxt.canHaveHTML = false; - } - else { - this.oTxt = this.pHtmlDoc.createElement("input"); - this.oTxt.id = "txt_rename"; - this.oTxt.autocomplete = false; - } - - this.oTxt.refCount = 0; - this.oTxt.id = "txt_rename"; - this.oTxt.style.whiteSpace = "nowrap"; - this.oTxt.onselectstart = function(e){ - (e || event).cancelBubble = true; - }; - //this.oTxt.host = this; - jpf.sanitizeTextbox(this.oTxt); - - this.oTxt.onmouseover = this.oTxt.onmouseout = this.oTxt.oncontextmenu = - this.oTxt.onmousedown = function(e){ (e || event).cancelBubble = true; }; - - this.oTxt.onkeyup = function(){ - if (!this.host.$autocomplete) - return; - - this.host.$lookup(this[jpf.hasContentEditable ? "innerHTML" : "value"]); - } - - this.oTxt.select = function(){ - if (!jpf.hasMsRangeObject) - return this.focus(); - - var r = document.selection.createRange(); - //r.moveEnd("character", this.oExt.innerText.length); - try { - r.moveToElementText(this); - - if (jpf.isFalse(this.host.$getOption("main", "selectrename")) - || typeof this.host.$renameStartCollapse != "undefined") //@todo please deprecate renameStartCollapse - r.collapse(this.host.$renameStartCollapse); - } catch(e) {} //BUG!!!! - - r.select(); - }; - - this.oTxt.onfocus = function(){ - if (jpf.hasFocusBug) - jpf.window.$focusfix2(); - }; - - this.oTxt.onblur = function(){ - if (jpf.isGecko) - return; //bug in firefox calling onblur too much - - if (jpf.hasFocusBug) - jpf.window.$blurfix(); - - if (this.host.$autocomplete) - return; - - this.host.stopRename(null, true); - }; - } - this.oTxt.refCount++; - - this.$jmlDestroyers.push(function(){ - this.oTxt.refCount--; - - if (!this.oTxt.refCount) { - this.oTxt.host = - this.oTxt.onmouseover = - this.oTxt.onmousedown = - this.oTxt.select = - this.oTxt.onfocus = - this.oTxt.onblur = null; - } - }); -}; - - - -/*FILEHEAD(/var/lib/jpf/src/core/node/xforms.js)SIZE(-1077090856)TIME(1225628611)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-var __XFORMS__ = 1 << 17;
-
- - -/*FILEHEAD(/var/lib/jpf/src/core/node/editmode.js)SIZE(-1077090856)TIME(1238944816)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - -var __EDITMODE__ = 1 << 15; -var __MULTILANG__ = 1 << 16; - - -/** - * Adds multilingual support for jml applications. Reads language symbols from - * an xml file and distributes them among elements containing text elements - * or images. When EditMode is turned on, it can subtract all text elements - * necesary for translation and export them in an xml file. This file can be - * sent to a translator to translate and then loaded back into the application. - * Examples: - * This examples shows a small language file. For example purpose it's loaded - * inline in a model. Normally this file would be loaded from a web server. - * There is a simple window and a couple of buttons that receive symbols from - * the language file. Two buttons provide a means to switch the language of the - * application, using the language symbols from the model. - * <code> - * <j:model id="mdlLang"> - * <groups> - * <!-- For French --> - * <french id="sub"> - * <group id="main"> - * <key id="tab1">Textuele</key> - * <key id="tab2">Arte</key> - * <key id="title">Bonjour</key> - * <key id="1">Adresse de courrier electronique *</key> - * ... - * </group> - * </french> - * - * <!-- For English --> - * <english id="sub"> - * <group id="main"> - * <key id="tab1">Text</key> - * <key id="tab2">Art</key> - * <key id="title">Hello</key> - * <key id="1">E-mail *</key> - * ... - * </group> - * </english> - * </groups> - * </j:model> - * - * <j:appsettings language="mdlLang:english" /> - * - * <j:window title="$sub.main.title$"> - * <j:tab> - * <j:page caption="$sub.main.tab0$"> - * <j:label>$sub.main.1$</j:label> - * <j:textbox /> - * <j:button>$sub.main.2$</j:button> - * </j:page> - * <j:page caption="$sub.main.tab2$"> - * <j:picture src="$sub.main.3$" /> - * </j:page> - * </j:tab> - * </j:window> - * - * <j:button icon="us.gif" - * onclick="jpf.language.loadFrom('mdlLang:english');"> - * English - * </j:button> - * <j:button icon="fr.gif" - * onclick="jpf.language.loadFrom('mdlLang:french');"> - * French - * </j:button> - * </code> - * - * @default_private - * @todo get appsettings to understand language - */ -jpf.language = { - /** - * {Boolean} whether read strings are tried to match themselves if no key - * was gives. - */ - automatch : false, - /** - * {String} the prefix to the set of language symbols. This is a tree path - * using a dott (.) as a seperation symbol. - */ - prefix : "sub.main.", - words : {}, - texts : {}, - elements : {}, - count : 0, - - /** - * Loads the symbol list from an xml node. - * @param {XMLElement} xmlNode the root of the symbol tree for the choosen language. - * @param {String} [prefix] the prefix that overrides the default prefix. - */ - loadXml : function(xmlNode, prefix){ - if (typeof xmlNode == "string") - xmlNode = jpf.getXmlDom(xmlNode).documentElement; - this.parseSection(xmlNode, prefix); - }, - - /** - * Loads the symbol list using a {@link term.datainstruction data instruction} - * @param {String} instruction the {@link term.datainstruction data instruction} to load the symbol xml from. - */ - loadForm : function(instruction) { - jpf.setModel(instruction, { - load: function(xmlNode){ - if (!xmlNode || this.isLoaded) return; - - if (!xmlNode) { - throw new Error(jpf.formatErrorString(0, null, - "Loading language", - "Could not find language symbols using processing \ - instruction: '" + instruction + "'")); - - return; - } - - jpf.language.loadXml(xmlNode); - this.isLoaded = true; - }, - - setModel: function(model, xpath){ - if (typeof model == "string") - model = jpf.nameserver.get("model", model); - model.register(this, xpath); - } - }); - }, - - parseSection: function(xmlNode, prefix){ - if (!prefix) - prefix = ""; - - if (xmlNode.tagName == "key") { - prefix += "." + xmlNode.getAttribute("id"); - this.update(prefix, xmlNode.firstChild ? xmlNode.firstChild.nodeValue : ""); - return; - } - - //if(xmlNode.tagName == "lang") prefix = xmlNode.getAttribute("id"); - if (xmlNode.tagName == "group") - prefix += (prefix ? "." : "") + xmlNode.getAttribute("id"); - - var nodes = xmlNode.childNodes; - for (var i = 0; i < nodes.length; i++) - this.parseSection(nodes[i], prefix); - }, - - /** - * Updates a key with the value specified and reflects this immediately in - * the user interface of the applications. - * @param {String} key the identifier of the element to be updated. - * @param {String} value the new text of the element. - */ - update: function(key, value){ - this.words[key] = value; - if (!this.elements[key]) - return; - - for (var i = 0; i < this.elements[key].length; i++) { - if (this.elements[key][i].htmlNode.nodeType == 1) - this.elements[key][i].htmlNode.innerHTML = value; - else - this.elements[key][i].htmlNode.nodeValue = value; - } - }, - - /* - #ifdef __WITH_EDITMODE - - exportXml : function(doTest){ - //var re = new RegExp("^" + this.prefix.replace(/\./g, "\\.")), - // str = ["<lang id='EN'><group id='main'>"]; - var lut = {}; - for (key in this.words) { - nKey = key.split(".");//replace(/^.*\.(.*)$/, "$1"); - if(!lut[nKey[0]]) - lut[nKey[0]] = []; - //if (!lut[nKey[0]][nKey[1]]) - // lut[nKey[0]][nKey[1]] = [] - //lut[nKey[0]][nKey[1]].push("<key id='", nKey[2], "'><![CDATA[", doTest ? "aaaaa" : this.words[key], "]]></key>"); - lut[nKey[0]].push("<key id='", nKey[1], "'><![CDATA[", doTest ? "aaaaa" : this.words[key], "]]></key>"); - } - - var str = ["<app>"]; - //for (var lang in lut) { - str.push("<lang id='" + this.lang + "'>"); - for (var group in lut) { - str.push("<group id='" + group + "'>"); - for(var i = 0; i < lut[group].length; i++) - str.push(lut[group][i]); - str.push("</group>"); - } - str.push("</lang>"); - //} - - var result = str.join("") + "</app>"; - - return result; - }, - - addWord : function(str, key, oEl){ - if (this.automatch && !key && this.texts[str]) - key = this.texts[str]; - if (!key) - key = this.getNewKey(); - this.words[key] = str; - this.texts[str] = key; - if (!this.elements[key]) - this.elements[key] = []; - if (oEl) - this.elements[key].push(oEl); - - return key; - }, - - getNewKey : function(){ - var key = this.prefix + this.count++; - while (this.words[key] !== undefined) { - key = this.prefix + this.count++; - } - return key; - }, - - removeElement : function(key, oEl){ - if (!this.elements[key]) return; - this.elements[key].remove(oEl); - }, - - #endif - */ - addElement: function(key, oEl){ - if (!this.elements[key]) - this.elements[key] = []; - return this.elements[key].push(oEl) - 1; - }, - - removeElement: function(key, id){ - this.elements[key].removeIndex(id); - }, - - getWord: function(key){ - return this.words[key]; - } -}; - - - - -/** - * Baseclass adding multilingual features to this element. - * - * @see core.layout - * @constructor - * @baseclass - * @author Ruben Daniels - * @version %I%, %G% - * @since 0.5 - * @todo Make this work together with appsettings.defaults and property management - */ -jpf.MultiLang = function(){ - this.$regbase = this.$regbase | __MULTILANG__; - - var reggedItems = []; - this.$makeEditable = function(type, htmlNode, jmlNode){ - if (jmlNode.prefix != "j") - return;//using a non-xml format is unsupported - - var config = this.editableParts[type]; - for (var i = 0; i < config.length; i++) { - var subNode = this.$getLayoutNode(type, config[i][0], htmlNode); - if (!subNode) - continue; - - var xmlNode = config - ? jpf.xmldb.selectSingleNode(config[i][1], jmlNode) - : jpf.xmldb.getTextNode(jmlNode); - - if (!xmlNode) - continue;//xmlNode = jpf.xmldb.createNodeFromXpath(jmlNode, config[i][1]); - - var key = xmlNode.nodeValue.match(/^\$(.*)\$$/); // is this not conflicting? - if (key) { - subNode = subNode.nodeType == 1 - ? subNode - : (subNode.nodeType == 3 || subNode.nodeType == 4 - ? subNode.parentNode - : subNode); //subNode.ownerElement || subNode.selectSinglesubNode("..") - reggedItems.push([key[1], jpf.language.addElement(key[1], { - htmlNode: subNode - })]); - } - } - }; - - this.$removeEditable = function(){ - for (var i = 0; i < reggedItems.length; i++) { - jpf.language.removeElement(reggedItems[i][0], reggedItems[i][1]); - } - - reggedItems = []; - }; - - this.$jmlDestroyers.push(function(){ - this.$removeEditable(); - }); -}; - -//setTimeout('alert("Switch"); -// jpf.language.setWordListXml("<group id=\'main\'><key id=\'0\'>aaaaaaa</key></group>", "sub");', 1000); - - - -/*FILEHEAD(/var/lib/jpf/src/core/node/docking.js)SIZE(-1077090856)TIME(1238933673)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-var __DOCKING__ = 1 << 18;
-
-
-/**
- * Baseclass adding Docking features to this Element.
- *
- * @constructor
- * @baseclass
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.5
- *
- * @see baseclass.alignment
- */
-jpf.Docking = function(){
- this.$regbase = this.$regbase | __DOCKING__;
-
- /**
- * @private
- */
- this.startDocking = function(e){
- if (!this.aData)
- return jpf.console.warn("Docking start without alignment set on this element");
-
- jpf.DockServer.start(this.aData, this, e);
- };
-};
-
-/**
- * @private
- */
-jpf.DockServer = {
- edge: 30,
- inited: false,
-
- init: function(){
- if (this.inited)
- return;
- this.inited = true;
-
- jpf.dragmode.defineMode("dockobject", this);
-
- if (!this.nextPositionMarker) {
- this.nextPositionMarker = document.body.appendChild(document.createElement("div"));
- this.nextPositionMarker.style.border = "4px solid #555";
- this.nextPositionMarker.style.position = "absolute";
- this.nextPositionMarker.style.zIndex = 10000;
- this.nextPositionMarker.style.filter = "progid:DXImageTransform.Microsoft.Alpha(opacity=50);"
- this.nextPositionMarker.style.opacity = 0.5;
- jpf.setUniqueHtmlId(this.nextPositionMarker);
- }
- },
-
- start: function(oItem, jmlNode, e){
- if (!this.inited)
- jpf.DockServer.init();
-
- this.dragdata = {
- item: oItem,
- jmlNode: jmlNode,
- x: e.offsetX || e.layerX,
- y: e.offsetY || e.layerY
- }
-
- jpf.dragmode.setMode("dockobject");
-
- jpf.plane.show(this.nextPositionMarker);
-
- var pos = jpf.getAbsolutePosition(oItem.oHtml);
- var diff = jpf.getDiff(this.nextPositionMarker);
-
- this.nextPositionMarker.style.left = pos[0] + "px";
- this.nextPositionMarker.style.top = pos[1] + "px";
- this.nextPositionMarker.style.width = (oItem.oHtml.offsetWidth - diff[0]) + "px"
- this.nextPositionMarker.style.height = (oItem.oHtml.offsetHeight - diff[1]) + "px";
- this.nextPositionMarker.style.display = "block";
-
- jpf.layout.pause(oItem.oHtml.parentNode);
- },
-
- floatElement: function(e){
- this.dragdata.item.setPosition(e.clientX - this.dragdata.x,
- e.clientY - this.dragdata.y)
-
- if (this.dragdata.item.hidden != 3) {
- this.dragdata.item.setFloat();
- this.dragdata.jmlNode.purgeAlignment();
- }
- else
- jpf.layout.play(this.dragdata.item.oHtml.parentNode);
- },
-
- setPosition: function(e){
- var diff = jpf.getDiff(this.nextPositionMarker);
-
- this.nextPositionMarker.style.left = (e.clientX - this.dragdata.x) + "px";
- this.nextPositionMarker.style.top = (e.clientY - this.dragdata.y) + "px";
- this.nextPositionMarker.style.width = (this.dragdata.item.size[0] - diff[0]) + "px";
- this.nextPositionMarker.style.height = ((this.dragdata.item.state < 0
- ? this.dragdata.item.size[1]
- : this.dragdata.item.fheight) - diff[1]) + "px";
-
- document.body.style.cursor = "default";
- //jpf.setStyleClass(document.body, "", ["same", "south", "east", "north", "west"]);
- },
-
- onmousemove: function(e){
- if (!e)
- e = event;
- if (jpf.isIE && e.button < 1)
- return false;
-
- jpf.plane.hide();
-
- jpf.DockServer.nextPositionMarker.style.top = "10000px";
- //jpf.DockServer.dragdata.jmlNode.oExt.style.top = "10000px";
-
- var el = document.elementFromPoint(e.clientX
- + document.documentElement.scrollLeft,
- e.clientY + document.documentElement.scrollTop);
-
- jpf.plane.show(jpf.DockServer.nextPositionMarker);
-
- var o = el;
- while (o && !o.host && o.parentNode)
- o = o.parentNode;
- var jmlNode = o && o.host ? o.host : false;
- var htmlNode = jmlNode.oExt;
- if (!jmlNode.aData || !jmlNode.dock) {
- document.body.style.cursor = "";
- jpf.setStyleClass(document.body, "same",
- ["south", "east", "north", "west"]);
- return jpf.DockServer.setPosition(e);
- }
-
- if (jpf.DockServer.dragdata.item == jmlNode.aData && jmlNode.aData.hidden == 3)
- return jpf.DockServer.setPosition(e);
-
- var calcData = jmlNode.aData.calcData;
-
- var pos = jpf.getAbsolutePosition(htmlNode);
- var l = e.clientX - pos[0];
- var t = e.clientY - pos[1];
-
- var diff = jpf.getDiff(jpf.DockServer.nextPositionMarker);
- var verdiff = diff[1];
- var hordiff = diff[0];
-
- var region;
- var vEdge = Math.min(jpf.DockServer.edge, htmlNode.offsetHeight / 2);
- var hEdge = Math.min(jpf.DockServer.edge, htmlNode.offsetWidth / 2);
-
- var r = htmlNode.offsetWidth - l;
- var b = htmlNode.offsetHeight - t;
-
- var p = b / vEdge, q = l / hEdge, z = t / vEdge, w = r / hEdge;
-
- if (p < Math.min(q, w, z)) {
- if (b <= vEdge)
- region = "south";
- }
- else if (w < Math.min(p, z, q)) {
- if (r <= hEdge)
- region = "east";
- }
- else if (q < Math.min(p, z, w)) {
- if (l <= hEdge)
- region = "west";
- }
- else if (z < Math.min(q, w, p)) {
- if (t <= vEdge)
- region = "north";
- }
-
- if (jpf.DockServer.dragdata.item == jmlNode.aData)
- region = "same";
-
- if (!region)
- return jpf.DockServer.setPosition(e);
-
- var nextPositionMarker = jpf.DockServer.nextPositionMarker;
- if (region == "west") {
- nextPositionMarker.style.left = pos[0] + "px";
- nextPositionMarker.style.top = pos[1] + "px";
- nextPositionMarker.style.width = ((htmlNode.offsetWidth / 2) - hordiff) + "px"
- nextPositionMarker.style.height = (htmlNode.offsetHeight - verdiff) + "px";
- }
- else if (region == "north") {
- nextPositionMarker.style.left = pos[0] + "px";
- nextPositionMarker.style.top = pos[1] + "px";
- nextPositionMarker.style.width = (htmlNode.offsetWidth - hordiff) + "px"
- nextPositionMarker.style.height = (Math.ceil(htmlNode.offsetHeight / 2) - verdiff) + "px";
- }
- else if (region == "east") {
- nextPositionMarker.style.left = (pos[0] + Math.ceil(htmlNode.offsetWidth / 2)) + "px";
- nextPositionMarker.style.top = pos[1] + "px";
- nextPositionMarker.style.width = ((htmlNode.offsetWidth / 2) - hordiff) + "px"
- nextPositionMarker.style.height = (htmlNode.offsetHeight - verdiff) + "px";
- }
- else if (region == "south") {
- nextPositionMarker.style.left = pos[0] + "px";
- nextPositionMarker.style.top = (pos[1] + Math.ceil(htmlNode.offsetHeight / 2)) + "px";
- nextPositionMarker.style.width = (htmlNode.offsetWidth - hordiff) + "px"
- nextPositionMarker.style.height = (Math.ceil(htmlNode.offsetHeight / 2) - verdiff) + "px";
- }
- else if (region == "same") {
- nextPositionMarker.style.left = pos[0] + "px";
- nextPositionMarker.style.top = pos[1] + "px";
- nextPositionMarker.style.width = (htmlNode.offsetWidth - hordiff) + "px"
- nextPositionMarker.style.height = (htmlNode.offsetHeight - verdiff) + "px";
- }
-
- document.body.style.cursor = "";
- jpf.setStyleClass(document.body, region,
- ["same", "south", "east", "north", "west"]);
- },
-
- onmouseup: function(e){
- if (!e)
- e = event;
- if (jpf.isIE && e.button < 1)
- return false;
-
- jpf.plane.hide();
-
- jpf.dragmode.clear();
- jpf.DockServer.nextPositionMarker.style.display = "none";
- //jpf.DockServer.dragdata.jmlNode.oExt.style.top = "10000px";
- document.body.className = "";
-
- var el = document.elementFromPoint(e.clientX
- + document.documentElement.scrollLeft,
- e.clientY + document.documentElement.scrollTop);
- var o = el;
- while (o && !o.host && o.parentNode)
- o = o.parentNode;
- var jmlNode = o && o.host ? o.host : false;
- var htmlNode = jmlNode.oExt;
- var aData = jmlNode.aData;
-
- if (!jmlNode.aData || !jmlNode.dock
- || jpf.DockServer.dragdata.item == jmlNode.aData
- && jmlNode.aData.hidden == 3) {
- //jpf.layout.play(htmlNode.parentNode);
- return jpf.DockServer.floatElement(e);
- }
- if (jpf.DockServer.dragdata.item == jmlNode.aData)
- return jpf.layout.play(htmlNode.parentNode);
-
- var pos = jpf.getAbsolutePosition(htmlNode);
- var l = e.clientX - pos[0];
- var t = e.clientY - pos[1];
-
- var diff = jpf.getDiff(jpf.DockServer.nextPositionMarker);
- var verdiff = diff[1];
- var hordiff = diff[0];
-
- var region;
- var vEdge = Math.min(jpf.DockServer.edge, htmlNode.offsetHeight / 2);
- var hEdge = Math.min(jpf.DockServer.edge, htmlNode.offsetWidth / 2);
-
- var r = htmlNode.offsetWidth - l;
- var b = htmlNode.offsetHeight - t;
-
- var p = b / vEdge, q = l / hEdge, z = t / vEdge, w = r / hEdge;
-
- if (p < Math.min(q, w, z)) {
- if (b <= vEdge)
- region = "b";
- }
- else if (w < Math.min(p, z, q)) {
- if (r <= hEdge)
- region = "r";
- }
- else if (q < Math.min(p, z, w)) {
- if (l <= hEdge)
- region = "l";
- }
- else if (z < Math.min(q, w, p)) {
- if (t <= vEdge)
- region = "t";
- }
-
- if (!region)
- return jpf.DockServer.floatElement(e);
-
- var pHtmlNode = htmlNode.parentNode;
- l = jpf.layout.layouts[pHtmlNode.getAttribute("id")];
- if (!l)
- return false;
-
- var root = l.root;//.copy();
- var current = aData;
-
- if (jpf.DockServer.dragdata.item.hidden == 3)
- jpf.DockServer.dragdata.item.unfloat();
-
- var newItem = jpf.DockServer.dragdata.item;
- var pItem = newItem.parent;
- if (pItem.children.length == 2) {
- var fixItem = pItem.children[(newItem.stackId == 0) ? 1 : 0];
- fixItem.parent = pItem.parent;
- fixItem.stackId = pItem.stackId;
- fixItem.parent.children[fixItem.stackId] = fixItem;
- fixItem.weight = pItem.weight;
- fixItem.fwidth = pItem.fwidth;
- fixItem.fheight = pItem.fheight;
- }
- else {
- var nodes = pItem.children;
- for (var j = newItem.stackId; j < nodes.length; j++) {
- nodes[j] = nodes[j + 1];
- if (nodes[j])
- nodes[j].stackId = j;
- }
- nodes.length--;
- }
-
- var type = (region == "l" || region == "r") ? "hbox" : "vbox";
- var parent = current.parent;
- var newBox = jpf.layout.getData(type, l.layout);
-
- newBox.splitter = current.splitter;
- newBox.edgeMargin = current.edgeMargin;
- newBox.id = jpf.layout.metadata.push(newBox) - 1;
- newBox.parent = parent;
- parent.children[current.stackId] = newBox;
- newBox.stackId = current.stackId;
- newBox.children = (region == "b" || region == "r")
- ? [current, newItem]
- : [newItem, current];
- current.parent = newItem.parent = newBox
- current.stackId = (region == "b" || region == "r") ? 0 : 1;
- newItem.stackId = (region == "b" || region == "r") ? 1 : 0;
-
- //if(type == "vbox")
- newBox.fwidth = current.fwidth;
- //else if(type == "hbox")
- newBox.fheight = current.fheight;
-
- newItem.weight = current.weight = 1;//current.weight / 2;
- current.fwidth = current.fheight = null;
-
- var root = root.copy();
- l.layout.compile(root);
- l.layout.reset();
- jpf.layout.activateRules(l.layout.parentNode);
- }
-};
-
- - -/*FILEHEAD(/var/lib/jpf/src/core/node/anchoring.js)SIZE(-1077090856)TIME(1238944816)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-var __ANCHORING__ = 1 << 13;
-
-
-/**
- * Baseclass adding Anchoring features to this Element. Each side of the
- * element can be attached at a certain distance to it's parent's rectangle.
- * When the parent is resized the anchored side of the element stays
- * at the specified distance at all times. If both sides are anchored the
- * element size is changed to make sure the specified distance is maintained.
- * Example:
- * This example shows a bar that has 10% as a margin around it and contains a
- * frame that is displayed using different calculations and settings.
- * <code>
- * <j:bar width="80%" height="80%" top="10%" left="10%">
- * <j:frame title="Example"
- * left = "50%+10"
- * top = "100"
- * right = "10%"
- * bottom = "Math.round(0.232*100)" />
- * </j:bar>
- * </code>
- * Remarks:
- * This is one of three positioning methods.
- * See {@link baseclass.alignment}
- * See {@link element.grid}
- *
- * @constructor
- * @baseclass
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.3
- */
-jpf.Anchoring = function(){
- this.$regbase = this.$regbase | __ANCHORING__;
- this.$anchors = [];
-
- var VERTICAL = 1;
- var HORIZONTAL = 2;
-
- var l = jpf.layout, inited = false, updateQueue = 0,
- hordiff, verdiff, rule_v = "", rule_h = "", rule_header,
- id, inited, parsed, disabled;
-
- /**
- * Turns anchoring off.
- *
- */
- this.disableAnchoring = function(activate){
- if (!parsed || !inited || disabled)
- return;
-
- l.removeRule(this.pHtmlNode, this.uniqueId + "_anchors");
- if (l.queue)
- l.queue(this.pHtmlNode);
-
- this.$propHandlers["anchors"] =
- this.$propHandlers["left"] =
- this.$propHandlers["width"] =
- this.$propHandlers["right"] =
- this.$propHandlers["top"] =
- this.$propHandlers["height"] =
- this.$propHandlers["bottom"] = null;
-
- this.$domHandlers["remove"].remove(remove);
- this.$domHandlers["reparent"].remove(reparent);
-
- if (this.right)
- this.oExt.style.left = this.oExt.offsetLeft;
-
- if (this.bottom)
- this.oExt.style.top = this.oExt.offsetTop;
-
- this.$hide = null;
- this.$show = null;
-
- inited = false;
- disabled = true; //isn't this redundant?
- };
-
- /**
- * Enables anchoring based on attributes set in the JML of this element
- *
- * @attribute {Number, String} [left] a way to determine the amount of pixels from the left border of this element to the left edge of it's parent's border. This attribute can also contain percentages, arithmetic and even full expressions.
- * Example:
- * <j:bar left="(20% + 10) * SOME_JS_VAR" />
- * @attribute {Number, String} [right] a way to determine the amount of pixels from the right border of this element to the right edge of it's parent's border.This attribute can also contain percentages, arithmetic and even full expressions.
- * Example:
- * <j:bar right="(20% + 10) * SOME_JS_VAR" />
- * @attribute {Number, String} [width] a way to determine the amount of pixels from the left border to the right border of this element.This attribute can also contain percentages, arithmetic and even full expressions.
- * Example:
- * <j:bar width="(20% + 10) * SOME_JS_VAR" />
- * @attribute {Number, String} [top] a way to determine the amount of pixels from the top border of this element to the top edge of it's parent's border.This attribute can also contain percentages, arithmetic and even full expressions.
- * Example:
- * <j:bar top="(20% + 10) * SOME_JS_VAR" />
- * @attribute {Number, String} [bottom] a way to determine the amount of pixels from the bottom border of this element to the bottom edge of it's parent's border.This attribute can also contain percentages, arithmetic and even full expressions.
- * Example:
- * <j:bar bottom="(20% + 10) * SOME_JS_VAR" />
- * @attribute {Number, String} [height] a way to determine the amount of pixels from the top border to the bottom border of this element.This attribute can also contain percentages, arithmetic and even full expressions.
- * Example:
- * <j:bar height="(20% + 10) * SOME_JS_VAR" />
- */
- this.enableAnchoring = function(){
- if (inited) //@todo add code to reenable anchoring rules (when showing)
- return;
-
- /**** Properties and Attributes ****/
-
- this.$supportedProperties.push("right", "bottom", "width",
- "left", "top", "height");
-
- this.$propHandlers["anchors"] = function(value){
- this.$anchors = value.splitSafe("(?:, *| )");
-
- if (!updateQueue && jpf.loaded)
- l.queue(this.pHtmlNode, this);
- updateQueue = updateQueue | HORIZONTAL | VERTICAL;
- };
-
- this.$propHandlers["left"] =
- this.$propHandlers["width"] =
- this.$propHandlers["right"] = function(value){
- if (!updateQueue && (!jpf.isParsing || jpf.parsingFinalPass))
- l.queue(this.pHtmlNode, this);
- updateQueue = updateQueue | HORIZONTAL;
- };
-
- this.$propHandlers["top"] =
- this.$propHandlers["height"] =
- this.$propHandlers["bottom"] = function(value){
- if (!updateQueue && (!jpf.isParsing || jpf.parsingFinalPass))
- l.queue(this.pHtmlNode, this);
- updateQueue = updateQueue | VERTICAL;
- };
-
- /**** DOM Hooks ****/
-
- this.$domHandlers["remove"].push(remove);
- this.$domHandlers["reparent"].push(reparent);
-
- this.$hide = function(){
- if (!(rule_header || rule_v || rule_h))
- return;
-
- l.removeRule(this.pHtmlNode, this.uniqueId + "_anchors");
- l.queue(this.pHtmlNode)
- };
-
- this.$show = function(){
- if (!(rule_header || rule_v || rule_h))
- return;
-
- //@todo
- if (rule_v || rule_h) {
- rules = rule_header + "\n" + rule_v + "\n" + rule_h;
- l.setRules(this.pHtmlNode, this.uniqueId + "_anchors", rules);
- this.oExt.style.display = "none";
- l.queue(this.pHtmlNode, this);
- }
-
- l.processQueue();
- };
-
- inited = true;
- };
-
- function remove(doOnlyAdmin){
- if (doOnlyAdmin)
- return;
-
- if (l.queue) {
- l.removeRule(this.pHtmlNode, this.uniqueId + "_anchors");
- l.queue(this.pHtmlNode)
- }
- }
-
- function reparent(beforeNode, pNode, withinParent, oldParent){
- if (!this.$jmlLoaded)
- return;
-
- if (!withinParent && !disabled && parsed) //@todo hmm weird state check
- this.$moveAnchoringRules(oldParent);
- }
-
- this.$moveAnchoringRules = function(oldParent, updateNow){
- var rules = l.removeRule(oldParent, this.uniqueId + "_anchors");
- if (rules)
- l.queue(oldParent);
-
- if (!rule_v && !rule_h)
- return;
-
- rule_header = getRuleHeader.call(this);
- rules = rule_header + "\n" + rule_v + "\n" + rule_h;
-
- this.oExt.style.display = "none";
-
- l.setRules(this.pHtmlNode, this.uniqueId + "_anchors", rules);
- l.queue(this.pHtmlNode, this);
- };
-
- this.$hasAnchorRules = function(){
- return rule_v || rule_h ? true : false;
- };
-
- this.$setAnchoringEnabled = function(){
- disabled = false;
- };
-
- function getRuleHeader(){
- return "try{\
- var oHtml = " + (jpf.hasHtmlIdsInJs
- ? this.oExt.getAttribute("id")
- : "document.getElementById('"
- + this.oExt.getAttribute("id") + "')") + ";\
- \
- var pWidth = " + (this.pHtmlNode == this.pHtmlDoc.body
- ? (jpf.isIE
- ? "document.documentElement.offsetWidth"
- : "window.innerWidth")
- : "oHtml.parentNode.offsetWidth") + ";\
- \
- var pHeight = " + (this.pHtmlNode == this.pHtmlDoc.body
- ? (jpf.isIE
- ? "document.documentElement.offsetHeight"
- : "window.innerHeight")
- : "oHtml.parentNode.offsetHeight") + ";\
- }catch(e){\
- }";
- }
-
- /**
- * @macro
- */
- function setPercentage(expr, value){
- return String(expr).replace(jpf.percentageMatch, "((" + value + " * $1)/100)");
- }
-
- this.$updateLayout = function(){
- if (!parsed) {
- if (!this.oExt.getAttribute("id"))
- jpf.setUniqueHtmlId(this.oExt);
-
- var diff = jpf.getDiff(this.oExt);
- hordiff = diff[0];
- verdiff = diff[1];
- rule_header = getRuleHeader.call(this);
- parsed = true;
- }
-
- if (!updateQueue) {
- if (this.visible)
- this.oExt.style.display = "block";
- return;
- }
-
- if (this.left || this.top || this.right || this.bottom || this.$anchors.length)
- this.oExt.style.position = "absolute";
-
- var rules;
-
- if (updateQueue & HORIZONTAL) {
- rules = [];
-
- var left = this.left || this.$anchors[3];
- var right = this.right || this.$anchors[1];
- var width = this.width;
-
- if (right && typeof right == "string")
- right = setPercentage(right, "pWidth");
-
- if (left) {
- if (parseInt(left) != left) {
- left = setPercentage(left, "pWidth");
- rules.push("oHtml.style.left = (" + left + ") + 'px'");
- }
- else
- this.oExt.style.left = left + "px";
- }
- if (!left && right) {
- if (parseInt(right) != right) {
- right = setPercentage(right, "pWidth");
- rules.push("oHtml.style.right = (" + right + ") + 'px'");
- }
- else
- this.oExt.style.right = right + "px";
- }
- if (width) {
- if (parseInt(width) != width) {
- width = setPercentage(width, "pWidth");
- rules.push("oHtml.style.width = ("
- + width + " - " + hordiff + ") + 'px'");
- }
- else
- this.oExt.style.width = (width - hordiff) + "px";
- }
-
- if (right != null && left != null) {
- rules.push("oHtml.style.width = (pWidth - (" + right
- + ") - (" + left + ") - " + hordiff + ") + 'px'");
- }
-
- rule_h = (rules.length
- ? "try{" + rules.join(";}catch(e){};try{") + ";}catch(e){};"
- : "");
- }
-
- if (updateQueue & VERTICAL) {
- rules = [];
-
- var top = this.top || this.$anchors[0];
- var bottom = this.bottom || this.$anchors[2];
- var height = this.height;
-
- if (bottom && typeof bottom == "string")
- bottom = setPercentage(bottom, "pHeight");
-
- if (top) {
- if (parseInt(top) != top) {
- top = setPercentage(top, "pHeight");
- rules.push("oHtml.style.top = (" + top + ") + 'px'");
- }
- else
- this.oExt.style.top = top + "px";
- }
- if (!top && bottom) {
- if (parseInt(bottom) != bottom) {
- rules.push("oHtml.style.bottom = (" + bottom + ") + 'px'");
- }
- else
- this.oExt.style.bottom = bottom + "px";
- }
- if (height) {
- if (parseInt(height) != height) {
- height = setPercentage(height, "pHeight");
- rules.push("oHtml.style.height = (" + height + " - " + verdiff + ") + 'px'");
- }
- else
- this.oExt.style.height = (height - verdiff) + "px";
- }
-
- if (bottom != null && top != null) {
- rules.push("oHtml.style.height = (pHeight - (" + bottom +
- ") - (" + top + ") - " + verdiff + ") + 'px'");
- }
-
- rule_v = (rules.length
- ? "try{" + rules.join(";}catch(e){};try{") + ";}catch(e){};"
- : "");
- }
-
- if (rule_v || rule_h) {
- l.setRules(this.pHtmlNode, this.uniqueId + "_anchors",
- rule_header + "\n" + rule_v + "\n" + rule_h, true);
- }
- else {
- l.removeRule(this.pHtmlNode, this.uniqueId + "_anchors");
- }
-
- updateQueue = 0;
- disabled = false;
- };
-
- this.$addJmlLoader(function(){
- if (updateQueue)
- this.$updateLayout();
- });
-
- this.$jmlDestroyers.push(function(){
- this.disableAnchoring();
- });
-};
-
- - -/*FILEHEAD(/var/lib/jpf/src/core/node/multilevelbinding.js)SIZE(-1077090856)TIME(1238944816)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-var __MULTIBINDING__ = 1 << 7;
-
-
-/**
- * Baseclass adding the ability to databind the selection of this Element.
- * Example:
- * In this example the selection of the dropdown determines the value of the city
- * xml element in mdlForm. The dropdown is filled with information from mdlCities.
- * <code>
- * <j:model id="mdlCities" load="url:cities.php" />
- * <j:model id="mdlForm">
- * <form>
- * <name />
- * <city />
- * </form>
- * </j:model>
- *
- * <j:bar model="mdlForm">
- * <j:textbox ref="name" />
- * <j:dropdown ref="city" model="mdlCities">
- * <j:bindings>
- * <j:caption select="text()" />
- * <j:value select="@code" />
- * <j:traverse select="city" />
- * </j:bindings>
- * </j:dropdown>
- * </j:bar>
- * </code>
- *
- * @see element.dropdown
- * @private
- * @constructor
- * @baseclass
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.5
- */
-jpf.MultiLevelBinding = function(jmlNode){
- this.uniqueId = jpf.all.push(this) - 1;
- this.nodeFunc = jpf.NODE_HIDDEN;
- this.tagName = "MultiBinding";
- this.name = jmlNode.name + "_multibinding";
-
- this.$propHandlers = {}; //@todo fix this in each component
- this.$domHandlers = {
- "remove" : [],
- "insert" : [],
- "reparent" : [],
- "removechild" : []
- };
- this.$booleanProperties = {};
- this.$supportedProperties = [];
-
- jmlNode.$regbase = jmlNode.$regbase | __MULTIBINDING__;
-
- jpf.makeClass(this);
- this.inherit(jpf.DataBinding); /** @inherits jpf.DataBinding */
-
- this.getActionTracker = function(ignoreMe){
- return jmlNode.getActionTracker(ignoreMe);
- };
-
- this.getHost = function(){
- return jmlNode;
- };
-
- this.changeSelection = function(list){
- var i, k, addList, removeList, xmlNode,
- selNodes = this.getSelectionNodes(),
- traverseNodes = jmlNode.getTraverseNodes();
- //Find nodes that are removed from the selection
- for (removeList = [], i = 0; i < selNodes.length; i++) {
- for (k = 0; k < traverseNodes.length; k++) {
- xmlNode = null;
- if (this.compareNodes(selNodes[i], traverseNodes[k])) {
- xmlNode = traverseNodes[k];
- break;
- }
- }
-
- if (!xmlNode || !list.contains(xmlNode))
- removeList.push(selNodes[i]);
- }
-
- //Find nodes that are added to the selection
- for (addList = [], i = 0; i < list.length; i++) {
- var found = false;
- for (k = 0; k < selNodes.length; k++) {
- if (this.compareNodes(selNodes[k], list[i])) {
- found = true;
- break;
- }
- }
-
- if (!found)
- addList.push(mlNode.createSelectionNode(list[i]));
- }
-
- //Use Action Tracker
- this.executeAction("addRemoveNodes", [this.xmlRoot, addList, removeList],
- "changeselection", jmlNode.selected);
- };
-
- this.change = function(value){
- if (this.errBox && this.errBox.visible && this.isValid())
- this.clearError();
-
- if ((!this.createModel || !this.dataParent && !this.getModel()) && !this.xmlRoot) { //!this.$jml.getAttribute("ref")
- //Not databound
- if (this.dispatchEvent("beforechange", {value : value}) === false)
- return;
-
- this.setProperty("value", value);
- return this.dispatchEvent("afterchange", {value : value});
- }
-
- this.executeActionByRuleSet("change", this.mainBind, this.xmlRoot, value);
- };
-
- if (jmlNode.hasFeature(__VALIDATION__)) {
- this.addEventListener("beforechange", function(){
- jmlNode.dispatchEvent("beforechange")
- });
- this.addEventListener("afterchange", function(){
- jmlNode.dispatchEvent("afterchange")
- });
- }
-
- this.clear = function(nomsg, do_event){
- this.documentId = this.xmlRoot = this.cacheID = subTreeCacheContext = null;
-
- if (!nomsg && jmlNode["default"])
- jmlNode.setValue(jmlNode["default"]); //@todo setting action
- else
- jmlNode.clearSelection();
- //else if (jmlNode.$showSelection)
- //jmlNode.$showSelection("");
- };
-
- this.disable = function(){
- jmlNode.disable();
- this.disabled = true
- };
-
- this.enable = function(){
- jmlNode.enable();
- this.disabled = false
- };
-
- this.$xmlUpdate = function(action, xmlNode, listenNode, UndoObj){
- if (UndoObj)
- UndoObj.xmlNode = this.xmlRoot;
-
- this.$updateSelection();
-
- if (jmlNode["default"] && !jmlNode.getValue())
- jmlNode.setValue(jmlNode["default"]);
-
- this.dispatchEvent("xmlupdate", {
- action : action,
- xmlNode : xmlNode,
- listenNode: listenNode
- });
- };
-
- this.$load = function(XMLRoot){
- //if(jmlNode.name == "refSMArt_Situatie") debugger;
- //Add listener to XMLRoot Node
- jpf.xmldb.addNodeListener(XMLRoot, this);
-
- this.$updateSelection();
-
- if (jmlNode["default"] && !jmlNode.getValue())
- jmlNode.setValue(jmlNode["default"]);
-
- if (!this.createModel && this.disabled != jmlNode.disabled)
- jmlNode.setProperty("disabled", this.disabled);
- };
-
- this.$updateSelection = function(){
- if (!jmlNode.xmlRoot || !mlNode.xmlRoot)
- return;
-
- var i, k, xmlNode;
- if (jmlNode.multiselect) {
- var selNodes = this.getSelectionNodes();
- var traverseNodes = jmlNode.getTraverseNodes();
-
- //Check if a selected node is not selected yet
- for (i = 0; i < selNodes.length; i++) {
- for (k = 0; k < traverseNodes.length; k++) {
- xmlNode = null;
- if (this.compareNodes(selNodes[i], traverseNodes[k])) {
- xmlNode = traverseNodes[k];
- break;
- }
- }
-
- if (xmlNode && !jmlNode.isSelected(xmlNode))
- jmlNode.select(xmlNode, null, null, null, null, true);
- }
-
- //Check if a currently selected item should be deselected
- var jSelNodes = jmlNode.getSelection();
- for (i = 0; i < jSelNodes.length; i++) {
- for (k = 0; k < selNodes.length; k++) {
- xmlNode = false;
- if (this.compareNodes(selNodes[k], jSelNodes[i])) {
- xmlNode = true;
- break;
- }
- }
-
- if (!xmlNode)
- jmlNode.select(jSelNodes[i], null, null, null, null, true);
- }
-
- //jmlNode.selectList(selList);
- }
- else {
- if (!jmlNode.xmlRoot) {
- //Selection is maintained and visualized, but no Nodes are selected
- if (jmlNode.$showSelection)
- jmlNode.$showSelection();
- return;
- }
-
- xmlNode = jmlNode.findXmlNodeByValue(this.applyRuleSetOnNode(this.mainBind, this.xmlRoot));
- if (xmlNode) {
- if (jmlNode.$showSelection)
- jmlNode.$showSelection(jmlNode.applyRuleSetOnNode("caption", xmlNode));
- if (jmlNode.selected != xmlNode) {
- jmlNode.select(xmlNode, null, null, null, null, true);
- jmlNode.dispatchEvent("updateselect");
- jmlNode.setConnections(xmlNode);
- }
- }
- //if (jmlNode.clearOnNoSelection)
- else {
- jmlNode.clearSelection(null, true);
- }
- }
- };
-
- this.getSelectionNodes = function(){
- return this.xmlRoot
- ? this.xmlRoot.selectNodes(jmlNode.$jml.getAttribute("ref"))
- : [];//This should be read from the bindingRule //this.getTraverseNodes();
- };
-
- this.getSelectionValue = function(xmlNode){
- return jpf.getXmlValue(xmlNode, "text()")
- };
-
- this.getSelectionNodeByValue = function(value, nodes){
- if (!nodes)
- nodes = this.getSelectionNodes();
- for (var i = 0; i < nodes.length; i++) {
- if (this.getSelectionValue(nodes[i]) == value)
- return nodes[i];
- }
-
- return false;
- };
-
- this.mode = "default";//"copy"
- this.xpath = "text()";
-
- this.createSelectionNode = function(xmlNode){
- if (this.mode == "copy") {
- return jpf.xmldb.clearConnections(xmlNode.cloneNode(true));
- }
- else if (this.xmlRoot) {
- var value = jmlNode.applyRuleSetOnNode(jmlNode.mainBind, xmlNode);
- var selNode = this.xmlRoot.ownerDocument.createElement(jmlNode.$jml.getAttribute("ref"));
- jpf.xmldb.createNodeFromXpath(selNode, this.xpath);
- jpf.xmldb.setNodeValue(selNode.selectSingleNode(this.xpath), value);
- return selNode;
- }
- };
-
- this.compareNodes = function(selNode, traverseNode){
- if (this.mode == "copy") {
- //Other ways of linking should be considered here
- return jmlNode.applyRuleSetOnNode(jmlNode.mainBind, traverseNode)
- == jmlNode.applyRuleSetOnNode(jmlNode.mainBind, selNode);
- }
- else {
- return jmlNode.applyRuleSetOnNode(jmlNode.mainBind, traverseNode)
- == this.getSelectionValue(selNode);
- }
- };
-
- var mlNode = this;
- jmlNode.addEventListener("afterselect", function(e){
- if (!mlNode.xmlRoot && (!this.createModel || !mlNode.$model)) {
- if (this.value)
- mlNode.change(this.value);
-
- return;
- }
-
- if (this.multiselect)
- mlNode.changeSelection(e.list);
- else
- mlNode.change(this.applyRuleSetOnNode(this.mainBind, e.xmlNode));
- });
-
- //jmlNode.addEventListener("xmlupdate", function(action, xmlNode){
- // updateSelection.call(this, null, this.selected);
- //});
- jmlNode.addEventListener("afterload", function(){
- if (this.multiselect) {
- //skipped...
- }
- else {
- var xmlNode = this.findXmlNodeByValue(mlNode.applyRuleSetOnNode(
- mlNode.mainBind, mlNode.xmlRoot));
- if (xmlNode) {
- if (jmlNode.$showSelection)
- jmlNode.$showSelection(jmlNode.applyRuleSetOnNode("caption", xmlNode));
- jmlNode.select(xmlNode, null, null, null, null, true);
- jmlNode.setConnections(xmlNode);
- }
- else if (jmlNode.clearOnNoSelection) {
- //This seems cumbersome... check abstraction
- xmlNode = mlNode.getNodeFromRule(mlNode.mainBind,
- mlNode.xmlRoot, null, null, true);
- jpf.xmldb.setNodeValue(xmlNode, "");
- if (this.$updateOtherBindings)
- this.$updateOtherBindings();
- if (this.$showSelection)
- this.$showSelection();
- }
- }
- });
-
- jmlNode.addEventListener("afterdeselect", function(){
- if (!mlNode.xmlRoot)
- return;
-
- //Remove sel nodes
- if (this.multiselect) {
- /*
- //Translate sel to a list of nodes in this xml space
- for(var removeList=[],xmlNode, value, i=0;i<sel.length;i++){
- xmlNode = mlNode.findXmlNodeByValue(this.applyRuleSetOnNode(this.mainBind, sel[i]));
- //Node to be unselected (removed) cannot be found. This should not happen.
- if (!xmlNode) continue;
- removeList.push(xmlNode);
- }
-
- //Remove node using ActionTracker
- if (removeList.length)
- mlNode.SelectRemove(removeList);
- */
- }
- //Set value to ""
- else
- if (jmlNode.clearOnNoSelection) {
- this.$updateOtherBindings();
- //mlNode.change("");
-
- //This should be researched better....
- jpf.xmldb.setNodeValue(jpf.xmldb.createNodeFromXpath(mlNode.xmlRoot,
- mlNode.bindingRules[mlNode.mainBind][0].getAttribute("select")),
- "", true);
- }
- });
-};
-
- - -/*FILEHEAD(/var/lib/jpf/src/core/node/dragdrop.js)SIZE(-1077090856)TIME(1238950355)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-var __DRAGDROP__ = 1 << 5;
-
-
-/**
- * Baseclass adding drag&drop features to this element. This baseclass
- * operates on the bound data of this element. When a rendered item is dragged
- * and dropped the bound data is moved or copied from one element to another,
- * or to the same element but at a different position. Drag&drop can be turned
- * on with a simple boolean, or detailed rules can be specified which data
- * should be dragged and/or dropped and where.
- *
- * Example:
- * <code>
- * <j:smartbinding>
- * <j:actions>
- * <j:move
- * select = "self::folder"
- * set = "{@link term.datainstruction data instruction}" />
- * <j:copy
- * select = "self::file"
- * set = "{@link term.datainstruction data instruction}" />
- * </j:actions>
- * <j:dragdrop>
- * <j:allow-drag select = "person" copy-condition="event.ctrlKey" />
- * <j:allow-drop
- * select = "person"
- * target = "company|office"
- * action = "list-append"
- * copy-condition = "event.ctrlKey" />
- * <j:allow-drop
- * select = "offer"
- * target = "person"
- * action = "tree-append"
- * copy-condition = "event.ctrlKey" />
- * </j:dragdrop>
- * </j:smartbinding>
- * </code>
- *
- * Example:
- * <code>
- * <j:list
- * dragEnabled = "true"
- * dropEnabled = "true"
- * dragMoveEnabled = "true" />
- * </code>
- *
- * @event dragdata Fires before a drag&drop operation is started to determine the data that is dragged.
- * object:
- * {XMLElement} data the default data for the drag&drop operation
- * @event dragstart Fires before a drag operation is started.
- * cancellable: Prevents the drag operation to start.
- * object:
- * {XMLElement} data the data for the drag&drop operation
- * {XMLElement} selection the selection at the start of the drag operation
- * {HTMLElement} indicator the html element that is shown while dragging the data
- * {JMLElement} host the jml source element.
- * @event dragover Fires when the users drags over this jml element.
- * cancellable: Prevents the possibility to drop.
- * object:
- * {XMLElement} data the data for the drag&drop operation
- * {XMLElement} selection the selection at the start of the drag operation
- * {HTMLElement} indicator the html element that is shown while dragging the data
- * {JMLElement} host the jml source element.
- * @event dragout Fires when the user moves away from this jml element.
- * object:
- * {XMLElement} data the data for the drag&drop operation
- * {XMLElement} selection the selection at the start of the drag operation
- * {HTMLElement} indicator the html element that is shown while dragging the data
- * {JMLElement} host the jml source element.
- * @event dragdrop Fires when the user drops an item on this jml element.
- * cancellable: Prevents the possibility to drop.
- * object:
- * {XMLElement} data the data for the drag&drop operation
- * {XMLElement} selection the selection at the start of the drag operation
- * {HTMLElement} indicator the html element that is shown while dragging the data
- * {JMLElement} host the jml source element.
- * {Boolean} candrop wether the data can be inserted at the point hovered over by the user
- *
- * @see element.allow-drag
- * @see element.allow-drop
- * @see element.dragdrop
- *
- * @define dragdrop
- * @allowchild allow-drop, allow-drag
- * @define allow-drag Specifies when nodes can be dragged from this element.
- * @attribute {String} select an xpath statement querying the xml data element that is dragged. If the query matches a node it is allowed to be dropped. The xpath is automatically prefixed by 'self::'.
- * @attribute {String} copy-condition a javascript expression that determines whether the dragged element is a copy or a move. Use event.ctrlKey to use the Ctrl key to determine whether the element is copied.
- * @define allow-drop Specifies when nodes can be dropped into this element.
- * @attribute {String} select an xpath statement querying the xml data element that is dragged. If the query matches a node it is allowed to be dropped. The xpath is automatically prefixed by 'self::'.
- * @attribute {String} target an xpath statement determining the new parent of the dropped xml data element. The xpath is automatically prefixed by 'self::'.
- * @attribute {String} action the action to perform when the xml data element is inserted.
- * Possible values:
- * tree-append Appends the xml data element to the element it's dropped on.
- * list-append Appends the xml data element to the root element of this element.
- * insert-before Inserts the xml data element before the elements it's dropped on.
- * @attribute {String} copy-condition a javascript expression that determines whether the drop is a copy or a move. Use event.ctrlKey to use the Ctrl key to determine whether the element is copied.
- */
-/**
- * @constructor
- * @baseclass
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.5
- */
-jpf.DragDrop = function(){
- this.$regbase = this.$regbase | __DRAGDROP__;
-
- /* **********************
- Actions
- ***********************/
-
- /**
- * Copies a data element to the dataset of this element.
- *
- * @action
- * @param {XMLElement} xmlNode the xml data element which is copied.
- * @param {XMLElement} pNode the new parent element of the copied data element. If none specified the root element of the data loaded in this element is used.
- * @param {XMLElement} [beforeNode] the position where the data element is inserted.
- */
- this.copy = function(xmlNode, pNode, beforeNode){
- xmlNode = xmlNode.cloneNode(true);
-
- //Use Action Tracker
- var exec = this.executeAction("appendChild",
- [pNode, xmlNode, beforeNode], "copy", xmlNode);
-
- if (exec !== false)
- return xmlNode;
-
- return false;
- };
-
- /**
- * Moves a data element to the dataset of this element.
- *
- * @action
- * @param {XMLElement} xmlNode the xml data element which is copied.
- * @param {XMLElement} pNode the new parent element of the moved data element. If none specified the root element of the data loaded in this element is used.
- * @param {XMLElement} [beforeNode] the position where the data element is inserted.
- */
- this.move = function(xmlNode, pNode, beforeNode){
- //Use Action Tracker
- var exec = this.executeAction("moveNode",
- [pNode, xmlNode, beforeNode], "move", xmlNode);
- if (exec !== false)
- return xmlNode;
- return false;
- };
-
- /**
- * Determines whether the user is allowed to drag the passed XML node.
- *
- * @param {XMLElement} x the xml data element subject to the test.
- * @return {Boolean} result of the test
- */
- this.isDragAllowed = function(x){
- if(typeof jpf.offline != "undefined" && !jpf.offline.canTransact())
- return false;
-
- if (this.disabled || !x)
- return false;
-
- if (this.dragenabled || this.dragmoveenabled)
- return true;
-
- var rules = (this.dragdropRules || {})["allow-drag"];
- if (!rules || !rules.length)
- return false;
-
- for (var i = 0; i < rules.length; i++) {
- if (x.selectSingleNode("self::" +
- jpf.parseExpression(rules[i].getAttribute("select"))
- .split("|").join("|self::")))
- return rules[i];
- }
-
- return false;
- };
-
- /**
- * Determines whether the user is allowed to dropped the passed XML node.
- *
- * @param {XMLElement} x the xml data element subject to the test.
- * @param {Object} target
- * @return {Boolean} result of the test
- */
- this.isDropAllowed = function(x, target){
- if(typeof jpf.offline != "undefined" && !jpf.offline.canTransact())
- return false;
-
- if (this.disabled || !x || !target)
- return false;
-
- var data, tgt;
-
- if (this.dropenabled) {
- data = x.selectSingleNode("true".indexOf(this.dropenabled) == -1
- ? this.dropenabled
- : (this.hasFeature(__MULTISELECT__)
- ? "self::" + this.traverse.replace(/.*?\/([^\/]+)(\||$)/g, "$1$2").split("|").join("|self::")
- : "."));
-
- tgt = target || target == this.xmlRoot && target || null;
-
- if (data && tgt && !jpf.xmldb.isChildOf(data, tgt, true))
- return [tgt, null];
- }
-
- var rules = (this.dragdropRules || {})["allow-drop"];
-
- if (!rules || !rules.length)
- return false;
-
- for (var op, strTgt, i = 0; i < rules.length; i++) {
- data = x.selectSingleNode("self::" +
- jpf.parseExpression(rules[i].getAttribute("select"))
- .split("|").join("|self::"));
-
- if (!data)
- continue;
-
- strTgt = rules[i].getAttribute("target");
- if (!strTgt || strTgt == ".") {
- op = rules[i].getAttribute("operation");
- tgt = (op == "list-append" || target == this.xmlRoot
- ? this.xmlRoot
- : null);
- }
- else
- tgt = target.selectSingleNode("self::" + strTgt);
-
- if (data && tgt && !jpf.xmldb.isChildOf(data, tgt, true))
- return [tgt, rules[i]];
- }
-
- return false;
- };
-
- this.$dragDrop = function(xmlReceiver, xmlNode, rule, defaction, isParent, srcRule, event){
- if (action == "tree-append" && isParent)
- return false;
-
- /*
- Possibilities:
-
- tree-append [default]: xmlNode.appendChild(movedNode);
- list-append : xmlNode.parentNode.appendChild(movedNode);
- insert-before : xmlNode.parentNode.insertBefore(movedNode, xmlNode);
- */
- var action = rule && rule.getAttribute("operation") || defaction;
-
- //copy-condition convenience variables
- var internal = jpf.DragServer.dragdata.host == this;
- var ctrlKey = event.ctrlKey;
- var keyCode = event.keyCode;
-
- //jpf.parseExpression
- var ifcopy = rule && rule.getAttribute("copy-condition")
- ? eval(rule.getAttribute("copy-condition"))
- : this.dragmoveenabled;
- if (!ifcopy)
- ifcopy = typeof srcRule == "object"
- && srcRule.getAttribute("copy-condition")
- ? eval(srcRule.getAttribute("copy-condition"))
- : false;
-
- var sNode, actRule = ifcopy ? 'copy' : 'move';
-
- var parentXpath = rule ? rule.getAttribute("parent") : null;
- switch (action) {
- case "list-append":
- xmlReceiver = (isParent
- ? xmlReceiver
- : this.getTraverseParent(xmlReceiver));
- if (parentXpath)
- xmlReceiver = xmlReceiver.selectSingleNode(parentXpath);
- sNode = this[actRule](xmlNode, xmlReceiver);
- break;
- case "insert-before":
- sNode = isParent
- ? this[actRule](xmlNode, xmlReceiver)
- : this[actRule](xmlNode, xmlReceiver.parentNode, xmlReceiver);
- break;
- case "tree-append":
- if (parentXpath)
- xmlReceiver = xmlReceiver.selectSingleNode(parentXpath);
- sNode = this[actRule](xmlNode, xmlReceiver);
- break;
- }
-
- if (this.selectable && sNode)
- this.select(sNode, null, null, null, true);
-
- return sNode;
- };
-
- /* **********************
- Init
- ***********************/
-
- var drag_inited;
- /**
- * Loads the dragdrop rules from the j:dragdrop element
- *
- * @param {Array} rules the rules array created using {@link core.jpf.method.getrules}
- * @param {XMLElement} [node] the reference to the j:dragdrop element
- * @see SmartBinding
- * @private
- */
- this.loadDragDrop = function(rules, node){
- jpf.console.info("Initializing Drag&Drop for " + this.tagName
- + "[" + (this.name || '') + "]");
-
- if (rules) {
- if (this.dragdropRules)
- this.unloadDragDrop();
-
- //Set Properties
- this.dragdropRules = rules;
- }
-
- //Set cursors
- //SHOULD come from skin
- this.icoAllowed = "";//this.xmlDragDrop.getAttribute("allowed");
- this.icoDenied = "";//this.xmlDragDrop.getAttribute("denied");
-
- //Setup External Object
- this.oExt.dragdrop = false;
-
- this.oExt.onmousedown = function(e){
- if (!e)
- e = event;
- var fEl, srcEl = e.originalTarget || e.srcElement || e.target;
- if (this.host.hasFeature(__MULTISELECT__) && srcEl == this.host.oInt)
- return;
- this.host.dragging = 0;
-
- var srcElement = e.srcElement || e.target;
- if (this.host.allowdeselect
- && (srcElement == this
- || srcElement.getAttribute(jpf.xmldb.htmlIdTag)))
- return this.host.clearSelection(); //hacky
-
- //MultiSelect must have carret behaviour AND deselect at clicking white
- //for(prop in e) if(prop.match(/x/i)) str += prop + "\n";
- //alert(str);
- if (this.host.findValueNode)
- fEl = this.host.findValueNode(srcEl);
- var el = (fEl
- ? jpf.xmldb.getNode(fEl)
- : jpf.xmldb.findXMLNode(srcEl));
- if (this.selectable && (!this.host.selected || el == this.host.xmlRoot) || !el)
- return;
-
- if (this.host.isDragAllowed(this.selectable ? this.host.selected : el)) {
- this.host.dragging = 1;
-
- jpf.DragServer.coordinates = {
- srcElement : srcEl,
- offsetX : (e.layerX ? e.layerX - srcEl.offsetLeft : e.offsetX), //|| jpf.event.layerX - srcEl.offsetLeft,
- offsetY : (e.layerY ? e.layerY - srcEl.offsetTop : e.offsetY), //|| jpf.event.layerY - srcEl.offsetTop,
- clientX : e.clientX,
- clientY : e.clientY
- };
-
- jpf.DragServer.start(this.host);
- }
-
- //e.cancelBubble = true;
- }
-
- this.oExt.onmousemove = function(e){
- if (!e) e = event;
- if (this.host.dragging != 1) return;//e.button != 1 ||
- //if(Math.abs(jpf.DragServer.coordinates.offsetX - (e.layerX ? e.layerX - jpf.DragServer.coordinates.srcElement.offsetLeft : e.offsetX)) < 6 && Math.abs(jpf.DragServer.coordinates.offsetY - (e.layerX ? e.layerY - jpf.DragServer.coordinates.srcElement.offsetTop : e.offsetY)) < 6)
- //return;
-
- //jpf.DragServer.start(this.host);
- };
-
- this.oExt.onmouseup = function(){
- this.host.dragging = 0;
- };
-
- this.oExt.ondragmove =
- this.oExt.ondragstart = function(){ return false; };
-
- if(document.elementFromPointAdd)
- document.elementFromPointAdd(this.oExt);
-
- if (this.$initDragDrop && (!rules || !drag_inited))
- this.$initDragDrop();
-
- drag_inited = true;
- };
- //this.addEventListener("skinchange", this.loadDragDrop);
-
- /**
- * Unloads the dragdrop rules from this element
- *
- * @see SmartBinding
- * @private
- */
- this.unloadDragDrop = function(){
- this.xmlDragDrop = this.dragdropRules = this.icoAllowed = this.icoDenied
- = this.oExt.dragdrop = this.oExt.onmousedown = this.oExt.onmousemove
- = this.oExt.onmouseup = this.oExt.ondragmove = this.oExt.ondragstart
- = null;
-
- if (document.elementFromPointRemove)
- document.elementFromPointRemove(this.oExt);
- };
-
- this.$booleanProperties["dragenabled"] = true;
- this.$booleanProperties["dragmoveenabled"] = true;
- this.$supportedProperties.push("dropenabled", "dragenabled", "dragmoveenabled");
-
- /**
- * @attribute {Boolean} dragEnabled whether the element allows dragging of it's items.
- * Example:
- * <code>
- * <j:list dragEnabled="true">
- * <j:item>item 1</j:item>
- * <j:item>item 2</j:item>
- * <j:item>item 3</j:item>
- * </j:list>
- * </code>
- * @attribute {Boolean} dragMoveEnabled whether dragged items are moved or copied when holding the Ctrl key.
- * Example:
- * <code>
- * <j:list dragMoveEnabled="true">
- * <j:item>item 1</j:item>
- * <j:item>item 2</j:item>
- * <j:item>item 3</j:item>
- * </j:list>
- * </code>
- * @attribute {Boolean} dropEnabled whether the element allows items to be dropped.
- * Example:
- * <code>
- * <j:list dropEnabled="true">
- * <j:item>item 1</j:item>
- * <j:item>item 2</j:item>
- * <j:item>item 3</j:item>
- * </j:list>
- * </code>
- * @attribute {String} dragdrop the name of the j:dragdrop element for this element.
- * <code>
- * <j:list dragdrop="bndDragdrop" />
- *
- * <j:dragdrop id="bndDragdrop">
- * <j:allow-drag select = "person" copy-condition="event.ctrlKey" />
- * <j:allow-drop
- * select = "offer"
- * target = "person"
- * action = "tree-append"
- * copy-condition = "event.ctrlKey" />
- * </j:dragdrop>
- * </code>
- */
- this.$propHandlers["dragenabled"] =
- this.$propHandlers["dragmoveenabled"] =
- this.$propHandlers["dropenabled"] = function(value){
- if (value && !drag_inited)
- this.loadDragDrop();
- };
-
- this.$propHandlers["dragdrop"] = function(value){
- var sb = this.smartBinding || (jpf.isParsing
- ? jpf.JmlParser.getFromSbStack(this.uniqueId)
- : this.$propHandlers["smartbinding"].call(this, new jpf.smartbinding()));
-
- if (!value) {
- //sb.removeBindings();
- throw new Error("Not Implemented"); //@todo
- return;
- }
-
- if (!jpf.nameserver.get("dragdrop", value))
- throw new Error(jpf.formatErrorString(1066, this,
- "Connecting dragdrop",
- "Could not find dragdrop by name '"
- + value + "'", this.$jml));
-
- sb.addDragDrop(jpf.nameserver.get("dragdrop", value));
- };
-
- this.$jmlDestroyers.push(function(){
- this.unloadDragDrop();
- });
-};
-
-/**
- * @private
- */
-jpf.DragServer = {
- Init : function(){
- jpf.dragmode.defineMode("dragdrop", this);
-
- jpf.addEventListener("hotkey", function(e){
- if (jpf.window.dragging && e.keyCode == 27) {
- if (document.body.lastHost && document.body.lastHost.dragOut)
- document.body.lastHost.dragOut(jpf.dragHost);
-
- return jpf.DragServer.stopdrag();
- }
- });
- },
-
- /* **********************
- API
- ***********************/
-
- start : function(host){
- if (document.elementFromPointReset)
- document.elementFromPointReset();
-
- //Create Drag Object
- var selection = host.selectable ? host.getSelection()[0] : host.xmlRoot; //currently only a single item is supported
-
- var srcRule = host.isDragAllowed(selection);
- if (!srcRule) return;
-
- var data = srcRule.nodeType
- ? selection.selectSingleNode("self::" +
- jpf.parseExpression(srcRule.getAttribute("select"))
- .split("|").join("|self::"))
- : selection;
-
- if (host.hasEventListener("dragdata"))
- data = host.dispatchEvent("dragdata", {data : data});
-
- this.dragdata = {
- selection : selection,
- data : data,
- indicator : host.$showDragIndicator(selection, this.coordinates),
- host : host
- };
-
- //EVENT - cancellable: ondragstart
- if (host.dispatchEvent("dragstart", this.dragdata) === false)
- return false;//(this.host.$tempsel ? select(this.host.$tempsel) : false);
- host.dragging = 2;
-
- jpf.dragmode.setMode("dragdrop");
- },
-
- stop : function(runEvent){
- if (this.last) this.dragout();
-
- //Reset Objects
- this.dragdata.host.dragging = 0;
- this.dragdata.host.$hideDragIndicator();
-
- //????EVENT: ondragstop
- //if(runEvent && this.dragdata.host.ondragstop) this.dragdata.host.ondragstop();
-
- jpf.dragmode.clear();
- this.dragdata = null;
- },
-
- m_out : function(){
- //this.style.cursor = "default";
- if (this.$onmouseout)
- this.$onmouseout();
- this.onmouseout = this.$onmouseout || null;
- },
-
- dragover : function(o, el, e){
- if(!e) e = event;
- var fEl;
- if (o.findValueNode)
- fEl = o.findValueNode(el);
- //if(!fEl) return;
-
- //Check Permission
- var elSel = (fEl
- ? jpf.xmldb.getNode(fEl)
- : jpf.xmldb.findXMLNode(el));
- var candrop = o.isDropAllowed
- ? o.isDropAllowed(this.dragdata.selection, elSel || o.xmlRoot)
- : false;
- //EVENT - cancellable: ondragover
- if (o.dispatchEvent("dragover", this.dragdata) === false)
- candrop = false;
-
- //Set Cursor
- var srcEl = e.originalTarget || e.srcElement || e.target;
- //srcEl.style.cursor = (candrop ? o.icoAllowed : o.icoDenied);
- if (srcEl.onmouseout != this.m_out) {
- srcEl.$onmouseout = srcEl.onmouseout;
- srcEl.onmouseout = this.m_out;
- }
- //o.oExt.style.cursor = (candrop ? o.icoAllowed : o.icoDenied);
-
- //REQUIRED INTERFACE: __dragover()
- if (o && o.$dragover)
- o.$dragover(el, this.dragdata, candrop);
-
- this.last = o;
- },
-
- dragout : function(o){
- if (this.last == o) return false;
-
- //EVENT: ondragout
- if (o)
- o.dispatchEvent("dragout", this.dragdata);
-
- //REQUIRED INTERFACE: __dragout()
- if (this.last && this.last.$dragout)
- this.last.$dragout(null, this.dragdata);
-
- //Reset Cursor
- //o.oExt.style.cursor = "default";
- this.last = null;
- },
-
- dragdrop : function(o, el, srcO, e){
- //Check Permission
- var elSel = (o.findValueNode
- ? jpf.xmldb.getNode(o.findValueNode(el))
- : jpf.xmldb.findXMLNode(el));
- var candrop = (o.isDropAllowed)//elSel &&
- ? o.isDropAllowed(this.dragdata.data, elSel || o.xmlRoot)
- : false;
-
- //EVENT - cancellable: ondragdrop
- if (candrop) {
- if (o.dispatchEvent("dragdrop", jpf.extend({candrop : candrop},
- this.dragdata)) === false)
- candrop = false;
- else {
- var action = candrop[1]
- && candrop[1].getAttribute("operation")
- || (o.isTreeArch ? "tree-append" : "list-append");
- if (action == "list-append" && o == this.dragdata.host)
- candrop = false;
- }
- }
-
- //Exit if not allowed
- if (!candrop) {
- this.dragout(o);
- return false;
- }
-
- //Move XML
- var rNode = o.$dragDrop(candrop[0], this.dragdata.data, candrop[1],
- action, (candrop[0] == o.xmlRoot), // || !o.isTraverseNode(candrop[0])
- srcO.isDragAllowed(this.dragdata.selection), e);
- this.dragdata.resultNode = rNode;
-
- //REQUIRED INTERFACE: __dragdrop()
- if (o && o.$dragdrop) {
- o.$dragdrop(el, jpf.extend({
- htmlEvent : e,
- xmlNode : rNode
- }, this.dragdata), candrop);
- }
-
- //Reset Cursor
- //o.oExt.style.cursor = "default";
- this.last = null;
- },
-
- /* **********************
- Mouse Movements
- ***********************/
-
- onmousemove : function(e){
- if (!jpf.DragServer.dragdata) return;
- if (!e) e = event;
- var dragdata = jpf.DragServer.dragdata;
-
- if (!dragdata.started
- && Math.abs(jpf.DragServer.coordinates.clientX - e.clientX) < 6
- && Math.abs(jpf.DragServer.coordinates.clientY - e.clientY) < 6)
- return;
-
- if (!dragdata.started) {
- if (dragdata.host.$dragstart)
- dragdata.host.$dragstart(null, dragdata);
- dragdata.started = true;
- }
-
- //dragdata.indicator.style.top = e.clientY+"px";
- //dragdata.indicator.style.left = e.clientX+"px";
-
- var storeIndicatorTopPos = dragdata.indicator.style.top;
- //jpf.console.info("INDICATOR BEFORE: "+dragdata.indicator.style.top+" "+dragdata.indicator.style.left);
- //get Element at x, y
- dragdata.indicator.style.display = "block";
- if (dragdata.indicator)
- dragdata.indicator.style.top = "10000px";
-
- jpf.DragServer.dragdata.x = e.clientX + document.documentElement.scrollLeft;
- jpf.DragServer.dragdata.y = e.clientY + document.documentElement.scrollTop;
- var el = document.elementFromPoint(jpf.DragServer.dragdata.x,
- jpf.DragServer.dragdata.y);
-
- dragdata.indicator.style.top = storeIndicatorTopPos;
- //jpf.console.info("INDICATOR AFTER: "+dragdata.indicator.style.top+" "+dragdata.indicator.style.left+" "+jpf.DragServer.dragdata.x+" "+jpf.DragServer.dragdata.y);
- //Set Indicator
- dragdata.host.$moveDragIndicator(e);
-
- //get element and call events
- var receiver = jpf.findHost(el);
-
- //Run Events
- jpf.DragServer.dragout(receiver);
- if (receiver)
- jpf.DragServer.dragover(receiver, el, e);
-
- jpf.DragServer.lastTime = new Date().getTime();
- },
-
- onmouseup : function(e){
- if(!e) e = event;
-
- if (!jpf.DragServer.dragdata.started
- && Math.abs(jpf.DragServer.coordinates.clientX - e.clientX) < 6
- && Math.abs(jpf.DragServer.coordinates.clientY - e.clientY) < 6) {
- jpf.DragServer.stop(true)
- return;
- }
-
- //get Element at x, y
- var indicator = jpf.DragServer.dragdata.indicator;
-
- var storeIndicatorTopPos = indicator.style.top;
- //jpf.console.info("INDICATOR UP BEFORE: "+indicator.style.top+" "+indicator.style.left);
- if (indicator)
- indicator.style.top = "10000px";
-
- jpf.DragServer.dragdata.x = e.clientX+document.documentElement.scrollLeft;
- jpf.DragServer.dragdata.y = e.clientY+document.documentElement.scrollTop;
- var el = document.elementFromPoint(jpf.DragServer.dragdata.x,
- jpf.DragServer.dragdata.y);
-
- indicator.style.top = storeIndicatorTopPos;
- //jpf.console.info("INDICATOR UP AFTER: "+indicator.style.top+" "+indicator.style.left);
-
- //get element and call events
- var host = jpf.findHost(el);
-
- //Run Events
- if (host != jpf.DragServer.host)
- jpf.DragServer.dragout(host);
- jpf.DragServer.dragdrop(host, el, jpf.DragServer.dragdata.host, e);
- jpf.DragServer.stop(true)
-
- //Clear Selection
- if (jpf.isNS) {
- var selObj = window.getSelection();
- if (selObj)
- selObj.collapseToEnd();
- }
- }
-};
-
-if (jpf.dragmode)
- jpf.DragServer.Init();
-else
- jpf.Init.addConditional(function(){jpf.DragServer.Init();}, null, 'jpf.dragmode');
-
- - -/*FILEHEAD(/var/lib/jpf/src/core/lib/scrollbar.js)SIZE(-1077090856)TIME(1228480170)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-//@todo: fix the stuff with all the uppercase variable and function names...wazzup?
-
-/**
- * This library needs to be refactored.
- * @constructor
- * @private
- */
-jpf.scrollbar = function(){
- var SCROLLVALUE = 0;
- var STEPVALUE = 0.03;
- var BIGSTEPVALUE = 0.1;
- var CURVALUE = 0;
- var TIMER = null;
- var SCROLLWAIT;
- var SLIDEMAXHEIGHT;
- var _self = this;
-
- var offsetName = jpf.isIE ? "offset" : "layer";
-
- //Init Class
- var uniqueId = this.uniqueId = jpf.all.push(this) - 1;
- jpf.makeClass(this);
-
- //Init Skin
- this.realtime = true;
- this.$supportedProperties = [];
- this.$propHandlers = {};
- this.inherit(jpf.Presentation); /** @inherits jpf.Presentation */
- if (this.$loadSkin)
- this.$loadSkin("default:scrollbar");
-
- //Init DragDrop mode
- jpf.dragmode.defineMode("scrollbar" + this.uniqueId, this);
-
- //Build Skin
- this.$getNewContext("main");
- this.oExt = jpf.xmldb.htmlImport(this.$getLayoutNode("main"), document.body);
- this.oExt.host = this;
- this.oExt.style.display = "none";
-
- var MAIN = this.oExt;
- var INDICATOR = this.$getLayoutNode("main", "indicator", this.oExt);
- var SLIDEFAST = this.$getLayoutNode("main", "slidefast", this.oExt);
- var BTNUP = BTN = this.$getLayoutNode("main", "btnup", this.oExt)
- var BTNDOWN = this.$getLayoutNode("main", "btndown", this.oExt);
- var STARTPOS = false;
-
- INDICATOR.ondragstart = function(){
- return false
- };
-
- //document.getElementById('btnup').ondblclick =
- BTNUP.onmousedown = function(e){
- if (!e)
- e = event;
- this.className = "btnup btnupdown";
- clearTimeout(TIMER);
-
- CURVALUE -= STEPVALUE;
- setScroll();
- e.cancelBubble = true;
-
- TIMER = setTimeout(function(){
- TIMER = setInterval(function(){
- CURVALUE -= STEPVALUE;
- jpf.lookup(uniqueId).setScroll();
- }, 20);
- }, 300);
- };
-
- //document.getElementById('btndown').ondblclick =
- BTNDOWN.onmousedown = function(e){
- if (!e)
- e = event;
- this.className = "btndown btndowndown";
- clearTimeout(TIMER);
-
- CURVALUE += STEPVALUE;
- setScroll();
- e.cancelBubble = true;
-
- TIMER = setTimeout(function(){
- TIMER = setInterval(function(){
- CURVALUE += STEPVALUE;
- jpf.lookup(uniqueId).setScroll();
- }, 20);
- }, 300);
- };
-
- BTNUP.onmouseout = BTNUP.onmouseup = function(){
- this.className = "btnup";
- clearInterval(TIMER);
- };
-
- BTNDOWN.onmouseout = BTNDOWN.onmouseup = function(){
- this.className = "btndown";
- clearInterval(TIMER);
- };
-
- INDICATOR.onmousedown = function(e){
- if (!e)
- e = event;
- STARTPOS = [e[offsetName + "X"], e[offsetName + "Y"] + BTN.offsetHeight];
-
- jpf.dragmode.setMode("scrollbar" + _self.uniqueId);
-
- e.cancelBubble = true;
- return false;
- };
-
- MAIN.onmousedown = function(e){
- if (!e)
- e = event;
- clearInterval(TIMER);
- var offset;
-
- if (e[offsetName + "Y"] > INDICATOR.offsetTop + INDICATOR.offsetHeight) {
- CURVALUE += BIGSTEPVALUE;
- setScroll(true);
-
- SLIDEFAST.style.display = "block";
- SLIDEFAST.style.top = (INDICATOR.offsetTop
- + INDICATOR.offsetHeight) + "px";
- SLIDEFAST.style.height = (MAIN.offsetHeight - SLIDEFAST.offsetTop
- - BTN.offsetHeight) + "px";
-
- offset = e[offsetName + "Y"];
- TIMER = setTimeout(function(){
- TIMER = setInterval(function(){
- jpf.lookup(uniqueId).scrollDown(offset);
- }, 20);
- }, 300);
- }
- else
- if (e[offsetName + "Y"] < INDICATOR.offsetTop) {
- CURVALUE -= BIGSTEPVALUE;
- setScroll(true);
-
- SLIDEFAST.style.display = "block";
- SLIDEFAST.style.top = BTN.offsetHeight + "px";
- SLIDEFAST.style.height = (INDICATOR.offsetTop - BTN.offsetHeight) + "px";
-
- offset = e[offsetName + "Y"];
- TIMER = setTimeout(function(){
- TIMER = setInterval(function(){
- jpf.lookup(uniqueId).scrollUp(offset);
- }, 20);
- }, 300);
- }
- };
-
- MAIN.onmouseup = function(){
- clearInterval(TIMER);
- if (!_self.realtime)
- setScroll();
- SLIDEFAST.style.display = "none";
- };
-
- this.onmousemove = function(e){
- if (!e)
- e = event;
- //if(e.button != 1) return this.onmouseup();
- if (!STARTPOS)
- return false;
-
- var next = BTN.offsetHeight + (e.clientY - STARTPOS[1]
- - jpf.getAbsolutePosition(MAIN)[1] - BTN.offsetHeight / 3);
- var min = BTN.offsetHeight;
- if (next < min)
- next = min;
- var max = (MAIN.offsetHeight - (BTN.offsetHeight) - INDICATOR.offsetHeight);
- if (next > max)
- next = max;
- //INDICATOR.style.top = next + "px"
-
- CURVALUE = (next - min) / (max - min);
- setTimeout(function(){
- setScroll(true);
- });
- };
-
- this.onmouseup = function(){
- STARTPOS = false;
- if (!_self.realtime)
- setScroll();
- jpf.dragmode.clear();
- };
-
- var LIST, viewheight, scrollheight;
-
- function onscroll(timed, perc){
- LIST.scrollTop = (LIST.scrollHeight - LIST.offsetHeight + 4) * CURVALUE;
- /*var now = new Date().getTime();
- if (timed && now - LIST.last < (timed ? SCROLLWAIT : 0)) return;
- LIST.last = now;
- var value = parseInt((DATA.length - LIST.len + 1) * CURVALUE);
- showData(value);*/
- }
-
- this.attach = function(oHtml, o, scroll_func){
- LIST = o;
- onscroll = scroll_func;
- viewheight = oHtml.offsetHeight;
- scrollheight = viewheight;
-
- oHtml.parentNode.appendChild(this.oExt);
- this.oExt.style.display = "block";
- this.oExt.style.zIndex = 100000;
- //this.oExt.style.left = "166px";//(o.offsetLeft + o.offsetWidth) + "px";
- this.oExt.style.top = "24px";//o.offsetTop + "px";
- this.oExt.style.height = "160px";//o.offsetHeight + "px";
-
- function wheel(e){
- if (!e)
- e = event;
-
- var delta = null;
- if (e.wheelDelta) {
- delta = e.wheelDelta / 120;
- if (jpf.isOpera)
- delta *= -1;
- }
- else if (e.detail)
- delta = -e.detail / 3;
-
- if (delta !== null) {
- var ev = {delta: delta};
- var res = jpf.dispatchEvent("mousescroll", ev);
- if (res === false || ev.returnValue === false) {
- if (e.preventDefault)
- e.preventDefault();
-
- e.returnValue = false;
- }
- }
-
-
- STEPVALUE = (o.limit / o.length) / 5;
- CURVALUE += ((jpf.isOpera ? 1 : -1) * delta * STEPVALUE);
- setScroll(true);
- }
-
- if (document.addEventListener)
- document.addEventListener('DOMMouseScroll', wheel, false);
- else
- oHtml.onmousewheel = wheel;
-
- SCROLLWAIT = 0;//(LIST.len * COLS)/2;
- SLIDEMAXHEIGHT = MAIN.offsetHeight - BTNDOWN.offsetHeight - BTNUP.offsetHeight;
- STEPVALUE = (viewheight / scrollheight) / 20;
- BIGSTEPVALUE = STEPVALUE * 3;
-
- //viewheight / scrollheight
- if (o.length) {
- INDICATOR.style.height = Math.max(5, ((o.limit / o.length)
- * SLIDEMAXHEIGHT)) + "px";
- if (INDICATOR.offsetHeight - 4 == SLIDEMAXHEIGHT)
- MAIN.style.display = "none";
- }
-
- return this;
- };
-
- var jmlNode = this;
- function setScroll(timed, noEvent){
- if (CURVALUE > 1)
- CURVALUE = 1;
- if (CURVALUE < 0)
- CURVALUE = 0;
- INDICATOR.style.top = (BTN.offsetHeight + (MAIN.offsetHeight
- - (BTN.offsetHeight * 2) - INDICATOR.offsetHeight) * CURVALUE) + "px";
-
- //status = CURVALUE;
- jmlNode.pos = CURVALUE;//(INDICATOR.offsetTop-BTNUP.offsetHeight)/(SLIDEMAXHEIGHT-INDICATOR.offsetHeight);
- if (!noEvent)
- onscroll(timed, jmlNode.pos);
- }
-
- this.setScroll = setScroll;
-
- function scrollUp(v){
- if (v > INDICATOR.offsetTop)
- return MAIN.onmouseup();
- CURVALUE -= BIGSTEPVALUE;
- setScroll();
-
- SLIDEFAST.style.height = Math.max(1, INDICATOR.offsetTop
- - BTN.offsetHeight) + "px";
- SLIDEFAST.style.top = BTN.offsetHeight + "px";
- }
-
- this.scrollUp = scrollUp;
-
- function scrollDown(v){
- if (v < INDICATOR.offsetTop + INDICATOR.offsetHeight)
- return MAIN.onmouseup();
- CURVALUE += BIGSTEPVALUE;
- setScroll();
-
- SLIDEFAST.style.top = (INDICATOR.offsetTop + INDICATOR.offsetHeight) + "px";
- SLIDEFAST.style.height = Math.max(1, MAIN.offsetHeight - SLIDEFAST.offsetTop
- - BTN.offsetHeight) + "px";
- }
-
- this.scrollDown = scrollDown;
-
- this.getPosition = function(){
- return this.pos;
- };
-
- this.setPosition = function(pos, noEvent){
- CURVALUE = pos;
- setScroll(null, noEvent);
- };
-
- this.update = function(){
- var o = LIST;
- if (o.length) {
- SLIDEMAXHEIGHT = MAIN.offsetHeight - BTNDOWN.offsetHeight - BTNUP.offsetHeight;
- INDICATOR.style.height = Math.max(5, ((o.limit / o.length) * 2
- * SLIDEMAXHEIGHT)) + "px";
- if (INDICATOR.offsetHeight - 4 == SLIDEMAXHEIGHT)
- MAIN.style.display = "none";
-
- STEPVALUE = (o.limit / o.length) / 20;
- BIGSTEPVALUE = STEPVALUE * 3;
- }
-
- this.oExt.style.top = "-2px";
- this.oExt.style.right = 0;
-
- if (this.oExt.parentNode.offsetHeight)
- this.oExt.style.height = (this.oExt.parentNode.offsetHeight - 20) + "px";
- else
- this.oExt.style.height = "100%"
- }
-};
-
- - -/*FILEHEAD(/var/lib/jpf/src/core/lib/draw_canvas.js)SIZE(-1077090856)TIME(1238933677)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - -/*FILEHEAD(/var/lib/jpf/src/core/lib/history.js)SIZE(-1077090856)TIME(1238944816)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -/** - * Implementation of hash change listener. The 'hash' is the part of the - * location string in your browser that takes care of pointing to a section - * within the current application. - * Example: - * <code> - * http://www.example.com/index.php#products - * </code> - * Remarks: - * In future browsers (2008) the location hash can be set by script and the - * {@link element.history.event.hashchange} event is called when it's changed by using the back or forward - * button of the browsers. In the current (2008) browsers this is not the case. - * This object handles that logic for those browsers in such a way that the user - * of the application can use the back and forward buttons in an intuitive manner. - * - * @event hashchange Fires when the hash changes. This can be either by setting - * a new hash value or when a user uses the back or forward button. Typing a - * new hash value in the location bar will also trigger this function. - * Example: - * <code> - * jpf.addEventListener("hashchange", function(e){ - * var info = e.page.split(":"); - * - * switch(info[0]) { - * case "product": //hash is for instance 'product:23849' - * //Sets the state to displaying product information see {@link element.state} - * stProduct.activate(); - * //Loads a product by id - * loadProduct(info[1]); - * break; - * case "news": - * stNews.activate(); - * break; - * } - * }); - * </code> - * - * @default_private - */ -jpf.history = { - inited: false, - page : null, - - init : function(name){ - this.inited = true; - this.hasChanged(name); - - if (jpf.isIE) { - var str = - "<style>\ - BODY, HTML{margin : 0;}\ - h1{height : 100px;margin : 0;padding : 0;}\ - </style>\ - <body>\ - <h1 id='" + name + "'>0</h1>\ - </body>\ - <script>\ - var lastURL = -1;\ - if(document.all){\ - document.body.onscroll = checkUrl;\ - }else{\ - setInterval('checkUrl()', 200);\ - }\ - function checkUrl(){\ - var nr=Math.round((document.all ? document.body : document.documentElement).scrollTop/100);\ - top.jpf.history.hasChanged(document.getElementsByTagName('h1')[nr].id);\ - lastURL = document.body.scrollTop;\ - }\ - checkUrl();\ - </script>"; - - if (top == self) { - document.body.insertAdjacentHTML("beforeend", - "<iframe name='nav' style2='position:absolute;left:10px;top:10px;height:100px;width:100px;z-index:1000'\ - style='width:1px;height:1px;' src='about:blank'></iframe>"); - document.frames["nav"].document.open(); - document.frames["nav"].document.write(str); - document.frames["nav"].document.close(); - } - - this.iframe = document.frames["nav"];// : document.getElementById("nav").contentWindow; - //Check to see if url has been manually changed - this.timer2 = setInterval(function(){ - //status = jpf.history.changingHash; - if (!jpf.history.changingHash && location.hash != "#" + jpf.history.page) { - jpf.history.hasChanged(location.hash.replace(/^#/, "")); - } - }, jpf.history.delay || 200); - } - else { - jpf.history.lastUrl = location.href; - this.timer2 = setInterval(function(){ - if (jpf.history.lastUrl == location.href) - return; - - jpf.history.lastUrl = location.href; - //var page = location.href.replace(/^.*#(.*)$/, "$1") - var page = location.hash.replace("#", "");//.replace(/^.*#(.*)$/,"$1"); - jpf.history.hasChanged(decodeURI(page)); - }, 20); - } - }, - - /** - * Sets the hash value of the location bar in the browser. This is used - * to represent the state of the application for use by the back and forward - * buttons as well as for use when bookmarking or sharing url's. - * @param {String} name the new hash value. - * @param {Boolean} timed whether to add a delay to setting the value. - */ - to_name : null, - setHash : function(name, timed){ - if (this.changing || this.page == name || location.hash == "#" + name) { - this.to_name = name; - return; - } - - if (jpf.isIE && !timed) { - this.to_name = name; - return setTimeout(function(){jpf.history.setHash(jpf.history.to_name, true);}, 200); - } - - this.changePage(name); - if (!this.inited) - return this.init(name); - - this.changePage(name); - if (!this.inited) - return this.init(name); - - if (jpf.isIE) { - var h = this.iframe.document.body - .appendChild(this.iframe.document.createElement('h1')); - h.id = name; - h.innerHTML = this.length; - }; - - (jpf.isIE ? this.iframe : window).location.href = "#" + name; - - if (!jpf.isIE) - jpf.history.lastUrl = location.href; - }, - - timer : null, - changePage: function(page){ - if (jpf.isIE) { - this.page = page; - this.changingHash = true; - clearTimeout(this.timer); - this.timer = setTimeout(function(){ - location.hash = page; - jpf.history.changingHash = false; - }, 1); - } - }, - - hasChanged: function(page){ - if (page == this.page) return; - this.changePage(page); - - this.changing = true; - jpf.dispatchEvent("hashchange", {page: page}); - this.changing = false; - } -}; - - - -/*FILEHEAD(/var/lib/jpf/src/core/lib/offline.js)SIZE(-1077090856)TIME(1238965806)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * @define offline
- * Adds offline support for jml applications. It can store and restore the state
- * of the application, the models, any transaction that occurred whilst being
- * offline, queuing actions (ActionTracker state) and state of the runtime
- * application itself (all properties of each element). This allows the
- * application to return to the exact state the user left it, when needed. This
- * means that when enabled you can at any moment turn of your computer (i.e.
- * remove the battery) and when your computer starts up whilst sitting in the
- * train start the application and continue working as if the application
- * was never closed.
- * Example:
- * <code>
- * <j:appsettings>
- * <j:offline providers="gears"
- * resources = "application|models|transactions|queue|state"
- * rsb-timeout = "10000"
- * detect-url = "network.txt"
- * detection = "auto"
- * realtime = "true"
- * onrestore = "return confirm('Continue your previous session?');"
- * onlosechanges = "" />
- * </j:appsettings>
- * </code>
- *
- * @event losechanges Fires before the offline state is removed.
- * cancellable: Prevents the application from losing it's recorded offline state.
- * @event beforeoffline Fires before bringing the application offline.
- * cancellable: Prevents the application from going offline
- * @event afteroffline Firest after the application is brought offline.
- * @event beforeonline Fires before bringing the application online.
- * cancellable: Prevents the application from going online
- * @event afteronline Fires after the application is brought online.
- * @event beforeload Fires before loading the offline state into this application.
- * cancellable: Prevents the application from reloading it's offline state.
- * @event sync Fires at each sync item's completion.
- * object:
- * {Number} position
- * {Number} length
- *
- * @attribute {Number} progress the progress of the sync. A number between 0 and 1.
- * Example:
- * <code>
- * <j:modalwindow title="Synchronizing" visible="{offline.syncing}">
- * <j:Label>Synchronizing your changes</j:label>
- * <j:progressbar value="{offline.progress}" />
- * <j:button onclick="jpf.offline.stopSync()">Cancel</j:button>
- * <j:button onclick="this.parentNode.hide()">Hide Window</j:button>
- * </j:modalwindow>
- * </code>
- * @attribute {Number} position the progress of the sync.
- * @attribute {Number} length the total length of items to sync.
- * @attribute {Boolean} syncing wether the application is syncing while coming online.
- * @attribute {Boolean} onLine wether the application is online. This property is false during sync.
- * @attribute {String} resources the resources that should be
- * kept offline and synced later. This is a pipe '|' seperated list.
- * Possible values:
- * application deals with making the actual application offline avaible.
- * models takes care of having the data of the models offline available.
- * transactions records the state of the actiontrackers so that these are available offline.
- * queue handles queuing of actions that can only be executed whilst online.
- * state records the state of all elements in this application on a property level.
- *
- * @default_private
- */
-jpf.namespace("offline", {
- /**
- * {Boolean} whether offline support is enabled.
- */
- enabled : false,
-
- /**
- * {Boolean} whether the application is online.
- */
- onLine : -1,
- resources : ["application", "models", "transactions", "queue", "state"],
- autoInstall : false,
- storage : null,
- inited : false,
- rsbTimeout : 600000,//After 10 minutes, we assume the RSB messaged will be destroyed
-
- init : function(jml){
- jpf.makeClass(this);
-
- //Read configuration
- if (jml) {
- this.$jml = jml;
-
- if (typeof jml == "string") {
-
- }
- else if (jml.nodeType) {
- if (jml.getAttribute("resources"))
- this.providers = jml.getAttribute("resources").split("|");
-
- /**
- * @attribute {Number} rsb-timeout the number of milliseconds
- * after the remote smartbindings server considers a client
- * offline and destroys all saved offline messages.
- */
- if (jml.getAttribute("rsb-timeout"))
- this.rsbTimeout = parseInt(jml.getAttribute("rsb-timeout"));
-
- //Events
- var a, i, attr = jml.attributes;
- for (i = 0; i < attr.length; i++) {
- a = attr[i];
- if (a.nodeName.indexOf("on") == 0)
- this.addEventListener(a.nodeName, new Function(a.nodeValue));
- }
- }
- else {
- jpf.extend(this, jml);
- }
- }
-
- var provider = jpf.offline.application.init(jml)
-
- //Check for storage provider
- if (provider) {
- this.storage = jpf.storage.getProvider(provider);
-
- if (this.storage)
- jpf.console.info("Installed storage provider '" + provider + "'");
- }
-
- if (!this.storage) {
- this.storage = jpf.storage.initialized
- ? jpf.storage
- : jpf.storage.init(); //autodetect
- }
-
- if (!this.storage) {
- throw new Error("Offline failed to attain access \
- to a storage provider");
-
- return;
- }
-
- if (!this.storage.isPermanent()) {
- jpf.addEventListener("exit", function(){
- return jpf.offline.dispatchEvent("losechanges");
- });
- }
-
- if (this.storage.asyncInit) {
- jpf.JmlParser.shouldWait = true;
- this.storage.ready(function(){
- jpf.offline.storage.onready = null; //Prevent being called twice
- jpf.offline.continueInit();
- jpf.JmlParser.continueStartup();
- });
-
- return;
- }
-
- this.continueInit();
- },
-
- continueInit : function(){
- // Check if all specified resources are available
- for (i = this.resources.length - 1; i >= 0; i--) {
- if (!this[this.resources[i]])
- this.resources.removeIndex(i);
- else
- this[this.resources[i]].init(this.$jml);
- }
-
- this.enabled = true;
-
- this.detector.init(this.$jml);
-
- this.offlineTime = parseInt(this.storage.get("offlinetime", this.namespace));
-
- //If we were offline lets stay offline
- if (this.offlineTime)
- this.goOffline();
- else //Else we try to go online
- this.goOnline();
-
- jpf.offline.dispatchEvent("load");
- },
-
- $destroy : function(){
- jpf.console.info("Cleaning offline");
-
- if (this.provider && this.provider.destroy)
- this.provider.destroy();
-
- if (this.storage && this.storage.destroy)
- this.storage.destroy();
-
- for (i = this.resources.length - 1; i >= 0; i--) {
- if (this[this.resources[i]].destroy)
- this[this.resources[i]].destroy();
- }
- },
-
- IDLE : 0, //idle
- TO_OFFLINE : 1, //going offline
- TO_ONLINE : 2, //going online
- STOPPING : 3, //stopping going online
-
- /**
- * Indicates what's happening right now
- */
- inProcess : 0,
-
- $supportedProperties : ["syncing", "position", "length", "progress", "onLine"],
- handlePropSet : function(prop, value, force){
- this[prop] = value;
- //All read-only properties
- },
-
- /**
- * Brings the application offline.
- */
- goOffline : function(){
- if (!this.enabled || this.onLine === false
- || this.inProcess == this.TO_OFFLINE)
- return false;
-
- //We can't go offline yet, we'll terminate current process and wait
- if (this.inProcess) {
- this.inProcess = this.STOPPING;
- return false;
- }
-
- if (this.dispatchEvent("beforeoffline") === false)
- return false;
-
- //We're offline, let's dim the light
- this.setProperty("onLine", false);
- this.inProcess = this.TO_OFFLINE;
-
- if (!this.offlineTime) {
- this.offlineTime = new Date().getTime();
- this.storage.put("offlinetime", this.offlineTime, this.namespace);
- }
-
- //if (jpf.auth.retry) //Don't want to ruin the chances of having a smooth ride on a bad connection
- // jpf.auth.loggedIn = false; //we're logged out now, we'll auto-login when going online
-
- //Turn off detection if needed
- if (this.detector.enabled && this.detector.detection != "manual")
- this.detector.start();
-
- if (!this.initial) {
- this.initial = {
- disableRSB : jpf.xmldb.disableRSB //@todo record this in storage
- }
- }
- jpf.xmldb.disableRSB = true;
-
- this.inProcess = this.IDLE;
-
- this.dispatchEvent("afteroffline");
-
- jpf.console.info("The application is now working offline.")
-
- return true;//success
- },
-
- /**
- * Brings the application online.
- */
- goOnline : function(){
- if (!this.enabled || this.onLine === true
- || this.inProcess == this.TO_ONLINE)
- return false;
-
- if (this.dispatchEvent("beforeonline") === false)
- return false;
-
- //We're online, let's show the beacon
- this.setProperty("onLine", true); //@todo Think about doing this in the callback, because of processes that will now intersect
- this.inProcess = this.TO_ONLINE;
- this.onlineTime = new Date().getTime();
- this.reloading = false;
-
- jpf.console.info("Trying to go online.")
-
- //Turn off detection if needed
- if (this.detector.enabled && this.detector.detection == "error")
- this.detector.stop();
-
- //Check if we have to reload all models
- this.$checkRsbTimeout();
-
- //Reset RSB in original state
- if (this.initial)
- jpf.xmldb.disableRSB = this.initial.disableRSB;
-
- var callback = function(){
- /*
- @todo syncing should probably be patched to take a random
- time before starting to prevent blasting a server during a
- glitch, of course decent loadbalancing would solve this as well.
- */
- this.startSync();
-
- this.dispatchEvent("afteronline");
- }
-
- //First let's log in to the services that need it before syncing changes
- if (jpf.auth.needsLogin && jpf.auth.loggedIn) { // && !jpf.auth.loggedIn
- jpf.auth.authRequired({
- object : this,
- retry : callback
- });
- }
- else
- {
- callback.call(this);
- }
-
- return true;//success
- },
-
- /**
- * If we've been offline for a long time,
- * let's clear the models, we can't trust the data anymore
- */
- $checkRsbTimeout : function(){
- if (!this.rsbTimeout)
- return;
-
- var i, j, rsbs = jpf.nameserver.getAll("remote");
- for (i = 0; i < rsbs.length; i++) {
- var rsb = rsbs[i];
- if (this.reloading
- || this.onlineTime - this.offlineTime > this.rsbTimeout) {
- if (!this.reloading) {
- if (this.dispatchEvent("beforereload") === false) {
- jpf.console.warn("Warning, potential data corruption\
- because you've cancelled reloading the data of all \
- remote smartbinding synchronized models.");
-
- break;
- }
-
- this.reloading = true;
- }
-
- rsb.discardBefore = this.onlineTime;
-
- for (j = 0; k < rsb.models.length; j++) {
- rsb.models[j].clear();
-
- jpf.offline.models.addToInitQueue(rsb.models[j])
- }
- }
- }
-
- if (this.reloading) {
- jpf.console.warn("The application has been offline longer than the \
- server timeout. To maintain consistency the models\
- are reloaded. All undo stacks will be purged.");
-
- jpf.offline.transactions.clear("undo|redo");
-
- var ats = jpf.nameserver.getAll("actiontracker");
- for (var i = 0; i < ats.length; i++) {
- ats[i].reset();
- }
- }
- },
-
- $goOnlineDone : function(success){
- //this.reloading = true;
- this.inProcess = this.IDLE; //We're done
- this.setProperty("syncing", false);
-
- if (success) {
- this.offlineTime = null;
- this.initial = null;
- this.storage.remove("offlinetime", this.namespace);
-
- jpf.console.info("Syncing done.")
- jpf.console.info("The application is now working online.")
- }
- else {
- jpf.console.info("Syncing was cancelled. Going online failed")
-
- //Going online has failed. Going offline again
- this.goOffline();
- }
- },
-
- /**
- * Clears all offline data.
- */
- clear : function(){
- if (!this.enabled)
- return false;
-
- jpf.console.info("Clearing all offline and state cache");
-
- for (i = this.resources.length - 1; i >= 0; i--) {
- if (this[this.resources[i]].clear)
- this[this.resources[i]].clear();
- }
- },
-
- /**
- * Does cleanup after we've come online
- * @private
- */
- startSync : function(){
- if (this.syncing)
- return;
-
- this.setProperty("syncing", true);
-
- jpf.console.info("Start syncing offline changes.")
-
- var syncResources = [],
- syncLength = 0,
- syncPos = 0,
- syncRes = null,
- len, i;
-
- //Start finding all resources to sync
- for (i = this.resources.length - 1; i >= 0; i--) {
- if (this[this.resources[i]].sync) {
- len = this[this.resources[i]].getSyncLength();
-
- if (len) {
- syncResources.push(this[this.resources[i]]);
- syncLength += len;
- }
- }
- }
-
- var fln = jpf.offline;
- var callback = function(extra){
- if (fln.inProcess == fln.STOPPING) {
- if (!extra.finished && extra.length - 1 != extra.position) {
- syncRes.stopSync(function(){ //@todo if(syncRes) ??
- fln.$goOnlineDone(false);
- });
- }
- else {
- fln.$goOnlineDone(false);
- }
-
- return;
- }
-
- if (extra.finished) {
- if (syncResources.length) {
- syncRes = syncResources.pop();
- syncRes.sync(callback);
- }
- else {
- //@todo check if we need to sync more..
-
- fln.$goOnlineDone(true);
- }
-
- return;
- }
-
- if (!extra.start)
- syncPos++;
-
- fln.setProperty("progress", parseInt(syncPos/syncLength*100));
- fln.setProperty("position", syncPos);
- fln.setProperty("length", syncLength);
-
- fln.dispatchEvent("sync", jpf.extend(extra, {
- position : syncPos,
- length : syncLength
- }));
- }
-
- if (syncLength) {
- callback({start : true});
- callback({finished : true});
- }
- else {
- jpf.console.info("Nothing to synchronize.")
-
- this.$goOnlineDone(true);
- }
-
- /*
- When going online check loadedWhenOffline of
- the multiselect widgets and reload() them
- */
- var nodes = jpf.all; //@todo maintaining a list is more efficient, is it necesary??
- for (i = 0; i < nodes.length; i++) {
- if (nodes[i].loadedWhenOffline)
- nodes[i].reload();
- }
- },
-
- stopSync : function(){
- debugger;
- if (this.syncing)
- this.inProcess = this.STOPPING;
- }
-});
- - -/*FILEHEAD(/var/lib/jpf/src/core/lib/draw.js)SIZE(-1077090856)TIME(1238933677)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - -jpf.draw = { - - initDriver : function(){ - // initialize by copying either canvas of VML into my object. - if(!this.initLayer){ - var k,o=jpf.supportVML?jpf.draw.vml:jpf.draw.canvas; - for(k in o){ - this[k]=o[k]; - } - } - }, - - //---------------------------------------------------------------------- - - // vars - - //---------------------------------------------------------------------- - - vars : function(ml,mt,mr,mb){ - return ["var _math_,vx1 = v.vx1, vy1 = v.vy1,_rseed=1", - ",vx2 = v.vx2, vy2 = v.vy2, vw = vx2-vx1, vh = vy1-vy2", - ",vz2 = v.vz2, vz1 = v.vz1, vd = vz2-vz1", - ",zoom = 1/v.zoom", - ",dw = l.dw",ml?"-"+(ml+mr):"", - ",dh = l.dh",mt?"-"+(mt+mb):"", - ",dw12 = dw*0.5, dh12 = dh*0.5", - ",dx = ",ml?ml:0, - ",dy = ",mt?mt:0, - ",mx = m&&m.x, my = m&&m.y", - ",db = dy+dh, dr = dx+dw", - ",tw = dw/vw, th = dh/vh, ty = -vy2*th+dy, tx = -vx1*tw+dx", - ",v,t=0,n=(new Date()).getTime()*0.001, dt=-(l._n?l._n:n)+(l._n=n), z = 1/l.zoom", - ",e=Math.E, p=Math.PI, p2=2*p, p12=0.5*p", - ",x, y, z, _x,_y,_z, zt, i, j, k, _opt_;"].join(''); - }, - defCamVec : function(){ - // lets do a proper 3x3 inverse and mul it with our camera pos - return "var inv=1/m00*(m11*m22-m12*m21)-m01*(m10*m22-m12*m20)+m02*(m10*m21-m11*m20);"+ - "var mcx = inv*(m11*m22-m12*m21)*m03 + inv*(m02*m21-m01*m22)*m13 + inv*(m01*m12-m02*m11)*m23,"+ - " mcy = inv*(m12*m20-m10*m22)*m03 + inv*(m00*m22-m02*m20)*m13 + inv*(m02*m10-m00*m12)*m23,"+ - " mcz = inv*(m10*m21-m11*m20)*m03 + inv*(m01*m20-m00*m21)*m13 + inv*(m00*m11-m01*m10)*m23;" - // " mcz m10*m13+m20*m23,mcy=m01*m03+m11*m13+m21*m23,mcz=m02*m03+m12*m13+m22*m23;"; - }, - setMatrix3D : function(m){ - var l = this.l; - var s = ["var m00=",m[0],",m01=",m[1],",m02=",m[2], ",m03=",m[3], - ",m10=",m[4],",m11=",m[5],",m12=",m[6], ",m13=",m[7], - ",m20=",m[8],",m21=",m[9],",m22=",m[10],",m23=",m[11],";"]; - if(l.style.persp<0){ // we have ortho perspective - this.ortho = 1; - s.push("var persp = __max(dw,dh) / l.style.persp/-v.tz;"); - } else { - this.ortho = 0; - s.push("var persp = __max(dw,dh) / l.style.persp;"); - } - return s.join(''); - }, - - sincos3 : function(pre,rx,ry,rz){ - return[ "var ",pre,"cx = __cos(",rx,"),",pre,"sx = __sin(",rx,"),", - pre,"cy = __cos(",ry,"),",pre,"sy = __sin(",ry,"),", - pre,"cz = __cos(",rz,"),",pre,"sz = __sin(",rz,");" ].join(''); - }, - matrix4S : function(sx,sy,sz){ - return [ sx,0,0,0, - 0,sy,0,0, - 0,0,sz,0, - 0,0,0,1 ]; - }, - matrix4T : function(tx,ty,tz){ - return [ 1,0,0,tx, - 0,1,0,ty, - 0,0,1,tz, - 0,0,0,1 ]; - }, - matrix4RP : function(pre){ - return this.matrix4R(pre+'cx',pre+'sx',pre+'cy',pre+'sy',pre+'cz',pre+'sz'); - }, - matrix4R : function(cx,sx,cy,sy,cz,sz){ - return [ [cy,'*',cz].join(''), - ['(-',sz,'*',cy,')'].join(''), - sy, - 0, - ['(',cz,'*',sx,'*',sy,'+',sz,'*',cx,')'].join(''), - ['(-',sx,'*',sy,'*',sz,'+',cx,'*',cz,')'].join(''), - ['(-',sx,'*',cy,')'].join(''), - 0, - ['(-',cx,'*',sy,'*',cz,'+',sx,'*',sz,')'].join(''), - ['(',cx,'*',sy,'*',sz,'+',cz,'*',sx,')'].join(''), - ['(',cx,'*',cy,')'].join(''), - 0, - 0,0,0,1]; - }, - matrixMul : function(){ - // lets multiply matrices on our arglist with conceptually ordered transform - var m = arguments[arguments.length-1]; - for(var i = arguments.length-2;i>=0;i--) - m = this.matrixAB(m,arguments[i]); - return m; - }, - matrixAB : function(a,b){ - var out = [], x, y, i, j, t, v; - for(y = 0;y<16;y+=4){ - for(x = 0;x<4;x++){ - v = []; - if((i=a[y]) &&(j=b[x]) ) v[v.length] = i==1?j:(j==1?i:(i+'*'+j)); - if((i=a[y+1])&&(j=b[x+4]) ) v[v.length] = i==1?j:(j==1?i:(i+'*'+j)); - if((i=a[y+2])&&(j=b[x+8]) ) v[v.length] = i==1?j:(j==1?i:(i+'*'+j)); - if((i=a[y+3])&&(j=b[x+12])) v[v.length] = i==1?j:(j==1?i:(i+'*'+j)); - out[out.length] = v.length?((v.length>1)?'('+v.join('+')+')':v[0]):0; - } - } - return out; - }, - - // check for backface for a certain plane - backface3D : function(pts,cm,zmode){ - var a = pts[0], b = pts[1], c = pts[2], x = 0, y = 1, z = 2; - if(cm) x = cm[0], y = cm[1], z = cm[2]; - return this.ortho?[ - "-((m00*",b[x],"+m01*",b[y],"+m02*",b[z],"+m03)-(__ax=m00*",a[x],"+m01*",a[y],"+m02*",a[z],"+m03))*", - "((m10*",c[x],"+m11*",c[y],"+m12*",c[z],"+m13)-(__ay=m10*",a[x],"+m11*",a[y],"+m12*",a[z],"+m13))+", - "((m10*",b[x],"+m11*",b[y],"+m12*",b[z],"+m13)-__ay)*((m00*",c[x],"+m01*",c[y],"+m02*",c[z],"+m03)-__ax)"].join(''): - [ - "(((__by=m10*",b[x],"+m11*",b[y],"+m12*",b[z],"+m13) - (__ay=m10*",a[x],"+m11*",a[y],"+m12*",a[z],"+m13)) *", - "((__cz=m20*",c[x],"+m21*",c[y],"+m22*",c[z],"+m23) - (__az=m20*",a[x],"+m21*",a[y],"+m22*",a[z],"+m23)) -", - "((__bz=m20*",b[x],"+m21*",b[y],"+m22*",b[z],"+m23) - __az) * ((__cy=m10*",c[x],"+m11*",c[y],"+m12*",c[z],"+m13) - __ay) ) * ", - "(__ax=m00*",a[x],"+m01*",a[y],"+m02*",a[z],"+m03) + ", - "((__bz - __az) * ((__cx=m00*",c[x],"+m01*",c[y],"+m02*",c[z],"+m03) - __ax) -", - "((__bx=m00*",b[x],"+m01*",b[y],"+m02*",b[z],"+m03) - __ax) * (__cz - __az) ) * __ay + ", - "((__bx - __ax) * (__cy - __ay) - (__by - __ay) * (__cx - __ax) ) * __az "].join(''); - }, - - //---------------------------------------------------------------------- - - // 3D API - // draw a 3D polygon clipped against a z-plane - poly3DClip : function(idx,pt,cm,zc,open){ - var i = 0, d, pt, q, s = ["__n=0;"], x = 0, y = 1, z = 2, sx, sy, vx, vy, vxi, vyi; - if(cm) x = cm[0], y = cm[1], z = cm[2]; - - //calculate z-clipping info for each vertex - for(var i = 0;i<idx.length;i++){ - p = pt[idx[i]]; - s.push(["if(__n",i,"=(__z",i," = m20*",p[x],"+m21*",p[y],"+m22*",p[z],"+m23) < ",zc,")__n++;"].join('')) - } - s.push("if(__n){", - "if(__n==",idx.length,"){"); - // the nonclipped draw - for(var i = 0;i<idx.length;i++){ - p = pt[idx[i]]; - vx = ["dw12+(m00*",p[x],"+m01*",p[y],"+m02*",p[z],"+m03)*",this.ortho?"persp":"(persp/__z"+i+")"].join(''); - vy = ["dh12+(m10*",p[x],"+m11*",p[y],"+m12*",p[z],"+m13)*",this.ortho?"persp":"(persp/__z"+i+")"].join(''); - if(i==0)s.push(this.moveTo(vx,vy)); - else s.push(this.lineTo(vx,vy)); - } - if(!open)s.push(this.close()); - s.push("}else{"); - - // the clipped draw - for(var i = 0;i<idx.length;i++){ - p = pt[idx[i]]; - // if we are number index 0 we only move to - if(i==0){ // first vertex - s.push([ - "__x0=m00*",p[x],"+m01*",p[y],"+m02*",p[z],"+m03;", - "__y0=m10*",p[x],"+m11*",p[y],"+m12*",p[z],"+m13;", - "if( __o=__n0){", - this.moveTo("dw12+__x0*"+(this.ortho?"persp":"(persp/__z0)"),"dh12+__y0*"+(this.ortho?"persp":"(persp/__z0)")), - "}"].join('')); - } else { // all other vertices - s.push([ - "__xn=dw12+(__x",i,"=m00*",p[x],"+m01*",p[y],"+m02*",p[z],"+m03)*",(this.ortho?"persp;":"(persp/__z"+i+");"), - "__yn=dh12+(__y",i,"=m10*",p[x],"+m11*",p[y],"+m12*",p[z],"+m13)*",(this.ortho?"persp;":"(persp/__z"+i+");"), - "if( __n",i," && !__n",i-1," || !__n",i,"&& __n",i-1,"){", // we visible and prev not or prev inv and we not - "__z=(__zc=(",zc,"-__z",i-1,")/(__z",i,"-__z",i-1,")) * __z",i,"+(__ze=1-__zc)* __z",i-1,";", - "__xi=dw12+(__zc*__x",i,"+__ze* __x",i-1,")*",(this.ortho?"persp":"(persp/__z)"),";", - "__yi=dh12+(__zc*__y",i,"+__ze* __y",i-1,")*",(this.ortho?"persp":"(persp/__z)"),";", - "if(!__o){__o=true;", - this.moveTo("__xi","__yi"), - "}else{", - this.lineTo("__xi","__yi"), - "}", - "}", - "if( __n",i,"){", - this.lineTo("__xn","__yn"), - "}"].join('')); - } - if(i==idx.length-1){ - s.push([ // termination step - "if(!__n0 && __n",i," || __n0 && ! __n",i,"){", - // do a lineto to the interp pos between last element and us - "__z=(__zc=(",zc,"-__z",i,")/(__z0-__z",i,")) * __z0+(__ze=1-__zc)* __z",i,";", - this.lineTo(["dw12+(__zc*__x0+__ze* __x",i,")*",(this.ortho?"persp":"(persp/__z)")].join(''), - ["dh12+(__zc*__y0+__ze* __y",i,")*",(this.ortho?"persp":"(persp/__z)") ].join('')), - "}", - open?"":this.close()].join('')); - } - } - s.push("}}"); - return s.join('').replace(/m\d\d\*\(?0\)?\+/g,""); - }, - // draw a 3D polygon - poly3D : function(indices,pts,fl){ - // we want rects between: - // first we count the doubles - var v,f=1,i,j = 0,d,pt,q,s = [], - cc = new Array(pts.length), - cf = new Array(pts.length), - f0, f1, f2; - if(fl) f0 = fl[0], f1 = fl[1], f2 = fl[2]; - else f0 = 0, f1 = 1, f2 = 2; - // calculate which values are used more than once to cache them - for( i = 0;i<indices.length;i++){ - d = indices[i]; if(d>=0) cc[d]++; - } - for( i = 0;i<pts.length;i++){ - if(cc[i]>1)cc[i] = j++; - else cc[i]=0; - } - for(var i = 0;i<indices.length;i++){ - d = indices[i]; - if(d>=0){ - pt = pts[d]; - q=[this.ortho?"": - "zt = persp / (m20*"+pt[f0]+"+m21*"+pt[f1]+"+m22*"+pt[f2]+"+m23);", - "dw12+(m00*"+pt[f0]+"+m01*"+pt[f1]+"+m02*"+pt[f2]+"+m03)*"+ - (this.ortho?"persp":"zt"), - "dh12+(m10*"+pt[f0]+"+m11*"+pt[f1]+"+m12*"+pt[f2]+"+m13)*"+ - (this.ortho?"persp":"zt")]; - d = f?0:i; - if(cc[d])q[1]= "__t"+cc[d]+(cf[d]?"":"="+q[1]), - q[2]= "__t"+cc[d]+(cf[d]++?"":"="+q[2]); - }; - switch(d){ - case -1: f=1;s.push( this.close() );break; - case 0: f=0;s.push( q[0], this.moveTo(q[1],q[2]) ); break; - case indices.length-1: s.push( q[0], this.lineTo(q[1],q[2]), - this.close() );break; - default: s.push( q[0], this.lineTo(q[1],q[2]) ); break; - } - } - return s.join('').replace(/m\d\d\*\(?0\)?\+/g,""); - }, - lineTo3D : function(x,y,z,sx,sy,fl){ - return this.$do3D("lineTo",x,y,z,sx,sy,fl); - }, - moveTo3D : function(x,y,z,sx,sy,fl){ - return this.$do3D("moveTo",x,y,z,sx,sy,fl); - }, - $store3D : function(x,y){ - return x+";"+y+";"; - }, - store3D : function(x,y,z,sx,sy,fl){ - return this.$do3D("$store3D",x,y,z,sx,sy,fl); - }, - $do3D : function(f,x,y,z,sx,sy,fl){ - var _x,_y,_z; - if(typeof x == 'string' && x.match(/[\[\]\*\+\-\/]/))x="(_x="+x+")",_x="_x"; - else x="("+x+")",_x=x; - if(typeof y == 'string' && y.match(/[\[\]\*\+\-\/]/))y="(_y="+y+")",_y="_y"; - else y="("+y+")",_y=y; - if(typeof z == 'string' && z.match(/[\[\]\*\+\-\/]/))z="(_z="+z+")",_z="_z"; - else z="("+z+")",_z=z; - if(fl){ - var v = [x,y,z], _v = [_x,_y,_z]; - x = v[_x=fl[0]], y = v[_y=fl[1]], z = v[_z=fl[2]]; - _x = _v[_x], _y = _v[_y], _z = _v[_z]; - } - var r = []; - if(!this.ortho)r.push("zt =persp/(m20*"+x+"+m21*"+y+"+m22*"+z+"+m23);"); - r.push(this[f]( (sx===undefined?"":sx)+ - "dw12+(m00*"+_x+"+m01*"+_y+"+m02*"+_z+"+m03)*"+(this.ortho?"persp":"zt"), - (sy===undefined?"":sy)+ - "dh12+(m10*"+_x+"+m11*"+_y+"+m12*"+_z+"+m13)*"+(this.ortho?"persp":"zt") ) ); - return r.join('').replace(/m\d\d\*\(?0\)?\+/g,""); - }, - - //---------------------------------------------------------------------- - // Style parsing - //---------------------------------------------------------------------- - - parseStyle : function( style, str, err ) { - var o = {}, k1, v1, k2, v2, t, s, i, len, _self = this; - // first we parse our style string - if ( (o = this.parseJSS(str,err)) === null ) return null; - var _self = this; - if(!(t=_self.stateTransition)[0x40001]){ - s = {}; - for(v1 in t)for(i = 0;i<64;i++)s[v1|i]=t[v1]|i; - _self.stateTransition = s; - // alert( (n[p]|i).toString(16) ); - } - - function styleinit(d){ - if(d.line === null || d.line=='null') delete d.line; - if(d.fill === null || d.fill=='null') delete d.fill; - if( (d.isshape && d.fill === undefined && - d.line === undefined && d.tile === undefined) || - (d.isfont && d.family === undefined) ) return false; - if(d.isshape){ - d.alpha = d.alpha!==undefined ? d.alpha : 1; - d.fillalpha = d.fillalpha!==undefined ? d.fillalpha:d.alpha; - d.gradalpha = d.gradalpha!==undefined ? d.gradalpha:d.fillalpha; - d.linealpha = d.linealpha!==undefined ? d.linealpha:d.alpha; - d.angle = d.angle!==undefined ? d.angle : 0; - d.weight = d.weight!==undefined ? d.weight : 1 - } - return true; - } - - function objtohash(a){ - // this spits out an object as a comparable hash - var k,v,n=[],s=[],i; - for(k in a)if(k.indexOf('$')==-1)n[n.length]=k; - n.sort(); - for(i = n.length-1;i>=0;i--){ - s[s.length] = k = n[i]; - if( (k=typeof(v = a[k])) == 'object') s[s.length] = objtohash(v); - else if(k=='array') s[s.length] = v.join(''); - else s[s.length] = v;//String(v); - } - return s.join(''); - } - - function objinherit(d, s){ - var k,v,n; - for(k in s)if(k.indexOf('$')==-1){ - if( typeof(v=s[k]) == 'object' && v!==null ){ - if(typeof(n=d[k]) !='object') n = d[k] = {}; - objinherit(n, v); - }else if(d[k] === undefined)d[k] = v; - } - } - - function stylecopy(root, d, s, noinit){ - if(!s)return; - var k,v,t,n,m,w,p,h,q,u,o,x,y,z,r,g; - for(k in s){ - if( typeof(v=s[k]) == 'object' && v!==null ){ - if(typeof(n=d[k]) !='object') n = d[k] = {}; - stylecopy(root, n, v); - }else if(d[k] === undefined) - d[k] = _self.isDynamic(v)?_self.parseJSS(v):v; - } - if(t=s.inherit){ - stylecopy( root, d, root['$'+t]||root[t]||_self['$'+t], 1); - } - - if(!( d.isshape || d.isfont) ){ - - // inventory classes and states we have styles for - p=[]; - for(k in d)if( typeof(v=d[k])=='object' && - !(n=null) && ( (m=k.split(':')).length>1 || (n=k.split('.')).length>1 ) ){ - if(n && typeof(t=d[n[0]])=='object'){ - v.$base=n[0],v.$class=n[1]; - if(!(w=t.$classmap))w=t.$classmap=[],t.$base=v.$base,t.$isbase=1; - w[w.length] = (n[1].split(':'))[0]; - }else if(m && typeof(t=d[m[0]])=='object' && m[0].indexOf('.')==-1){ - v.$base=m[0],v.$state=m[1]; - if(!(w=t.$statemap))w=t.$statemap=[],p[p.length]=t,t.$base=v.$base,t.$isbase=1; - w[w.length] = m[1]; - } - } - // copy base states to class states - for(k=p.length-1;k>=0;--k){ - if( (v = p[k]).$classmap && !v.nocopy) { - // lets copy our states to the other classes - m = v.$statemap, n = v.$classmap, w=v.$base; - for(t=m.length-1;t>=0;--t){ - for(u=n.length-1;u>=0;--u){ - if(!d[o = w+'.'+n[u]+':'+m[t]]){ - objinherit( o=d[o]={}, d[w+':'+m[t]] ); - o.$base = w, o.$class = n[u], o.$state = m[t]; - } - } - } - } - } - // do all inheritance of classes and states - for(k in d)if( typeof(v=d[k])=='object' && v && (o=v.$base) ){ - m = v.$state,n = v.$class; - if(!v.nobase){ - while(m=_self.$stateInherit[m]){ - if( (n && (t=d[o+'.'+n+(m==1?'':':'+m)])) || - (t=d[o+(m==1?'':':'+m)])) - objinherit(v, t); - } - } - if((t = d[o]) && n)objinherit(v,t); - // lets see if we are pointless - if(!t.nomerge){ - if(!(n=t.$merge))n=t.$merge={}; - if(!n[m=objtohash(v)])n[m] = v; - else v.$merged = n[m]; - } - // - } - // hurrah now lets go and create the hashmaps CODECOMPLEXITY++ - n = _self.stateBit, q = _self.$stateFallback; - for(k in d)if( typeof(v=d[k])=='object' && v && (v.isshape||v.isfont) ){ - - var shadow = d[k+'.shadow']; - if(v.$isbase){ - w = v.$statehash = {}, y = v.$statelist = [], - r = v.$storelist = [], h = v.$speedhash={}; - delete v.$merge;delete v.$merged; - - m = v.$classmap || [], u = v.$base; - m.unshift(null); // add 'normal' state - for(i=m.length-1;i>=0;--i){ - t=u+((t=m[i])?'.'+t:''); - for(p in n){ - o = p; - while(!(x = d[ g=(o!=0?t+':'+o:t) ])) - if(!(o=q[o]))break; - - if(x && (x.$class!='shadow' || x.$state)){ // it has a special rendertarget - while(x.$merged) x = x.$merged; - if(!x.$isbase){ - if(!x.$inlist){ - g = x.$store = []; - x.$inlist = 1; - x.join = o!=0?t+':'+o:t; - if(x.$class) y.unshift(x),r.unshift(g) ; - else y[y.length]=x, r[r.length]=g; - } - if(!(o = w[z=(n[p]|i)] = x.$store).base && - x.overlay)o.base = (m[i]?d[t]:0) || {}; - if(z&0x36EC0000)o.trans=x.trans=1; - h[z] = x.speed || 1; - }else if(shadow)w[n[p]|i] = {}; - } - } - } - if(shadow){// if we have a shadow class so we need to shuffle some stuff around - g = v.$store = []; - // add our shadow to all the classes to be a baseclass - for(x = 0, p = r.length; x<p; x++) - r[x].base = ((m=y[x].$state)?((m=d[k+'.shadow:'+m])?m.$store:0):0)||{} - for(x in w)if(!w[x].sort)w[x] = g; - - r.unshift(g),y.unshift(v),g.base = {},w[0] = g; - v.$shadow = shadow; - shadow.$statelist = v.$statelist,shadow.$statehash = v.$statehash; - shadow.$storelist = v.$storelist,shadow.$speedhash = v.$speedhash; - } - // lets dump this shite - - } - // remove if we aint active - if( !styleinit(v) ) delete d[k]; - - } - } - } - stylecopy( style, o, style, 1 ); - - // for each base object, we need to create the subobject maps and state luts - // _statelut[state]->arrays - // _statelist[] all states except the base in order of layering - // _basemap[..name..] -> baseID a map from name to ID - // _transition[..state..] -> transitory map including baseID's - - - //jpf.alert_r(o); - return o; - }, - /* - stateBit : { - 0 : 0, - 'hidden' : 0x40000000, - 'init' : 0x20000000, - 'deinit' : 0x10000000, - 'hover' : 0x08000000, - 'hover-in' : 0x04000000, - 'hover-out' : 0x02000000, - 'select' : 0x01000000, - 'select-in' : 0x00800000, - 'select-out' : 0x00400000, - 'select-hover' : 0x00200000, - 'select-hover-in' : 0x00100000, - 'select-hover-out' : 0x00080000, - 'animating' : 0x00040000 - },*/ - stateBit : { - 0 : 0, - 'init' : 0x01000000, // 0xff0000 == statetype - 'hidden' : 0x00010000, // 0x0f000000 == dynamic type 0 = no dyn, 1 = in, 2 = out, 3 = inout - 'deinit' : 0x02000000, // 0xf0000000 == automated-return-type - 'hover' : 0x00020000, - 'hover-in' : 0x01020000, - 'hover-inout' : 0x11020000, - 'hover-out' : 0x02020000, - 'select' : 0x00030000, - 'select-in' : 0x01030000, - 'select-inout' : 0x11030000, - 'select-out' : 0x02030000, - 'select-hover' : 0x00040000, - 'select-hover-in' : 0x01040000, - 'select-hover-inout': 0x11040000, - 'select-hover-out' : 0x02040000, - 'animating' : 0x10050000 - }, - - stateTransition : { - 0x01000000 : 0, - 0x02000000 : 0x00010000, - 0x01020000 : 0x00020000, - 0x11020000 : 0x02020000, - 0x02020000 : 0, - 0x01030000 : 0x00030000, - 0x11030000 : 0x02030000, - 0x02030000 : 0, - 0x01040000 : 0x00040000, - 0x11040000 : 0x02040000, - 0x02040000 : 0x00030000, - 0x01050000 : 0x01050000 - }, - - stateMask : { - 'selected' : 0x01000000|0x00800000|0x00200000|0x00100000|0x00080000, - 'normal' : 0x20000000|0x08000000|0x04000000|0x02000000|0x00040000, - 'dynamic' : 0x20000000|0x10000000|0x04000000|0x02000000|0x00800000| - 0x00400000|0x00100000|0x00080000|0x00040000, - 'hover' : 0x08000000|0x04000000|0x00200000|0x00100000 - }, - - - $stateInherit : { - 'hidden' : 1, - 'init' : 1, - 'deinit' : 1, - 'hover' : 1, - 'hover-in' : 'hover', - 'hover-out' : 'hover', - 'select' : 1, - 'select-in' : 'select', - 'select-out' : 'select', - 'select-hover' : 'hover', - 'select-hover-in' : 'select-hover', - 'select-hover-out' : 'select-hover', - 'animating' : 1 - }, - - $stateFallback : { - 'init' : 1, - 'hover' : 1, - 'hover-in' : 'hover', - 'hover-inout' : 'hover-in', - 'hover-out' : 1, - 'select' : 1, - 'select-in' : 'select', - 'select-inout' : 'select-in', - 'select-out' : 1, - 'select-hover' : 'hover', - 'select-hover-in' : 'select-hover', - 'select-hover-inout': 'select-hover-in', - 'select-hover-out' : 'select', - 'hidden' : 1 - }, - - getXYWH : function( m, p, noflatten ){ - var t; - if(!( (t=this.$getXYWH_NT[p]) || (p=this.$getXYWH_TN[t=p]) ))return '0'; - if(m==null)return '0'; - if(typeof(m)=='object'){ - if(m.sort) return --p>=m.length?'0':( (t=m[p]) && t.sort && !noflatten ? t.join(''): t); - return (t=m[t])===undefined||p>1?'0':(t && t.sort && !noflatten ? t.join('') : t); - } - return p==1?m:'0'; - }, - $getXYWH_NT : {1:'x',2:'y',3:'z',4:'w'}, - $getXYWH_TN : {'x':1,'y':2,'z':3,'w':4}, - - getTRBL : function( m, p, noflatten ){ - var t; - if(!( (t=this.$getTRBL_NT[p]) || (p=this.$getTRBL_TN[t=p]) ))return '0'; - if(m==null)return '0'; - if(typeof(m)=='object'){ - if(m.sort) return --p>=m.length?'0':( (t=m[p]) && t.sort && !noflatten ? t.join(''): t); - return (t=m[t])===undefined||p>1?'0':(t && t.sort && !noflatten ? t.join('') : t); - } - return p==1?m:'0'; - }, - $getTRBL_NT : {1:'t',2:'r',3:'b',4:'l'}, - $getTRBL_TN : {'t':1,'y1':1,'r':2,'x2':2,'b':3,'y2':3,'l':4,'x1':4}, - - getFlat : function( m ){ - if(typeof(m)=='object' && m.sort) return m.join(''); - return m; - }, - - getColor : function (a) { - if(a.match(/\(/)) return a; - if(a.match(/^#/)) return "'"+a+"'"; - var b = a.toLowerCase(); - return (this.colors[b])?"'"+this.colors[b]+"'":a; - }, - - getX : function( s, pre, val, post, def){ - var v; return (typeof(v=s[val+'-x'])=='undefined' && - (typeof(v=s[val])!='object' || typeof(v=v[0])=='undefined'))? - (typeof(def)!='undefined'?def:''):(pre+v+post); - }, - getY : function( s, pre, val, post, def, ovl){ - var v; return (typeof(v=s[val+'-y'])=='undefined' && - (typeof(v=s[val])!='object' || typeof(v=v[1])=='undefined'))? - (typeof(def)!='undefined'?def:''):(pre+v+post); - }, - checkX : function( s, val, ovl, no){ - var v; return (typeof(v=s[val+'-x'])=='undefined' && - (typeof(v=s[val])!='object' || typeof(v=v[0])=='undefined'))? - (typeof(no)=='undefined'?'':no):ovl; - }, - checkY : function( s, val, ovl, no){ - var v; return (typeof(v=s[val+'-y'])=='undefined' && - (typeof(v=s[val])!='object' || typeof(v=v[1])=='undefined'))? - (typeof(no)=='undefined'?'':no):ovl; - }, - - isDynamic : function( a ) { - // check if we have a dynamic property.. how? - return a && typeof(a)=='string' && - !(a.indexOf('.')!=-1 && a.match(/^[\s:a-zA-Z0-9\/\\\._-]+$/)) && - a.match(/[\(+*\/-]/)!=null; - }, - - optimize : function( code ){ - var c2,c3,s=[],cnt={},n=0; - // first we need to join all nested arrays to depth 2 - if(typeof(code) == 'object'){ - code = code.join(''); - /* for(var i = code.length-1;i>=0;i--) - if(typeof(c2=code[i]) == 'object'){ - for(var j=c2.length-1;j>=0;j--) - if(typeof(c3=c2[j]) == 'object') - c2[j] = c3.join(''); - code[i] = c2.join(''); - }*/ - } - // find used math functions and create local var - code.replace(/\_\_(\w+)/g,function(m,a){ - if(!cnt[a]) { - if(a.length<=2)s.push("__"+a); - else s.push("__"+a+"=Math."+a); - cnt[a]=1; - } - }); - - // optimize out const parseInt and const math-operations - code = code.replace(/(__(\w+))\((\-?\d+\.?\d*)\)/g, - function(m,a,b,c){ - if(a=='__round')return Math.round(c); - return Math[b](c); - }); - - - //code = code.replace(/__round\((_d[xy])\)/g,"$1"); - //code = code.replace(/\(0\)\+/g,""); - - //TODO pull out 0 multiplication - //code = code.replace(/\+0\s*([\;\,\)])/g,"$1"); - - if(code.match('_rndtab'))s.push('_rndtab=jpf.draw.$rndtab'); - //code = code.replace(/\(([a-z0-9\_]+)\)/g,"$1"); - - code = s.length ? code.replace(/\_math\_/,s.join(',')): code; - - cnt = {},n = 0, s=[]; - /* - code = code.replace(/(m\d\d\*)\(?(\-?\d+(?:\.\d+))?\)/g,function(m,a,b){ - var t = a+b; - if(cnt[t] === undefined){ - s.push("_mo"+n+"="+t); - return cnt[t]="_mo"+(n++); - } - return cnt[t]; - }); - */ - code = s.length ? code.replace(/\_opt\_/,s.join(',')): code; - code = code.replace(/__round\((d[wh])\)/g,"$1"); - - return code; - }, - - parseJSS : function(s,err){ - if(!s)return{}; - var lp = 0, sm = 0, t, i, len, fn = 0, sfn = [], arg = [], sarg = [], - ac = [], sac = [], sn=[], obj = {}, prop = 0, sobj = [], - _self = this, mn={1:'}',2:')',3:']',4:')',5:'}'}, rn={'{':1,'(':2,'[':3}, ln=6; - try{ - s=s.replace(/\/\*[\S\s]*?\*\/|\/\/.*?;/g,''); - s.replace(/(["'])|([\w\.\_-]+\:?[\w\_-]*)\s*\{\s*|([\w\_-]+)\s*[:]+\s*|([\w\_-]+)\s*\(\s*|([({\[])|([)}\]])|(\\["'{}\[\](),;\:]|\s*[\<\>\=*+\%@&\/]\s*|\s*\-\s+)|([,\s]+)|(;)|$/g, - function(m,str,openobj,openval,openmac,open,close,skip,sep,split,pos){ - /*log( ln+' - '+(str?' str:'+str:'')+(word?' word:'+word:'')+(openw?' openw:'+openw:'')+ - (open?' open'+open:'')+(close?' close:'+close:'')+(sep?' sep:##'+sep+'#':'')+ - (split?' split:'+split:'')+(end?' end:'+end:'')+' pos:'+pos+'\n');*/ - if(skip)return m; - if(sm || str) { - if(str && !sm)sm = str; - else if(sm==str)sm = 0; - return m; - } - if( sep ){ - ac.push(s.slice(lp,pos));arg.push(ac.join(''));lp=pos+sep.length,ac=[]; - return m; - } - if( openval ){ - if(ln>=5){ - ln = 6, prop = openval, lp = pos+m.length;arg=[],ac=[]; - } - return m; - } - if( openmac){ - sn.push(ln=4); - if(pos>lp)ac.push( s.slice(lp,pos) ); - sac.push(ac); sarg.push(arg); - sfn.push(fn); fn = openmac; - arg = [], ac = [], lp = pos+m.length; - return m; - } - if(openobj){ - if(ln<5)throw({t:"JSS Error - object scope found inside macro",p:pos}); - lp = pos+m.length; sn.push(ln=5); - sobj.push(obj); obj = obj[openobj] = {}; - return m; - } - if( open ){ - sn.push(ln=rn[open]); - if(ln==1 && prop){ - sn.pop(); - lp = pos+m.length; sn.push(ln=5); - sobj.push(obj); obj = obj[prop] = {}; - }else if(ln==3){ - if(pos>lp)ac.push( s.slice(lp,pos) ); - sac.push(ac); sarg.push(arg); - arg = [], ac = [], lp = pos+open.length; - } - return m; - } - if( close ){ - if( !sn.length || mn[ln=sn.pop()] != close){ - throw({t:"JSS Error - closed "+ln+" with "+close,p:pos}); - log(); - } - switch(ln){ - case 3: // closed an array - ac.push(s.slice(lp,pos));arg.push(ac.join('')); - if(sarg.length!=1){ // append as string - (ac=sac.pop()).push( '[',arg.join(','),']' ); - arg = sarg.pop(); - } - else { // append as array - sac.pop();t = sarg.pop();ac=[]; - for(i = 0,len=arg.length;i<len;i++)t.push(arg[i]); - arg = t; - } - lp = pos+close.length; - break; - case 4: // closed a macro - ac.push(s.slice(lp,pos));arg.push(ac.join('')); - (ac=sac.pop()).push( (t=_self[fn])?t.apply( _self, - arg ) : arg.join(',') ); - arg = sarg.pop(), fn = sfn.pop(), lp = pos+1; - break; - case 5: // closed an object - ac.push(s.slice(lp,pos));arg.push(ac.join(''));lp = pos+close.length, ac = []; - if(prop)obj[prop] = arg.length>1?arg:arg[0]; - arg=[], prop=null, obj = sobj.pop(); - break; - } - if(!sarg.length)ln=6; - return m; - } - if( ln>=5 ){ - ac.push(s.slice(lp,pos)); - if((t=ac.join('')).length)arg.push(t); - lp = pos+m.length, ac = []; - if(prop)obj[prop] = arg.length>1?arg:arg[0]; - else if(t && sn.length==0)obj = arg.length>1?arg:arg[0]; - arg=[],prop=null; - } - return m; - }); - if(sm)throw({t:"JSS Error - Unclosed string found "+sm,p:lp}); - if(sn.length>0)throw({t:"JSS Error - Unclosed object found "+sn[sn.length-1],p:lp}); - }catch(e){ - jpf.alert_r(e); - if(err)err.v = e.p>=0 ? e.t+" at: "+e.p+" ->"+s.slice((t=e.p-4)<0?0:t,7)+"<-" : e.t; - return null; - } - return obj; - }, - - sin : function(a){return "__sin("+a+")";}, - cos : function(a){return "__cos("+a+")";}, - tan : function(a){return "__tan("+a+")";}, - asin : function(a){return "__asin("+a+")";}, - acos : function(a){return "__acos("+a+")";}, - atan : function(a){return "__atan("+a+")";}, - atan2 : function(a){return "__atan2("+a+")";}, - floor : function(a){return "__floor("+a+")";}, - exp : function(a){return "__exp("+a+")";}, - log : function(a){return "__log("+a+")";}, - pow : function(a,b){return "__pow("+a+","+b+")";}, - random : function(a){return "__random("+a+")";}, - round : function(a){return "__round("+a+")";}, - sqrt : function(a){return "__sqrt("+a+")";}, - $pal : function(imode,n){ - // alright this is a color interpolation function, we got n arguments - // which are string colors, hexcolors or otherwise and we need to write an interpolator - var s=[ - "'#'+('000000'+(__round(", - "((__a=parseInt((__t=["]; - for(var i = 2, len=arguments.length;i<len;i++){ - var t = arguments[i]; - // check what t is and insert - s.push(i>2?",":""); - if(jpf.draw.colors[t]) - s.push( "'", jpf.draw.colors[t], "'" ); - else if(t.match(/\(/)) - s.push(t); - else if(t.match(/^#/)) - s.push( "'", t, "'" ); - else - s.push(t); - } - s.push( - "])[ __floor( __c=(__f=(",n,")",imode?"*"+(len-3):"", - ")<0?-__f:__f)%",len-2,"].slice(1),16))&0xff)", - "*(__d=1-(__c-__floor(__c)))", - "+((__b=parseInt(__t[ __ceil(__c)%",len-2, - "].slice(1),16))&0xff)*(__e=1-__d) )", - "+(__round(__d*(__a&0xff00)+__e*(__b&0xff00))&0xff00)", - "+(__round(__d*(__a&0xff0000)+__e*(__b&0xff0000))&0xff0000)", - ").toString(16)).slice(-6)"); - return s.join(''); - }, - - $lut : function(imode,n){ - var s=["(["],a, i = 2, len = arguments.length; - for(;i<len;i++){ - a = arguments[i];s.push(i>2?",":""); - if(typeof(a)=='string' && a.match(/\(/) || a.match(/^['"]/)) - s.push(a); - else s.push("'",a,"'"); - } - s.push("])[__floor((__b=((",n,")",imode?"*"+(len-3):"", - ")%",len-2,")<0?-__b:__b)]"); - return s.join(''); - }, - - $lin : function(imode,n){ - var s=["((__t=["],a, i = 2,len=arguments.length; - for(;i<len;i++){ - a = arguments[i]; s.push(i>2?",":""); - if(typeof(a)=='string' && a.match(/\(/) || a.match(/^['"]/)) - s.push(a); - else s.push("'",a,"'"); - } - s.push("])[__floor( __c=(__f=(",n,")",imode?"*"+(len-3):"", - ")<0?-__f:__f)%",len-2,"]", - "*(__d=1-(__c-__floor(__c)))", - "+__t[ __ceil(__c)%",len-2, - "]*(__e=1-__d) )"); - return s.join(''); - }, - - fixed : function(a,v,nz){ - v = "parseFloat(("+a+").toFixed("+v+"))"; - return parseInt(nz)?this.nozero(a,v):v; - }, - padded : function(a,v,nz){ - v = "("+a+").toFixed("+v+")"; - return parseInt(nz)?this.nozero(a,v):v; - }, - abs : function(a){ - if(parseFloat(a)==a)return Math.abs(a); - if(typeof(a) == 'number' || a.match(/$[a-z0-9_]+^/)) - return "("+a+"<0?-"+a+":"+a+")"; - return "((__t="+a+")<0?-__t:__t)"; - }, - min : function(a,b){ - if(b===null)return a; - if(parseFloat(a)==a && parseFloat(b)==b)return Math.min(a,b); - var a1=a,b1=b,a2=a,b2=b; - if(typeof(a) == 'string' && !a.match(/$-?[a-z0-9\_]+^/))a1="(__a="+a+")", a2="__a"; - if(typeof(b) == 'string' && !b.match(/$-?[a-z0-9\_]+^/))b1="(__b="+b+")", b2="__b"; - return "(("+a1+")<("+b1+")?"+a2+":"+b2+")"; - }, - max : function(a,b){ - if(b===null)return a; - if(parseFloat(a)==a && parseFloat(b)==b)return Math.max(a,b); - var a1=a,b1=b,a2=a,b2=b; - if(typeof(a) == 'string' && !a.match(/$-?[a-z0-9\_]+^/))a1="(__c="+a+")", a2="__c"; - if(typeof(b) == 'string' && !b.match(/$-?[a-z0-9\_]+^/))b1="(__d="+b+")", b2="__d"; - return "(("+a1+")>("+b1+")?"+a2+":"+b2+")"; - }, - clamp : function(a,b,c){ - if(b===null||c==null)return a; - return this.max(this.min(a,c),b); - }, - pal : function(){ - var arg = Array.prototype.slice.call(arguments,0);arg.unshift(1); - return this.$pal.apply(this,arg); - }, - pali : function(){ - var arg = Array.prototype.slice.call(arguments,0);arg.unshift(0); - return this.$pal.apply(this,arg); - }, - lin : function(){ - var arg = Array.prototype.slice.call(arguments,0);arg.unshift(1); - return this.$lin.apply(this,arg); - }, - lini : function(){ - var arg = Array.prototype.slice.call(arguments,0);arg.unshift(0); - return this.$lin.apply(this,arg); - }, - lut : function(){ - var arg = Array.prototype.slice.call(arguments,0);arg.unshift(1); - return this.$lut.apply(this,arg); - }, - luti : function(){ - var arg = Array.prototype.slice.call(arguments,0);arg.unshift(0); - return this.$lut.apply(this,arg); - }, - $rgbpack : function( r,g,b){ - return ('#'+('000000'+(((r<0?0:(r>255?255:parseInt(r)))<<16)+ - ((g<0?0:(g>255?255:parseInt(g)))<<8)+ - ((b<0?0:(b>255?255:parseInt(b))))).toString(16)).slice(-6)); - }, - rgb : function(r,g,b){ - if(parseFloat(r)==r && parseFloat(g)==g && parseFloat(b)==b) - return this.$rgbpack(r,g,b); - return ["('#'+('000000'+(", - (parseFloat(r)==r?((r<0?0:(r>255?255:parseInt(r)))<<16): - "(((__t="+r+")<0?0:(__t>255?255:parseInt(__t)))<<16)"),"+", - (parseFloat(g)==g?((g<0?0:(g>255?255:parseInt(g)))<<8): - "(((__t="+g+")<0?0:(__t>255?255:parseInt(__t)))<<8)+"),"+", - (parseFloat(b)==b?((b<0?0:(b>255?255:parseInt(b)))): - "(((__t="+b+")<0?0:(__t>255?255:parseInt(__t))))"), - ").toString(16)).slice(-6))"].join(''); - }, - $hsvpack : function(h,s,v){ - var i, m=v*(1-s), - n=v*(1-s*((i=Math.floor(((h<0?-h:h)%1)*6))?h-i:1-(h-i))); - - switch (i) - { - case 6: - case 0: return this.$rgbpack(v, n, m); - case 1: return this.$rgbpack(n, v, m); - case 2: return this.$rgbpack(m, v, n); - case 3: return this.$rgbpack(m, n, v); - case 4: return this.$rgbpack(n, m, v); - default: - case 5: return this.$rgbpack.rgb(v, m, n); - } - }, - hsv : function(h,s,v){ - if(parseFloat(r)==r && parseFloat(g)==g && parseFloat(b)==b) - return this.$hsvpack(r,g,b); - return "jpf.draw.$hsvpack("+h+","+s+","+v+");"; - }, - rgbf : function(r,g,b){ - return this.rgb(parseFloat(r)==r?r*255:"255*("+r+")", - parseFloat(g)==g?g*255:"255*("+g+")", - parseFloat(b)==b?b*255:"255*("+b+")"); - }, - nozero : function(a,v,z){ - return "(("+a+")>-0.0000000001 && ("+a+")<0.0000000001)?"+ - (z!==undefined?z:"''")+":("+(v!==undefined?v:a)+")"; - }, - $rndtab : null, - rnd : function(a){ - if(a){ - if( !this.$rndtab ){ - var i, t = this.$rndtab = Array( 256 ); - for(i = -256;i<256;i++)t[i] = Math.random(); - } - return "_rndtab[__round(("+a+")*255)%255]"; - } - return "((_rseed=(_rseed * 16807)%2147483647)/2147483647)" - }, - snap : function(a,b){ - return "(__round(("+a+")/(__t=("+b+")))*__t)"; - }, - rnds : function(a,b){ - return this.rnd(this.snap(a,b)); - }, - tsin : function(a){ - return "(0.5+0.5*__sin("+a+"))"; - }, - tcos : function(a){ - return "(0.5+0.5*__cos("+a+"))"; - }, - usin : function(a){ - return "(0.5-0.5*__sin("+a+"))"; - }, - ucos : function(a){ - return "(0.5-0.5*__cos("+a+"))"; - }, - two : function(a){ - return "(0.5+0.5*("+a+"))"; - }, - - $equalStyle : function( a, b){ - if(a.isfont && b.isfont) - return a.family === b.family && - a.join === b.join && - a.height == b.height && - a.width == b.width && - a.align === b.align && - a.color === b.color && - a.size === b.size && - a.style === b.style - if(a.isshape && b.isshape) - return a.line === b.line && - a.join === b.join && - a.weight == b.weight && - a.fill === b.fill && - a.fillalpha === b.fillalpha && - a.linealpha === b.linealpha && - a.angle === b.angle; - return false; - }, - - $shape : { - isshape : true, - line : null, - fill : null, - tilex:'(this.tilex)', - tiley:'(this.tiley)' - }, - - $font : { - isfont : true, - height : 12, - family : "verdana", - weight : "normal", - color : "#00000", - size : 10 - }, - - //---------------------------------------------------------------------- - - // Generic rendering - - //---------------------------------------------------------------------- - - draw3D : function(x,y,z,w,h,d){ - return ''; - }, - - //---------------------------------------------------------------------- - - beginMouseState : function( style, sthis, func, nargs ){ - var s = [], l = this.l; - - this.mousestyle = style; - this.mousethis = sthis; - this.mousefunc = func; - this.mousestates = []; - var v = style.$statelist, i, j, t, u; - if(!v || !v.length) return ''; - - v = this.mousestates = v.slice(0); - if(v[0]!=style) - v.unshift(style); - - if(!l._mousestyles)l._mousestyles = []; - for(i = 0, j = v.length;i<j;i++){ - u = (t=v[i])._mid = l._mousestyles.push(t)-1; - if(t.$store)t.$store._mid = u; - } - - s.push("_s = l._mousestyles[",style._mid,"], _sh = _s.$statehash, _sp = _s.$speedhash;"); - - return s.join(''); - }, - - checkMouseState:function(state,time) { - var a=[],t,i,j,v = this.mousestates, s; - - if(!v || !v.length){ - for(i = 2, j = arguments.length;i<j;i++)a.push(arguments[i]); - a.push(true); - this.style = this.mousestyle; - s = this.mousefunc.apply(this.mousethis,a); - this.style = 0; - return s; - } - s = ["t=(n-",time,")*(_sp[_t=_sh[",state,"]]||100000);"]; - for(i = 2, j = arguments.length;i<j;i++){ - a.push( t = "_s"+(i-1) ); - s.push( t,"=",arguments[i],(i!=j-1)?",":";"); - } - a.push(true); - - s.push("switch(_t?_t._mid:0){" ); - for(i = 0, j = v.length;i<j;i++){ - style = v[i]; - //alert(jpf.vardump(style).replace(/\t/g,'@').replace(/\n/g,'#')); - this.style = style; - if(v[i]) - s[s.length]=[ - "case ",style._mid,":{","/*"+jpf.vardump(style,0,1)+"*/\n", - this.mousefunc.apply(this.mousethis,a), - "}break;"].join(''); - } - s.push("};"); - this.style = 0; - return s.join(''); - }, - - $endMouseState : function(){ - this.mousestyle = 0; - return ''; - }, - - //---------------------------------------------------------------------- - - drawPart : function(x,y,w,h,rs,rw,m){ - var t = this.style; - var ds = '0', dw = '1'; - var gx = this.getX, gy = this.getY, cx = this.checkX, cy = this.checkY; - switch(t.shape){ - default: - case 'pie': - if(gx(t,'','scale','','1')!='1'){ - rs=['_x5=(',gx(t,'(','offset',')+'),'(',rs,')','+', - gx(t,'(','center',')','0.5'),'*(_x3=',rw,')', - gx(t,'*(1-(_x4=','scale','))'),')*p2'].join(''); - rw='_x5+(_x3*_x4)*p2'; - }else{ - rs = ['_x5=(',gx(t,'(','offset',')+'),'(',rs,')',')*p2'].join(''); - rw = '_x5+('+rw+')*p2'; - } - if(gy(t,'','scale','','1')!='1'){ - ds=[gy(t,'(','offset',')+'),gy(t,'(','center',')','0.5'), - gy(t,'*(1-(_y4=','scale','))')].join(''); - dw='_y4'; - }else{ - ds = [gy(t,'(','offset',')','0')].join(''); - dw = '1'; - } - // lets draw an ellipse with rs and rw phases - // now we have an offset y and a size y how do we deal with that? - if(ds!='0'){ - x = "_x6=__sin(_y8=((_x9="+rs+")+(_y9="+rw+"))*0.5)*(_x8="+ - ds+")*(_x7="+w+")+("+x+")"+gx(t,'+_x7*(','move',')'); - y = "_y6=__cos(_y8)*_x8*(_y7="+h+")+("+y+")"+gy(t,'+_y7*(','move',')'); - w = '_x7*(_x3='+dw+')'; - h = '_y7*_x3'; - rs = '_x9'; - rw = '_y9'; - }else{ - x = "_x6=("+x+")"; - y = "_y6=("+y+")"; - w = dw=='1'?'('+w+')':'('+w+')*(_x3='+dw+')'; - h = dw=='1'?'('+h+')':'('+h+')*_x3'; - } - if(m){ - return [ - "if( ((_x1=((",x,")-mx)/(",w,"))*_x1+(_y1=((",y,")-my)/(",h,"))*_y1) < 1 ){", - "_x1=(p+__atan2(_x1,_y1));", - "if( ((_x2=(",rs,")%p2)<0?(_x2=p2-_x2):_x2) >", - "((_y2=(",rw,")%p2)<0?(_y2=p2-_y2):_y2) ){", - "if(_x1 >= _x2 || _x1<=_y2 )return x;", - "}else{", - "if(_x1 >= _x2 && _x1<=_y2 )return x;", - "}", - "}" - ].join(''); - }else{ - return [ - this.moveTo(x,y), - this.ellipse('_x6','_y6',w,h,rs,rw,1), - this.close()].join(''); - } - /* - if(gx(t,'','scale','','1')!='1'){ - rs=['_x5=(',gx(t,'(','offset',')+'),'(',rs,')','+', - gx(t,'(','center',')','0.5'),'*(_x3=',rw,')', - gx(t,'*(1-(_x4=','scale','))'), - gx(t,'+_x3*(','move',')'),')*p2'].join(''); - rw='_x5+(_x3*_x4)*p2'; - }else{ - rs = ['_x5=(',gx(t,'(','offset',')+'),'(',rs,')', - gx(t,'+(_x3='+rw+')*(','move',')'),')*p2'].join(''); - rw = '_x5+('+cx(t,'move','_x3',rw)+')*p2'; - } - if(gy(t,'','scale','','1')!='1'){ - ds=[gy(t,'(','offset',')+'),gy(t,'(','center',')','0.5'), - gy(t,'*(1-(_y4=','scale','))'),gy(t,'+(','move',')')].join(''); - dw='_y4'; - }else{ - ds = [gy(t,'(','offset',')','0'),gy(t,'+(','move',')')].join(''); - dw = '1'; - } - // lets draw an ellipse with rs and rw phases - // now we have an offset y and a size y how do we deal with that? - if(ds!='0'){ - return [ -this.moveTo("_x6=__cos(_y8=((_x9="+rs+")+(_y9="+rw+"))*0.5)*(_x8="+ds+")*(_x7="+w+")+("+x+")", - "_y6=__sin(_y8)*_x8*(_y7="+h+")+("+y+")"), - this.ellipse( '_x6','_y6','_x7*(_x3='+dw+')','_y7*_x3','_x9','_y9',1), - this.close()].join(''); - }else{ - return [ - this.moveTo("_x6=("+x+")","_y6=("+y+")"), - this.ellipse( '_x6','_y6',dw=='1'?'('+w+')':'('+w+')*(_x3='+dw+')', - dw=='1'?'('+h+')':'('+h+')*_x3',rs,rw,1), - this.close()].join(''); - }*/ - } - }, - - //---------------------------------------------------------------------- - - draw2D : function(x,y,w,h,m){ - // css stylable drawing - var t = this.style; - var gx = this.getX, gy = this.getY, cx = this.checkX, cy = this.checkY; - function rect(){ - if(gx(t,'','scale','','1')!='1'){ - x=[gx(t,'(','offset',')+'),'(',x,')','+',gx(t,'(','center',')','0.5'),'*(_x3=',w,')', - gx(t,'*(1-(_x4=','scale','))'),gx(t,'+_x3*(','move',')')].join(''); - w='_x3*_x4'; - }else{ - x = [gx(t,'(','offset',')+'),'(',x,')',gx(t,'+(_x3='+w+')*(','move',')')].join(''); - w = cx(t,'move','_x3',w); - } - if(gy(t,'','scale','','1')!='1'){ - y=[gy(t,'(','offset',')+'),'(',y,')','+',gy(t,'(','center',')','0.5'),'*(_y3=',h,')', - gy(t,'*(1-(_y4=','scale','))'),gy(t,'+_y3*(','move',')')].join(''); - h='_y3*_y4'; - }else{ - y = [gy(t,'(','offset',')+'),'(',y,')',gy(t,'+(_y3='+h+')*(','move',')')].join(''); - h = cy(t,'move','_y3',h); - } - } - switch(t.shape){ - case 'rect': - default: - if(!t.rotate){ - rect(); - return this.rect(x,y,w,h); - }else{ - return [ - '_x9=(_x8=(_x6=',gx(t,'(','center',')','0.5'),'*(_x3=',w,'))*(',gx(t, - '(1-(_x4=','scale','))','0'),'-1))+_x3',cx(t,'scale','*_x4'),';', - '_y9=(_y8=(_y6=',gy(t,'(','center',')','0.5'),'*(_y3=',h,'))*(',gy(t, - '(1-(_y4=','scale','))','0'),'-1))+_y3',cy(t,'scale','*_y4'),';', - this.moveTo('(_cr=__cos(_t='+t.rotate+'))*_x8-(_sr=__sin(_t))*_y8+(_x5='+ - gx(t,'(','offset',')+')+x+'+_x6)','_sr*_x8+_cr*_y8+(_y5='+ - gy(t,'(','offset',')+')+y+'+_y6)'), - this.lineTo('_cr*_x9-_sr*_y8+_x5','_sr*_x9+_cr*_y8+_y5'), - this.lineTo('_cr*_x9-_sr*_y9+_x5','_sr*_x9+_cr*_y9+_y5'), - this.lineTo('_cr*_x8-_sr*_y9+_x5','_sr*_x8+_cr*_y9+_y5'), - this.close() - ].join(''); - } - case 'circle':{ - rect(); - return t.pie?[ - this.moveTo('_x6='+x+'+'+'(_x5=0.5*('+w+'))','_y6='+y+'+'+'(_y5=0.5*('+h+'))'), - this.ellipse('_x6','_y6','_x5','_y5',gx(t,'','range','' ),gy(t,'','range','' ) ), - this.close()].join(''):[ - this.ellipse(x+'+'+'(_x5=0.5*('+w+'))',y+'+'+'(_y5=0.5*('+h+'))', - '_x5','_y5',gx(t,'','range','' ),gy(t,'','range','' ) ), - this.close()].join(''); - }break; - case 'polygon':{ - if(t.frames){ - - }else{ - return [ - "_x3=((_x2=",gy(t,"","range","","2*p"), - ")-(_x1=",gx(t,'','range','','0'),"))/(",t.steps||10,");v=_x1;", - this.moveTo("(_x4="+x+")+__sin(_x1)*(_x5="+w+")", - "(_y4="+y+")+__cos(_x1)*(_y5="+h+")"), - "for(v=_x1+_x3;v<_x2;v+=_x3){", - this.lineTo("_x4+__sin(_x1)*_x5", - "_y4+__cos(_x1)*_y5"), - "}", - this.close() - ].join(''); - } - }break; - case 'math':{ - if(t.frames){ - // expand shape - }else{ - rect(); - return [ - "_x7=((_x6=",gy(t,"","range","","2*p"), - ")-(_x5=",gx(t,'','range','','0'),"))/(",t.steps||10,");v=_x5;", - this.moveTo("(_x8="+x+")+"+gx(t,"(","path",")","0")+"*(_x9="+w+")", - "(_y8="+y+")+"+gy(t,"(","path",")","0")+"*(_y9="+h+")"), - "for(v=_x5+_x7;v<_x6;v+=_x7){", - this.lineTo("_x8"+gx(t,"+(","path",")*_x9"), - "_y8"+gy(t,"+(","path",")*_y9")), - "}", - this.close() - ].join(''); - } - }break; - } - return ''; - }, - - $endDraw : function() { - if(this.mousemode){ - return this.$endMouse(); - } - if(this.statemode){ - return this.$endState(); - } - var t = this.style; - if(t){ - if(t.isshape) - return this.$endShape(); - if(t.isfont) - return this.$endFont(); - } - return ''; - }, - - //---------------------------------------------------------------------- - - // HTML Text output - - //---------------------------------------------------------------------- - - - // generic htmlText - beginFont: function( style, needed, ml,mt,mr,mb ) { - if(!style || needed===undefined)return -1; - var l = this.l, html = l._htmljoin, s=[this.$endDraw()]; - this.style = style; - style._id = l._styles.push(style)-1; - - ml = ml!==undefined?ml:0; - mt = mt!==undefined?mt:0; - mr = mr!==undefined?mr:0; - mb = mb!==undefined?mb:0; - this.mx = ml?"-"+(ml*l.ds):""; - this.my = mt?"-"+(mt*l.ds):""; - // find a suitable same-styled other text so we minimize the textdivs - /* - for(i = l._styles.length-2;i>=0;i--){ - if(!l._styles[i]._prev && - jpf.draw.equalStyle( l._styles[i], style )){ - style._prev = i; - break; - } - } - if(style._prev===undefined){*/ - style._txtdiv = ["<div style='", - (style.vertical)? - "filter: flipv() fliph(); writing-mode: tb-rl;":"", - "position:absolute;cursor:default;overflow:hidden;left:0;top:0;display:none;font-family:", - style.family, ";color:",style.color,";font-weight:", - style.weight,";",";font-size:",style.size,"px;", - (style.line!==undefined)?"border:1px solid "+style.line+";" : "", - (style.fill!==undefined)?"background:"+style.fill+";" : "", - - (style.width!==undefined)?"width:"+style.width+"px;" : "", - (style.height!==undefined)?"height:"+style.height+"px;" : "", - (style.style!==undefined)?"font-style:"+style.style+";" : "", - (style.align!==undefined)?"text-align:"+style.align+";" : "", - "'>-</div>"].join(''); - html.push("<div onmousedown='return false' style='cursor:default;position:absolute;left:",ml,"px;top:",mt, - "px;width:",l.width-(mr+ml),"px;height:",l.height-(mb+mt), - "px;overflow:hidden;'></div>"); - - s.push( "_s=_styles[",style._id,"],_tn=_s._txtnodes,_tc = 0;\n"); - /*} else { - if(this.last !== style._prev) - s.push("_s=_styles[",style._prev, - "],_tn=_s._txtnodes,_tc = _s._txtcount;\n"); - }*/ - s.push("if((_l=(",needed, - ")) > _tn.length-_tc)jpf.draw.$allocText(_s,_l);"); - return s.join(''); - }, - - text : function( x, y, text) { - var t = ((this.l.ds>1)?"/"+this.l.ds:""); - return ["if( (_t=_tn[_tc++]).s!=(_v=",text,") )_t.v.nodeValue=_t.s=_v;", - "if(_t.x!=(_v=__round(",x,")))_t.n.style.left=_t.x=((_v", - this.mx,")",t,")+'px'", - ";if(_t.y!=(_v=__round(",y,")))_t.n.style.top=_t.y=((_v", - this.my,")",t,")+'px';\n" - ].join(''); - - }, - - - $allocText : function(style, needed){ - var t, tn = style._txtnode, ts = style._txtnodes; - if(!ts.length)tn.innerHTML = Array(needed+1).join(style._txtdiv); - else tn.insertAdjacentHTML('beforeend',Array(needed+1). - join(style._txtdiv)); - while(needed-->0){ - t=tn.childNodes[ts.length]; - ts.push({ n: t, v: t.firstChild,x:0,y:0,s:null}); - } - }, - - $endFont : function(){ - this.last = this.style._id; - this.style = 0; - this.mx="",this.my=""; - return "_s._txtcount = _tc;"; - }, - - $finalizeFont : function(style) { - var s=["if((_lc=(_s=_styles[",style._id,"])._txtused)>", - "(_tc=_s._txtcount)){_tn=_s._txtnodes;", - "for(;_lc>_tc;)_tn[--_lc].n.style.display='none';", - "_s._txtused=_tc;", - "} else if(_lc<_tc) {_tn=_s._txtnodes;", - "for(;_lc<_tc;)_tn[_lc++].n.style.display='block';", - "_s._txtused=_tc;", - "}\n"]; - var v = style._txtnodes = []; - style._txtused = 0; - style._txtcount = 0; - return s.join(''); - }, - - - colors : { - aliceblue:'#f0f8ff',antiquewhite:'#faebd7',aqua:'#00ffff', - aquamarine:'#7fffd4',azure:'#f0ffff',beige:'#f5f5dc',bisque:'#ffe4c4', - black:'#000000',blanchedalmond:'#ffebcd',blue:'#0000ff', - blueviolet:'#8a2be2',brown:'#a52a2a',burlywood:'#deb887', - cadetblue:'#5f9ea0',chartreuse:'#7fff00',chocolate:'#d2691e', - coral:'#ff7f50',cornflowerblue:'#6495ed',cornsilk:'#fff8dc', - crimson:'#dc143c',cyan:'#00ffff',darkblue:'#00008b',darkcyan:'#008b8b', - darkgoldenrod:'#b8860b',darkgray:'#a9a9a9',darkgrey:'#a9a9a9', - darkgreen:'#006400',darkkhaki:'#bdb76b',darkmagenta:'#8b008b', - darkolivegreen:'#556b2f',darkorange:'#ff8c00',darkorchid:'#9932cc', - darkred:'#8b0000',darksalmon:'#e9967a',darkseagreen:'#8fbc8f', - darkslateblue:'#483d8b',darkslategray:'#2f4f4f', - darkslategrey:'#2f4f4f',darkturquoise:'#00ced1',darkviolet:'#9400d3', - deeppink:'#ff1493',deepskyblue:'#00bfff',dimgray:'#696969', - dimgrey:'#696969',dodgerblue:'#1e90ff',firebrick:'#b22222', - floralwhite:'#fffaf0',forestgreen:'#228b22',fuchsia:'#ff00ff', - gainsboro:'#dcdcdc',ghostwhite:'#f8f8ff',gold:'#ffd700', - goldenrod:'#daa520',gray:'#808080',grey:'#808080',green:'#008000', - greenyellow:'#adff2f',honeydew:'#f0fff0',hotpink:'#ff69b4', - indianred:'#cd5c5c',indigo:'#4b0082',ivory:'#fffff0',khaki:'#f0e68c', - lavender:'#e6e6fa',lavenderblush:'#fff0f5',lawngreen:'#7cfc00', - lemonchiffon:'#fffacd',lightblue:'#add8e6',lightcoral:'#f08080', - lightcyan:'#e0ffff',lightgoldenrodyellow:'#fafad2',lightgray:'#d3d3d3', - lightgrey:'#d3d3d3',lightgreen:'#90ee90',lightpink:'#ffb6c1', - lightsalmon:'#ffa07a',lightseagreen:'#20b2aa',lightskyblue:'#87cefa', - lightslategray:'#778899',lightslategrey:'#778899', - lightsteelblue:'#b0c4de',lightyellow:'#ffffe0',lime:'#00ff00', - limegreen:'#32cd32',linen:'#faf0e6',magenta:'#ff00ff',maroon:'#800000', - mediumaquamarine:'#66cdaa',mediumblue:'#0000cd', - mediumorchid:'#ba55d3',mediumpurple:'#9370d8',mediumseagreen:'#3cb371', - mediumslateblue:'#7b68ee',mediumspringgreen:'#00fa9a', - mediumturquoise:'#48d1cc',mediumvioletred:'#c71585', - midnightblue:'#191970',mintcream:'#f5fffa',mistyrose:'#ffe4e1', - moccasin:'#ffe4b5',navajowhite:'#ffdead',navy:'#000080', - oldlace:'#fdf5e6',olive:'#808000',olivedrab:'#6b8e23',orange:'#ffa500', - orangered:'#ff4500',orchid:'#da70d6',palegoldenrod:'#eee8aa', - palegreen:'#98fb98',paleturquoise:'#afeeee',palevioletred:'#d87093', - papayawhip:'#ffefd5',peachpuff:'#ffdab9',peru:'#cd853f',pink:'#ffc0cb', - plum:'#dda0dd',powderblue:'#b0e0e6',purple:'#800080',red:'#ff0000', - rosybrown:'#bc8f8f',royalblue:'#4169e1',saddlebrown:'#8b4513', - salmon:'#fa8072',sandybrown:'#f4a460',seagreen:'#2e8b57', - seashell:'#fff5ee',sienna:'#a0522d',silver:'#c0c0c0',skyblue:'#87ceeb', - slateblue:'#6a5acd',slategray:'#708090',slategrey:'#708090', - snow:'#fffafa',springgreen:'#00ff7f',steelblue:'#4682b4',tan:'#d2b48c', - teal:'#008080',thistle:'#d8bfd8',tomato:'#ff6347',turquoise:'#40e0d0', - violet:'#ee82ee',wheat:'#f5deb3',white:'#ffffff',whitesmoke:'#f5f5f5', - yellow:'#ffff00',yellowgreen:'#9acd32' - } -}; - -/*FILEHEAD(/var/lib/jpf/src/core/lib/resize.js)SIZE(-1077090856)TIME(1228835494)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * This abstraction is using for resizing block elements. Resizing is allowed
- * with square elements in vertical, horizontal or both planes. Symmetric
- * resizing is possible with SHIFT button.
- *
- * @attribute {Object} scales
- * Properties:
- * {Boolean} scalex resizing in horizontal plane, default is true
- * Possible values:
- * true resizing in horizontal plane is allowed
- * false resizing in horizontal plane is not allowed
- * {Boolean} scaley resizing in vertical plane, default is true
- * Possible values:
- * true resizing in vertical plane is allowed
- * false resizing in vertical plane is not allowed
- * {Boolean} scaleratio resizing in horizontal or vertical plane only is not allowed. Resizing in two dimensions plane at the same time is allowed.
- * Possible values:
- * true resizing in two dimensions plane at the same time is allowed
- * false Resizing in two dimensions plane at the same time is not allowed
- * {Number} dwidth the minimal horizontal size of Block element, default is 56 pixels
- * {Number} dheight the minimal vertical size of Block element, default is 56 pixels
- * @attribute {HTMLElement} htmlElement html representation of resized block element
- * @attribute {Object} squares store object representations of inputs elements
- *
- * @default_private
- * @constructor
- *
- * @author Lukasz Lipinski
- * @version %I%, %G%
- * @since 1.0
- * @namespace jpf
- */
-
-jpf.resize = function() {
- this.scales = {
- scalex : false,
- scaley : false,
- scaleratio: false,
- dwidth : 0,
- dheight : 0
- };
-
- this.htmlElement;
-
- var squares = [];
-
- this.init = function() {
- squares = [
- new jpf.resize.square("top", "left", this),
- new jpf.resize.square("top", "middle", this),
- new jpf.resize.square("top", "right", this),
- new jpf.resize.square("middle", "left", this),
- new jpf.resize.square("middle", "right", this),
- new jpf.resize.square("bottom", "left", this),
- new jpf.resize.square("bottom", "middle", this),
- new jpf.resize.square("bottom", "right", this)];
- };
-
- this.grab = function(oHtml, scales) {
- this.htmlElement = oHtml;
- this.scales = scales;
-
- if (!squares.length)
- this.init();
- this.show();
- };
-
- this.hide = function() {
- for (var i = 0, l = squares.length; i < l; i++) {
- squares[i].visible = false;
- squares[i].repaint();
- }
- };
-
- this.show = function() {
- var sx = this.scales.scalex;
- var sy = this.scales.scaley;
- var sr = this.scales.scaleratio;
-
- /*if (!sx && !sy && !sr)
- return;*/
-
- for (var i = 0, l = squares.length, s; i < l; i++) {
- s = squares[i];
- s.visible = sx && sy
- ? true
- : (sy && !sx
- ? (s.posX == "middle"
- ? true
- : false)
- : (sx && !sy
- ? (s.posY == "middle"
- ? true
- : false)
- : (sr
- ? ((s.posY == "top" || s.posY == "bottom")
- && s.posX !== "middle"
- ? true
- : false)
- : false)));
- s.repaint();
- }
- };
-
- this.destroy = function(){
- for (var i = 0; i < squares.length; i++) {
- squares[i].destroy();
- }
- };
-};
-
-/**
- * Creates html and object representation for square element. Square is used for
- * resizing block elements.
- *
- * @param {String} posY square vertical align relative to resized block element
- * Possible values:
- * top square is on top of resized block element
- * middle square is in the middle of the resized block element
- * bottom square is on the bottom of resized block element
- * @param {String} posX square vertical align relative to resized block element
- * Possible values:
- * left square is on the left of resized block element
- * middle square is in the middle of the resized block element
- * right square is on the right of resized block element
- * @param {Object} objResize resize class constructor
- * @constructor
- */
-jpf.resize.square = function(posY, posX, objResize) {
- this.visible = true;
- this.posX = posX;
- this.posY = posY;
-
- var margin = 0;
- var _self = this;
-
- this.htmlElement = objResize.htmlElement.parentNode.appendChild(document.createElement('div'));
- jpf.setStyleClass(this.htmlElement, "square");
-
- this.repaint = function() {
- if (this.visible) {
- var block = objResize.htmlElement;
- this.htmlElement.style.display = "block";
-
- var bw = parseInt(block.style.width) + jpf.getDiff(block)[0];
- var bh = parseInt(block.style.height) + jpf.getDiff(block)[1];
- var bt = parseInt(block.style.top);
- var bl = parseInt(block.style.left);
-
- var sw = this.htmlElement.offsetWidth;
- var sh = this.htmlElement.offsetHeight;
-
- var t = posY == "top"
- ? bt - margin - sh
- : posY == "middle"
- ? bt + bh/2 - sh/2
- : bt + bh + margin;
- var l = posX == "left"
- ? bl - margin - sw
- : posX == "middle"
- ? bl + bw/2 - sw/2
- : bl + bw + margin;
-
- var c = (posY == "middle"
- ? "w-resize"
- : (posX == "middle"
- ? "n-resize"
- : (posY + posX == "topleft"
- || posY + posX == "bottomright")
- ? "nw-resize"
- : "ne-resize"));
-
- this.htmlElement.style.top = (t - 1) + "px";
- this.htmlElement.style.left = (l - 1) + "px";
- this.htmlElement.style.cursor = c;
- }
- else {
- //IE bug
- var sw = this.htmlElement.offsetWidth;
- this.htmlElement.style.display = 'none';
- }
- };
-
- this.destroy = function(){
- jpf.removeNode(this.htmlElement);
- };
-
- /* Events */
- this.htmlElement.onmouseover = function(e) {
- jpf.setStyleClass(_self.htmlElement, "squareHover");
- };
-
- this.htmlElement.onmouseout = function(e) {
- jpf.setStyleClass(_self.htmlElement, "", ["squareHover"]);
- };
-
- this.htmlElement.onmousedown = function(e) {
- e = (e || event);
-
- var block = objResize.htmlElement,
-
- sx = e.clientX,
- sy = e.clientY,
-
- pt = block.parentNode.offsetTop,
- pl = block.parentNode.offsetLeft,
-
- dw = objResize.scales.dwidth,
- dh = objResize.scales.dheight,
-
- objBlock = jpf.flow.isBlock(block),
- r = objBlock.other.ratio,
-
- posX = _self.posX,
- posY = _self.posY,
-
- width, height, top, left, dx, dy,
- prev_w, prev_h,
-
- l = parseInt(block.style.left),
- t = parseInt(block.style.top),
- w = parseInt(block.style.width),
- h = parseInt(block.style.height),
- resized = false;
-
- if (e.preventDefault) {
- e.preventDefault();
- }
-
- document.onmousemove = function(e) {
- e = (e || event);
-
- dx = e.clientX - sx;
- dy = e.clientY - sy;
- var shiftKey = e.shiftKey,
- proportion = r;
-
- if (shiftKey) {
- if (posX == "right" && posY == "bottom") {
- width = w + dx;
- height = width/proportion;
- left = l;
- top = t;
- }
- else if (posX == "right" && posY == "top") {
- width = w + dx;
- height = width/proportion;
- left = l;
- top = t - dx/proportion;
- }
- else if (posX == "left" && posY == "bottom") {
- width = w - dx;
- height = width/proportion;
- left = l + dx;
- top = t;
- }
- else if (posX == "left" && posY == "top") {
- width = w - dx;
- height = width/proportion;
- left = l + dx;
- top = t + dx/proportion;
- }
-
- /* Keep minimal size */
- if(width >= dw && height >= dh) {
- width = prev_w = Math.max(dw, width);
- height = prev_h = Math.max(dh, height);
- }
- else {
- width = prev_w;
- height = prev_h;
- return false;
- }
- }
- else {
- width = posX == "right"
- ? w + dx
- : (posX == "left"
- ? w - dx
- : w);
- height = posY == "bottom"
- ? h + dy
- : (posY == "top"
- ? h - dy
- : h);
- left = posX == "right"
- ? l
- : (posX == "left"
- ? Math.min(l + w - dw, l + dx)
- : l);
- top = posY == "bottom"
- ? t
- : (posY == "top"
- ? Math.min(t + h - dh, t + dy)
- : t);
-
- /* Keep minimal size */
- width = Math.max(dw, width);
- height = Math.max(dh, height);
- }
-
- if(objResize.onresize) {
- objResize.onresize(block, top, left, width, height);
- }
-
- objResize.show();
-
- resized = true;
- };
-
- document.onmouseup = function(e) {
- document.onmousemove = null;
- if (objResize.onresizedone) {
- if(resized) {
- objResize.onresizedone(width, height, top, left);
- objBlock.other.ratio = width / height;
- resized = false;
- }
- }
- };
- };
-}
-
- -/*FILEHEAD(/var/lib/jpf/src/core/lib/sort.js)SIZE(-1077090856)TIME(1238933677)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -/** - * Object handling sorting in a similar way as xslt. - * - * @constructor - * @todo use a struct instead of lots of local variables, and stop using eval - * - * @author Ruben Daniels - * @version %I%, %G% - * @since 0.8 - * - * @private - */ -jpf.Sort = function(xmlNode){ - var settings = {}; - //order, xpath, type, method, getNodes, dateFormat, dateReplace, sort_dateFmtStr, getValue; - - //use this function to parse the traverse node - this.parseXml = function(xmlNode, clear){ - if (clear) settings = {}; - - settings.order = xmlNode.getAttribute("order"); - settings.xpath = xmlNode.getAttribute("sort"); - settings.getNodes = self[xmlNode.getAttribute("nodes-method")]; - settings.getValue = function(item){ - return jpf.getXmlValue(item, settings.xpath); - } - - settings.ascending = (settings.order || "").indexOf("desc") == -1; - settings.order = null; - - if (xmlNode.getAttribute("data-type")) - settings.method = sort_methods[xmlNode.getAttribute("data-type")]; - else if (xmlNode.getAttribute("sort-method")) { - settings.method = self[xmlNode.getAttribute("sort-method")]; - - if (!settings.method) { - throw new Error(jpf.formatErrorString(0, null, - "Sorting nodes", - "Invalid or missing sort function name provided '" - + xmlNode.getAttribute("sort-method") + "'", xmlNode)); - } - } - else - settings.method = sort_methods["alpha"]; - - var str = xmlNode.getAttribute("date-format"); - if (str) { - settings.sort_dateFmtStr = str; - settings.method = sort_methods["date"]; - var result = str.match(/(D+|Y+|M+|h+|m+|s+)/g); - if (result) { - for (var pos = {}, i = 0; i < result.length; i++) - pos[result[i].substr(0, 1)] = i + 1; - settings.dateFormat = new RegExp(str.replace(/([^\sDYMhms])/g, '\\$1') - .replace(/YYYY/, "(\\d\\d\\d\\d)") - .replace(/(DD|YY|MM|hh|mm|ss)/g, "(\\d\\d)")); - settings.dateReplace = "$" + pos["M"] + "/$" + pos["D"] + "/$" + pos["Y"]; - if (pos["h"]) - settings.dateReplace += " $" + pos["h"] + ":$" + pos["m"] + ":$" + pos["s"]; - } - } - }; - - this.set = function(struct, clear){ - if (clear) settings = {}; - - jpf.extend(settings, struct); - - if (struct.order && !settings.ascending) - settings.ascending = struct.order.indexOf("desc") == -1; - - settings.order = null; - - if (struct["type"]) - settings.method = sort_methods[struct["type"]]; - else if (struct["method"]) - settings.method = self[struct["method"]]; - else if (!settings.method) - settings.method = sort_methods["alpha"]; - - if (!settings.getValue) { - settings.getValue = function(item){ - return jpf.getXmlValue(item, settings.xpath); - } - } - }; - - this.get = function(){ - return jpf.extend({}, settings); - }; - - //use this function in __xmlUpdate [this function isnt done yet] - this.findSortSibling = function(pNode, xmlNode){ - var nodes = getNodes ? getNodes(pNode, xmlNode) : this.getTraverseNodes(pNode); - - for (var i = 0; i < nodes.length; i++) - if (!compare(xmlNode, nodes[i], true, sortSettings)) - return nodes[i]; - - return null; - }; - - // Sorting methods for sort() - var sort_intmask = ["", "0", "00", "000", "0000", "00000", "000000", - "0000000", "00000000", "000000000", "0000000000", "00000000000", - "000000000000", "0000000000000", "00000000000000"]; - var sort_methods = { - "alpha" : function (n){ - return n.toString().toLowerCase() - }, - - "number" : function (t){ - return (t.length < sort_intmask.length - ? sort_intmask[sort_intmask.length - t.length] - : "") + t; - }, - - "date" : function (t, args){ - var sort_dateFormat = settings.dateFormat; - var sort_dateReplace = settings.dateReplace; - var sort_dateFmtStr = settings.sort_dateFmtStr; - - if (!sort_dateFormat || (args && sort_dateFmtStr != args[0])) - sort_dateFmt(args ? args[0] : "*"); - - var d; - if (sort_dateFmtStr == '*') - d = Date.parse(t); - else - d = (new Date(t.replace(sort_dateFormat, sort_dateReplace))).getTime(); - t = "" + parseInt(d); - if (t == "NaN") - t = "0"; - return (t.length < sort_intmask.length ? sort_intmask[sort_intmask.length - - t.length] : "") + t; - } - }; - - /* - sort(xpath, sort_xpath, sort_alpha, boolDesc, from, len) - jsort(n,f,p,ps,sm,desc,sp,ep) - */ - //var order, xpath, type, method, getNodes, dateFormat, dateReplace, sort_dateFmtStr, getValue; - this.apply = function(n, args, func, start, len){ - var sa = [], i = n.length; - - // build string-sortable list with sort method - while (i--) { - var v = settings.getValue(n[i]); - if (n) - sa[sa.length] = { - toString: function(){ - return this.v; - }, - xmlNode : n[i], - v : (settings.method || sort_methods.alpha)(v || "", args, n[i]) - }; - } - - // sort it - sa.sort(); - - //iterate like foreach - var end = len ? Math.min(sa.length, start + len) : sa.length; - if (!start) - start = 0; - - if (func) { - if (settings.ascending) - for (i = start; i < end; i++) - f(i, end, sa[i].xmlNode, sa[i].v); - else - for (i = end - 1; i >= start; i--) - f(end - i - 1, end, sa[i].xmlNode, sa[i].v); - } - else { - //this could be optimized by reusing n... time it later - var res = []; - if (settings.ascending) - for (i = start; i < end; i++) - res[res.length] = sa[i].xmlNode; - else - for (i = end - 1; i >= start; i--) - res[res.length] = sa[i].xmlNode; - return res; - } - }; - - if (xmlNode) - this.parseXml(xmlNode); -}; - - - -/*FILEHEAD(/var/lib/jpf/src/core/lib/auth.js)SIZE(-1077090856)TIME(1238944816)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * @define auth
- * Centralized authentication handling. Not being logged in, after being
- * offline for a while can put the application
- * in a complex undefined state. The auth element makes sure the state is always
- * properly managed. When it gets signalled 'authentication required' it dispatches the
- * appropriate events to display a login box. It can automatically retry logging
- * in to one or more services using in memory stored username/password
- * combinations. it will queue all requests that require authentication until
- * we're logged in again and will then empty the queue.
- * Example:
- * <code>
- * <j:appsettings>
- * <j:auth>
- * <j:service name = "my-backend"
- * login = "rpc:comm.login(username, password)"
- * logout = "rpc:comm.logout()" />
- * <j:service name = "my-jabber-server"
- * login = "xmpp:login(username, password, domain)"
- * logout = "xmpp:logout()" />
- * </j:auth>
- * </j:appsettings>
- * </code>
- * Example:
- * A login window with different states managed by j:auth
- * <code>
- * <j:appsettings>
- * <j:auth login = "xmpp:login(username, password)"
- * logout = "xmpp:logout()"
- * autostart = "true"
- * window = "winLogin"
- * fail-state = "stFail"
- * error-state = "stError"
- * login-state = "stIdle"
- * waiting-state = "stLoggingIn" />
- * </j:appsettings>
- *
- * <j:state-group
- * loginMsg.visible = "false"
- * winLogin.disabled = "false">
- * <j:state id="stFail"
- * loginMsg.value = "Username or password incorrect"
- * loginMsg.visible = "true" />
- * <j:state id="stError"
- * loginMsg.value = "An error has occurred. Please check your network."
- * loginMsg.visible = "true" />
- * <j:state id="stLoggingIn"
- * loginMsg.value = "Please wait whilst logging in..."
- * loginMsg.visible = "true"
- * winLogin.disabled = "true" />
- * <j:state id="stIdle" />
- * </j:state-group>
- *
- * <j:window id="winLogin">
- * <j:label>Username</j:label>
- * <j:textbox type="username" />
- *
- * <j:label>Password</j:label>
- * <j:textbox type="password" />
- *
- * <j:text id="loginMsg" />
- * <j:button action="login">Log in</j:button>
- * </j:window>
- * </code>
- *
- * @event beforelogin Fires before the log in request is sent to the service
- * cancellable: Prevents the log in from happening
- * @event beforelogout Fires before the log out request is sent to the service
- * cancellable: Prevents the log out from happening
- * @event logincheck Fires when log in data is received. Login is sometimes very complex, this event is dispatched to allow a custom check if a log in succeeded.
- * bubbles: yes
- * object:
- * {Object} data the data received from the log in request
- * {Number} state the return code of the log in request
- * @event loginfail Fires when a log in attempt has failed
- * @event loginsuccess Fires when a log in attempt succeeded
- * @event logoutcheck Fires when log out data is received. Login is sometimes very complex, this event is dispatched to allow a custom check if a log out succeeded.
- * bubbles: yes
- * object:
- * {Object} data the data received from the log out request
- * {Number} state the return code of the log out request
- * @event logoutfail Fires when a log out attempt has failed
- * @event logoutsuccess Fires when a log out attempt succeeded
- * @event authrequired Fires when log in credentials are required, either because they are incorrect, or because they are unavailable.
- * bubbles: yes
- *
- * @attribute {String} login the datainstruction on how to log in to a service.
- * @attribute {String} logout the datainstruction on how to log out of a service.
- * @attribute {Boolean} autostart whether to fire authrequired at startup.
- * @attribute {String} window the id of the window element that offers a log in form to the user.
- * @attribute {String} fail-state the id of the state element which is activated when logging in failed because the credentials where incorrect.
- * @attribute {String} error-state the id of the state element which is activated when logging in failed because of an error (i.e. network disconnected).
- * @attribute {String} login-state the id of the state element which is activated when logging in succeeded.
- * @attribute {String} waiting-state the id of the state element which is activated when the user is waiting while the application is logging in.
- * @attribute {String} logout-state the id of the state element which is activated when the user is logged out.
- * @attribute {String} model the id of the model element which gets the data loaded given at login success.
- * @allowchild service
- * @define service Element specifying a server to log into.
- * @attribute {String} name the unique identifier of the service
- * @attribute {String} login the datainstruction on how to log in to a service
- * @attribute {String} logout the datainstruction on how to log out of a service
- * @see element.auth
- *
- * @default_private
- */
-jpf.auth = {
- services : {},
- cache : {},
- retry : true,
- queue : [],
- loggedIn : false,
- needsLogin : false,
- autoStart : true,
-
- /**
- * Indicates the state of the log in process.
- * Possible values:
- * 0 idle
- * 1 logging in
- * 2 logging out
- * @private
- */
- inProcess : 0,
-
- init : function(jml){
- jpf.makeClass(this);
-
- this.inited = true;
- if (!jml)
- return;
-
- this.$jml = jml;
- if (jml.getAttribute("login")) {
- this.services["default"] = jml;
- this.needsLogin = true;
- }
-
- if (jml.getAttribute("retry"))
- this.retry = jpf.isTrue(jml.getAttribute("retry"));
-
- if (jml.getAttribute("autostart"))
- this.autoStart = jpf.isTrue(jml.getAttribute("autostart"));
-
- //Handling
- var loginWindow = jml.getAttribute("window");
- var waitingState = jml.getAttribute("waiting-state");
- var loginState = jml.getAttribute("login-state");
- var failState = jml.getAttribute("fail-state");
- var errorState = jml.getAttribute("error-state");
- var logoutState = jml.getAttribute("logout-state");
- var modelLogin = jml.getAttribute("model");
-
- if (loginWindow || loginState || failState || logoutState) {
- this.addEventListener("authrequired", function(){
- if (loginWindow) {
- var win = self[loginWindow];
- if (win) {
- win.show();
- return false;
- }
- }
- });
-
- this.addEventListener("beforelogin", function(){
- if (waitingState) {
- var state = self[waitingState];
- if (state) state.activate();
- }
- });
-
- function failFunction(e){
- var st = (e.state == jpf.TIMEOUT
- ? errorState
- : failState) || failState
-
- if (st) {
- var state = self[st];
- if (state) {
- state.activate();
- return false;
- }
- }
- }
- this.addEventListener("loginfail", failFunction);
- this.addEventListener("logoutfail", failFunction);
-
- this.addEventListener("logoutsuccess", function(){
- if (logoutState) {
- var state = self[logoutState];
- if (state) state.activate();
- }
- });
-
- this.addEventListener("loginsuccess", function(e){
- if (loginWindow) {
- var win = self[loginWindow];
- if (win) win.hide();
- }
-
- if (loginState) {
- var state = self[loginState];
- if (state) state.activate();
- }
-
- if (e.data && modelLogin) {
- var model = jpf.nameserver.get("model", modelLogin);
- if (model) model.load(e.data);
- }
- });
- }
-
- var i, nodes = jml.childNodes;
- for (i = 0; i < nodes.length; i++) {
- if(nodes[i].nodeType != 1)
- continue;
-
- if (!nodes[i].getAttribute("name")) {
- throw new Error(jpf.formatErrorString(0, this, "Parsing \
- login settings", "Invalid format for the service tag, \
- missing name attribute: <j:service name='' />", nodes[i]));
- }
-
- this.services[nodes[i].getAttribute("name")] = nodes[i];
- this.needsLogin = true;
- }
-
- //Events
- var attr = jml.attributes;
- for (i = 0; i < attr.length; i++) {
- if (attr[i].nodeName.substr(0,2) == "on")
- this.addEventListener(attr[i].nodeName,
- new Function(attr[i].nodeValue));
- }
-
- if (this.autoStart) {
- jpf.addEventListener("load", function(){
- jpf.auth.authRequired();
- });
- }
- },
-
- /**
- * Log in to one or more services
- * @param {String} username the username portion of the credentials used to log in with
- * @param {String} password the password portion of the credentials used to log in with
- * @param {Function} [callback] code to be called when the application succeeds or fails logging in
- * @param {Object} [options] extra settings and variables for the login. These variables will be available in the datainstruction which is called to execute the actual log in.
- * Properties:
- * {Array} services a list of names of services to be logged in to
- * {String} service the name of a single service to log in to
- */
- login : function(username, password, callback, options){
- if (!options) options = {};
-
- options.username = username;
- options.password = password;
-
- if (this.dispatchEvent("beforelogin", options) === false)
- return false;
-
- this.inProcess = 1; //Logging in
-
- var pos = 0, len = 0;
- var doneCallback = function (){
- if (len != ++pos)
- return;
-
- jpf.auth.inProcess = 0; //Idle
- jpf.auth.loggedIn = true;
- jpf.auth.clearQueue();
-
- if (callback)
- callback();
- }
-
- if (!options.service) {
- var s = options.services || this.services;
- for (var name in s) {
- len++;
- this.$do(name, options, "in", null, doneCallback);
- }
- }
- else if (options.service) {
- len = 1;
- this.$do(options.service, options, "in", null, doneCallback);
- }
- },
-
- relogin : function(){
- if (this.dispatchEvent("beforerelogin") === false)
- return false;
-
- jpf.console.info("Retrying login...", "auth");
-
- //@todo shouldn't I be using inProces here?
-
- var pos = 0, len = 0;
- var doneCallback = function (){
- if (len != ++pos)
- return;
-
- jpf.auth.inProcess = 0; //Idle
- jpf.auth.loggedIn = true;
- jpf.auth.clearQueue();
- }
-
- for (var name in this.services) {
- if (!this.cache[name])
- return false;
- len++;
- this.$do(name, this.cache[name], "in", true, doneCallback);
- }
-
- return true;
- },
-
- $do : function(service, options, type, isRelogin, callback){
- var xmlNode = this.services[service];
- var _self = options.userdata = this;
-
- options.ignoreOffline = true; //We don't want to be cached by jpf.offline
-
- jpf.console.info("Logging " + type + " on service '"
- + service + "'", "auth");
-
- //Execute login call
- jpf.saveData(xmlNode.getAttribute("log" + type), null, options,
- function(data, state, extra){
- if (state == jpf.TIMEOUT && extra.retries < jpf.maxHttpRetries)
- return extra.tpModule.retry(extra.id);
-
- /*
- Login is sometimes very complex, so this check is
- here to test the data for login information
- */
- var result = _self.dispatchEvent("log" + type + "check",
- jpf.extend({
- state : state,
- data : data,
- bubbles : true
- }, extra));
-
- var loginFailed = typeof result == "boolean"
- ? !result
- : !(state == jpf.SUCCESS || type == "out" && extra.http.status == 401);
-
- if (loginFailed) {
- jpf.auth.inProcess = 0; //Idle
-
- if (isRelogin) //If we're retrying then we'll step out here
- return _self.authRequired();
-
- jpf.console.info("Log " + type + " failure for service '"
- + service + "'", "auth");
-
- var commError = new Error(jpf.formatErrorString(0, null,
- "Logging " + type, "Error logging in: " + extra.message));
-
- if (_self.dispatchEvent("log" + type + "fail", jpf.extend({
- error : commError,
- state : state,
- bubbles : true
- }, extra)) !== false)
- throw commError; //@todo ouch, too harsh?
-
- //@todo Call auth required again??
-
- return;
- }
-
- if (type == "in") {
- //If we use retry, cache the login information
- if (!isRelogin && _self.retry) {
- var cacheItem = {};
- for (var prop in options) {
- if ("object|array".indexOf(typeof options[prop]) == -1)
- cacheItem[prop] = options[prop];
- }
- _self.cache[service || "default"] = cacheItem;
- }
- }
- else {
- //Remove cached credentials
- if (_self.cache[service || "default"])
- _self.cache[service || "default"] = null;
-
- jpf.auth.authRequired();
- }
-
- if (callback)
- callback();
-
- _self.dispatchEvent("log" + type + "success", jpf.extend({
- state : state,
- data : data,
- bubbles : true
- }, extra));
-
- jpf.console.info("Log " + type + " success for service '"
- + service + "'", "auth");
- });
- },
-
- clearQueue : function(){
- if (!this.loggedIn) //Queue should only be cleared when we're logged in
- return;
-
- var queue = this.queue.slice();
- this.queue.length = 0;
-
- for (var i = 0; i < queue.length; i++) {
- var qItem = queue[i];
-
- //We might be logged out somewhere in this process (think sync)
- if (!this.loggedIn) {
- this.queue.push(qItem);
- continue;
- }
-
- //Specialty retry (protocol specific)
- if (qItem.retry)
- qItem.retry.call(qItem.object);
-
- //Standard TelePort Module retry
- else if (qItem.id)
- qItem.tpModule.retry(qItem.id);
-
- //Dunno what's up, lets tell the developer
- else
- jpf.console.warn("Unable to retry queue item after \
- successfull logging in. It seems the protocol that sent \
- the message doesn't allow it.");
- }
-
- //The queue might be filled somehow
- if (this.queue.length)
- this.clearQueue();
- },
-
- /**
- * Log out of one or more services
- * @param {Function} [callback] code to be called when the application succeeds or fails logging out
- * @param {Object} [options] extra settings and variables for the login. These variables will be available out the datainstruction which is called to execute the actual log out.
- * Properties:
- * {Array} services a list of names of services to be logged out of
- * {String} service the name of a single service to log out of
- */
- logout : function(callback, options){
- if (!options) options = {};
-
- if (this.dispatchEvent("beforelogout", options) === false)
- return;
-
- this.loggedIn = false;
-
- if (!options.service) {
- for (var name in this.services) {
- this.$do(name, options, "out", null, callback);
- }
- }
- else if (options.service)
- this.$do(options.service, options, "out", null, callback);
-
- },
-
- /**
- * Signals services that a log in is required and fires authrequired event
- * @param {Object} [options] information on how to reconstruct a failed action, that detected a log in was required. (i.e. When an HTTP call fails with a 401 Auth Required the options object contains information on how to retry the http request)
- */
- authRequired : function(options, forceNoRetry){
- if (!this.inited)
- this.init();
-
- // If we're already logging in return
- if (options && options.userdata == this)
- return;
-
- // If we're supposed to be logged in we'll try to log in automatically
- if (this.loggedIn && !forceNoRetry && this.retry && this.relogin()) {
- var result = false;
- }
- else if (this.inProcess != 1) { //If we're not already logging in
- /*
- Apparently our credentials aren't valid anymore,
- or retry is turned off. If this event returns false
- the developer will call jpf.auth.login() at a later date.
- */
- var result = this.dispatchEvent("authrequired", jpf.extend({
- bubbles : true
- }, options));
- }
-
- this.loggedIn = false;
-
- if (result === false) {
- if (options) //Add communication to queue for later processing
- this.queue.push(options);
-
- return true; //cancels error state in protocol
- }
- }
-};
-
- - -/*FILEHEAD(/var/lib/jpf/src/core/lib/date.js)SIZE(-1077090856)TIME(1238933677)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-// Some common format strings
-jpf.date = {
- masks : {
- "default": "ddd mmm dd yyyy HH:MM:ss",
- shortDate: "m/d/yy",
- mediumDate: "mmm d, yyyy",
- longDate: "mmmm d, yyyy",
- fullDate: "dddd, mmmm d, yyyy",
- shortTime: "h:MM TT",
- mediumTime: "h:MM:ss TT",
- longTime: "h:MM:ss TT Z",
- isoDate: "yyyy-mm-dd",
- isoTime: "HH:MM:ss",
- isoDateTime: "yyyy-mm-dd'T'HH:MM:ss",
- isoUtcDateTime: "UTC:yyyy-mm-dd'T'HH:MM:ss'Z'"
- },
-
- // Internationalization strings
- i18n : {
- dayNames : [
- "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
- "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
- "Friday", "Saturday"
- ],
-
- dayNumbers : {
- "Sun" : 0, "Mon" : 1, "Tue" : 2, "Wed" : 3, "Thu" : 4, "Fri" : 5,
- "Sat" : 6, "Sunday" : 0, "Monday" : 1, "Tuesday" : 2,
- "Wednesday" : 3, "Thursday" : 4, "Friday" : 5, "Saturday" : 6
- },
- monthNames : [
- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
- "January", "February", "March", "April", "May", "June",
- "July", "August", "September", "October", "November", "December"
- ],
- monthNumbers : {
- "Jan" : 0, "Feb" : 1, "Mar" : 2, "Apr" : 3, "May" : 4, "Jun" : 5,
- "Jul" : 6, "Aug" : 7, "Sep" : 8, "Oct" : 9, "Nov" : 10, "Dec" : 11
- }
- }
-};
-
-jpf.date.dateFormat = (function () {
- var token = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g,
- timezone = /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g,
- timezoneClip = /[^-+\dA-Z]/g,
- pad = function (val, len) {
- val = String(val);
- len = len || 2;
- while (val.length < len) val = "0" + val;
- return val;
- };
-
- // Regexes and supporting functions are cached through closure
- return function (date, mask, utc) {
- var dF = jpf.date;
-
- // You can't provide utc if you skip other args (use the "UTC:" mask prefix)
- if (arguments.length == 1 && (typeof date == "string"
- || date instanceof String) && !/\d/.test(date)) {
- mask = date;
- date = undefined;
- }
-
- // Passing date through Date applies Date.parse, if necessary
- date = date ? new Date(date) : new Date();
-
- if (isNaN(date)) throw new SyntaxError("invalid date");
-
- mask = String(dF.masks[mask] || mask || dF.masks["default"]);
-
- // Allow setting the utc argument via the mask
- if (mask.slice(0, 4) == "UTC:") {
- mask = mask.slice(4);
- utc = true;
- }
-
- var _ = utc ? "getUTC" : "get",
- d = date[_ + "Date"](),
- D = date[_ + "Day"](),
- m = date[_ + "Month"](),
- y = date[_ + "FullYear"](),
- H = date[_ + "Hours"](),
- M = date[_ + "Minutes"](),
- s = date[_ + "Seconds"](),
- L = date[_ + "Milliseconds"](),
- o = utc ? 0 : date.getTimezoneOffset(),
- flags = {
- d : d,
- dd : pad(d),
- ddd : dF.i18n.dayNames[D],
- dddd: dF.i18n.dayNames[D + 7],
- m : m + 1,
- mm : pad(m + 1),
- mmm : dF.i18n.monthNames[m],
- mmmm: dF.i18n.monthNames[m + 12],
- yy : String(y).slice(2),
- yyyy: y,
- h : H % 12 || 12,
- hh : pad(H % 12 || 12),
- H : H,
- HH : pad(H),
- M : M,
- MM : pad(M),
- s : s,
- ss : pad(s),
- l : pad(L, 3),
- L : pad(L > 99 ? Math.round(L / 10) : L),
- t : H < 12 ? "a" : "p",
- tt : H < 12 ? "am" : "pm",
- T : H < 12 ? "A" : "P",
- TT : H < 12 ? "AM" : "PM",
- Z : utc
- ? "UTC"
- : (String(date).match(timezone)
- || [""]).pop().replace(timezoneClip, ""),
- o : (o > 0 ? "-" : "+")
- + pad(Math.floor(Math.abs(o) / 60) * 100
- + Math.abs(o) % 60, 4),
- S : ["th", "st", "nd", "rd"]
- [d % 10 > 3 ? 0 : (d % 100 - d % 10 != 10) * d % 10]
- };
-
- return mask.replace(token, function ($0) {
- return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1);
- });
- };
-})();
-
-
-/**
- * Create a object representation of date from datetime string parsing it with
- * datetime format string
- *
- * @param {String} datetime the date and time wrote in allowed format
- * @param {String} format style of displaying date, created using various
- * masks
- * Possible masks:
- * d day of the month as digits, no leading zero for single-digit days
- * dd day of the month as digits, leading zero for single-digit days
- * ddd day of the week as a three-letter abbreviation
- * dddd day of the week as its full name
- * m month as digits, no leading zero for single-digit months
- * mm month as digits, leading zero for single-digit months
- * mmm month as a three-letter abbreviation
- * mmmm month as its full name
- * yy year as last two digits, leading zero for years less than 2010
- * yyyy year represented by four digits
- * h hours, no leading zero for single-digit hours (12-hour clock)
- * hh hours, leading zero for single-digit hours (12-hour clock)
- * H hours, no leading zero for single-digit hours (24-hour clock)
- * HH hours, leading zero for single-digit hours (24-hour clock)
- * M minutes, no leading zero for single-digit minutes
- * MM minutes, leading zero for single-digit minutes
- * s seconds, no leading zero for single-digit seconds
- * ss seconds, leading zero for single-digit seconds
- */
-jpf.date.getDateTime = function(datetime, format) {
- var token = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g;
- var timezone = /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC:)(?:[-+]\d{4})?)\b/g;
- var alteration = 0;
- var time, y = new Date().getFullYear(), m = 1, d = 1,
- h = 12, M = 0, s = 0;
- var i18n = jpf.date.i18n;
-
- if (!format) {
- throw new Error(jpf.formatErrorString(0, null,
- "date-format", "Date format is null"));
- }
-
- format = format.replace(timezone, "");
-
- var str = format.replace(token, function(str, offset, p) {
- var part = datetime.substring(p + alteration, p + alteration + str.length);
-
- switch (str) {
- case 'd':
- case 'm':
- case 'h':
- case 'H':
- case 'M':
- case 's':
- if (!/[\/, :\-](d|m|h|H|M|s)$|^(d|m|h|H|M|s)[\/, :\-]|[\/, :\-](d|m|h|H|M|s)[\/, :\-]/.test(format)) {
- throw new Error(jpf.formatErrorString(0, null,
- "date-format", "Dates without leading zero needs separators"));
- }
-
- var value = parseInt(datetime.substring(p + alteration,
- p + alteration + 2));
-
- if (value.toString().length == 2)
- alteration++;
-
- return str == 'd'
- ? d = value
- : (str == 'm'
- ? m = value
- : (str == 'M'
- ? M = value
- : (str == 's'
- ? s = value
- : h = value)));
- case 'dd':
- return d = part; //01-31
- case 'dddd':
- //changeing alteration because "dddd" have no information about day number
- alteration += i18n.dayNames[i18n.dayNumbers[part.substring(0,3)] + 7].length - 4;
- break;
- case 'mm':
- return m = parseInt(part); //01 - 11
- case 'mmm':
- return m = i18n.monthNumbers[part] + 1;
- case 'mmmm':
- var monthNumber = i18n.monthNumbers[part.substring(0, 3)];
- alteration += i18n.monthNames[monthNumber + 12].length - 4;
- return m = monthNumber + 1;
- case 'yy':
- return y = parseInt(part) < 70 ? "20" + part : part;
- case 'yyyy':
- return y = part;
- case 'hh':
- return h = part;
- case 'HH':
- return h = part;
- case 'MM':
- return M = part;
- case 'ss':
- return s = part;
- case "'T'":
- case "'Z'":
- //because in date we have only T
- alteration -= 2;
- break;
- }
- });
-
- return new Date(y, m-1, d, h, M, s);
-};
-
-// For convenience...
-Date.prototype.format = function (mask, utc) {
- return jpf.date.dateFormat(this, mask, utc);
-};
-
-Date.parse = function (datetime, format) {
- return jpf.date.getDateTime(datetime, format);
-};
- - -/*FILEHEAD(/var/lib/jpf/src/core/lib/draw_vml.js)SIZE(-1077090856)TIME(1238933677)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - -/*FILEHEAD(/var/lib/jpf/src/core/lib/uirecorder.js)SIZE(-1077090856)TIME(1238933677)*/ - -jpf.uirecorder = {
- actionStack : [],
- playStack : [],
- isPlaying : false,
- isRecording : false,
- inited : false,
-
- init : function() {
- if (jpf.uirecorder.inited)
- return;
-
- jpf.uirecorder.inited = true;
-
- /* Support for various events listed in dEvents array */
- /*for (var i = 0, l = dEvents.length; i < l; i++) {
- document.documentElement[dEvents[i]] = function(e) {
- if (jpf.uirecorder.isPlaying || !jpf.uirecorder.isRecording)
- return;
-
- e = e || event;
-
- jpf.uirecorder.actionStack.push([new Date().getTime(), dEvents[i],
- e.srcElement || e.target, jpf.extend({}, e)]);
- }
- }*/
-
- /* Form events support */
- document.documentElement.onselect = function(e) {
- if (jpf.uirecorder.isPlaying || !jpf.uirecorder.isRecording)
- return;
-
- e = e || event;
-
- jpf.uirecorder.actionStack.push([new Date().getTime(), "onselect",
- e.srcElement || e.target, jpf.extend({}, e)]);
- }
-
- document.documentElement.onchange = function(e) {
- if (jpf.uirecorder.isPlaying || !jpf.uirecorder.isRecording)
- return;
-
- e = e || event;
-
- jpf.uirecorder.actionStack.push([new Date().getTime(), "onchange",
- e.srcElement || e.target, jpf.extend({}, e)]);
- }
-
- document.documentElement.onsubmit = function(e) {
- if (jpf.uirecorder.isPlaying || !jpf.uirecorder.isRecording)
- return;
-
- e = e || event;
-
- jpf.uirecorder.actionStack.push([new Date().getTime(), "onsubmit",
- e.srcElement || e.target, jpf.extend({}, e)]);
- }
-
- document.documentElement.onreset = function(e) {
- if (jpf.uirecorder.isPlaying || !jpf.uirecorder.isRecording)
- return;
-
- e = e || event;
-
- jpf.uirecorder.actionStack.push([new Date().getTime(), "onreset",
- e.srcElement || e.target, jpf.extend({}, e)]);
- }
-
- /* User interface events support */
- document.documentElement.onfocus = function(e) {
- if (jpf.uirecorder.isPlaying || !jpf.uirecorder.isRecording)
- return;
-
- e = e || event;
-
- jpf.uirecorder.actionStack.push([new Date().getTime(), "onfocus",
- e.srcElement || e.target, jpf.extend({}, e)]);
- }
-
- document.documentElement.onblur = function(e) {
- if (jpf.uirecorder.isPlaying || !jpf.uirecorder.isRecording)
- return;
-
- e = e || event;
-
- jpf.uirecorder.actionStack.push([new Date().getTime(), "onblur",
- e.srcElement || e.target, jpf.extend({}, e)]);
- }
-
- /* Mouse events support */
- document.documentElement.onclick = function(e) {
- if (jpf.uirecorder.isPlaying || !jpf.uirecorder.isRecording)
- return;
-
- e = e || event;
-//jpf.console.info("recording... onclick - "+e.clientX+" "+e.clientY);
- jpf.uirecorder.actionStack.push([new Date().getTime(), "onclick",
- e.srcElement || e.target, jpf.extend({}, e)]);
- }
-
- document.documentElement.ondblclick = function(e) {
- if (jpf.uirecorder.isPlaying || !jpf.uirecorder.isRecording)
- return;
-
- e = e || event;
-//jpf.console.info("recording... ondblclick - "+e.clientX+" "+e.clientY);
- jpf.uirecorder.actionStack.push([new Date().getTime(), "ondblclick",
- e.srcElement || e.target, jpf.extend({}, e)]);
- }
-
- document.documentElement.onmousedown = function(e) {
- if (jpf.uirecorder.isPlaying || !jpf.uirecorder.isRecording)
- return;
-
- e = e || event;
-//jpf.console.info("recording... onmousedown - "+e.clientX+" "+e.clientY);
- jpf.uirecorder.actionStack.push([new Date().getTime(), "onmousedown",
- e.srcElement || e.target, jpf.extend({}, e)]);
- }
-
- document.documentElement.onmouseup = function(e) {
- if (jpf.uirecorder.isPlaying || !jpf.uirecorder.isRecording)
- return;
-
- e = e || event;
-//jpf.console.info("recording... onmouseup - "+e.clientX+" "+e.clientY);
- jpf.uirecorder.actionStack.push([new Date().getTime(), "onmouseup",
- e.srcElement || e.target, jpf.extend({}, e)]);
- }
-
- document.documentElement.onmousemove = function(e) {
- if (jpf.uirecorder.isPlaying || !jpf.uirecorder.isRecording)
- return;
-
- e = e || event;
-//jpf.console.info("recording... onmousemove - "+e.clientX+" "+e.clientY);
- jpf.uirecorder.actionStack.push([new Date().getTime(), "onmousemove",
- e.srcElement || e.target, jpf.extend({}, e)]);
- }
-
- document.documentElement.onmouseover = function(e) {
- if (jpf.uirecorder.isPlaying || !jpf.uirecorder.isRecording)
- return;
-
- e = e || event;
-//jpf.console.info("recording... onmouseover - "+e.clientX+" "+e.clientY);
- jpf.uirecorder.actionStack.push([new Date().getTime(), "onmouseover",
- e.srcElement || e.target, jpf.extend({}, e)]);
- }
-
- document.documentElement.onmouseout = function(e) {
- if (jpf.uirecorder.isPlaying || !jpf.uirecorder.isRecording)
- return;
-
- e = e || event;
-//jpf.console.info("recording... onmouseout - "+e.clientX+" "+e.clientY);
- jpf.uirecorder.actionStack.push([new Date().getTime(), "onmouseout",
- e.srcElement || e.target, jpf.extend({}, e)]);
- }
-
- /* Keyboard events support for all browsers */
- document.documentElement.onkeyup = function(e) {
- if (jpf.uirecorder.isPlaying || !jpf.uirecorder.isRecording)
- return;
-
- e = e || event;
-
- jpf.uirecorder.actionStack.push([new Date().getTime(), "onkeyup",
- e.srcElement || e.target, jpf.extend({}, e)]);
- }
-
- document.documentElement.onkeydown = function(e) {
- if (jpf.uirecorder.isPlaying || !jpf.uirecorder.isRecording)
- return;
-
- e = e || event;
-
- jpf.uirecorder.actionStack.push([new Date().getTime(), "onkeydown",
- e.srcElement || e.target, jpf.extend({}, e)]);
- }
-
- document.documentElement.onkeypress = function(e) {
- if (jpf.uirecorder.isPlaying || !jpf.uirecorder.isRecording)
- return;
-
- e = e || event;
-
- jpf.uirecorder.actionStack.push([new Date().getTime(), "onkeypress",
- e.srcElement || e.target, jpf.extend({}, e)]);
- }
-
- var mEvents = ["DOMSubtreeModified", "DOMNodeInserted", "DOMNodeRemoved", "DOMNodeRemovedFromDocument",
- "DOMNodeInsertedIntoDocument", "DOMAttrModified", "DOMCharacterDataModified", "DOMActivate"];
-
- /* ============== Mutation Events ============== */
- /* Support for Mutation Events in FF */
- /*if(jpf.isGecko) {
- for (var i = 0, l = mEvents.length; i < l; i++) {
- document.addEventListener(mEvents[i], function(e) {
- if (jpf.uirecorder.isPlaying || !jpf.uirecorder.isRecording)
- return;
-
- e = e || event;
-
- jpf.uirecorder.actionStack.push([new Date().getTime(), mEvents[i], e.srcElement || e.target, jpf.extend({}, e)]);
- }, false);
- }
- }*/
- /* Support for Mutation events in IE */
- /*else if(jpf.isIE) {
- for (var i = 0, l = mEvents.length; i < l; i++) {
- document.attachEvent(mEvents[i], function(e) {
- if (jpf.uirecorder.isPlaying || !jpf.uirecorder.isRecording)
- return;
-
- e = e || event;
-
- jpf.uirecorder.actionStack.push([new Date().getTime(), mEvents[i], e.srcElement || e.target, jpf.extend({}, e)]);
- });
- }
- }*/
-
- /* Support for Mouse Scroll event */
- if(document.addEventListener) {
- /* FF */
- document.addEventListener("DOMMouseScroll", function(e) {
- if (jpf.uirecorder.isPlaying || !jpf.uirecorder.isRecording)
- return;
-
- e = e || event;
-
- /* scropt for checking marginTop */
- /*var el = e.srcElement || e.target;
-
- while (el != document.body && el.scrollHeight == el.offsetHeight) {
- jpf.console.info("Searching..."+el.id+" "+el.scrollHeight+" "+parseInt(el.style.height));
- el = el.parentNode || el.parentElement;
- }
-
- jpf.console.info("scroll"+el.scrollTop);*/
-
- jpf.uirecorder.actionStack.push([
- new Date().getTime(),
- "DOMMouseScroll",
- e.target,
- jpf.extend({}, jpf.uirecorder.createMouseWheelEvent(e))
- ]);
- }, false);
- }
- else {
- /* IE */
- document.onmousewheel = function(e) {
- if (jpf.uirecorder.isPlaying || !jpf.uirecorder.isRecording)
- return;
-
- e = e || event;
-
- jpf.uirecorder.actionStack.push([
- new Date().getTime(),
- "onmousewheel",
- e.srcElement,
- jpf.extend({}, jpf.uirecorder.createMouseWheelEvent(e))
- ]);
- };
- }
- },
-
- /**
- * Checks delta value and creates object to simulate mouse scroll
- *
- * @param {Object} e event object
- */
- createMouseWheelEvent : function(e) {
- var delta = null;
- if (e.wheelDelta) {
- delta = e.wheelDelta / 120;
- if (jpf.isOpera)
- delta *= -1;
- }
- else if (e.detail)
- delta = -e.detail / 3;
-
- return {
- type : jpf.isGecko ? "DOMMouseScroll" : (jpf.isIE ? "mousewheel" : "DOMMouseScroll"),
- delta : delta
- }
- },
-
- /**
- * Initiate user interface recorder and start recording
- */
- record : function() {
- jpf.uirecorder.isRecording = true;
- jpf.uirecorder.init();
- },
-
- /**
- * Stop recording and start playing
- */
- play : function() {
- jpf.uirecorder.isRecording = false;
- jpf.uirecorder.isPlaying = true;
- jpf.uirecorder.playStack = jpf.uirecorder.actionStack.slice(0);
-
- if (jpf.uirecorder.playStack.length)
- playFrame();
- },
-
- /**
- * Stop recording and playing
- */
- stop : function() {
- jpf.uirecorder.isRecording = false;
- jpf.uirecorder.isPlaying = false;
- },
-
- /**
- * Stop recording and playing, clear list of recorded actions
- */
- reset : function() {
- jpf.uirecorder.isRecording = false;
- jpf.uirecorder.isPlaying = false;
- jpf.uirecorder.playStack = [];
- jpf.uirecorder.actionStack = [];
- }
-};
-
-var timeout;
-function playFrame() {
- var frame = jpf.uirecorder.playStack.shift();
-
- if(!frame || !jpf.uirecorder.isPlaying)
- return;
-
- var lastTime = frame[0];
- var simulate = false;
- var src = frame[3], e;
-
- if (jpf.isIE) {
- e = document.createEventObject();
-
- for (prop in frame[3]) {
- if (frame[3][prop]) {
- e[prop] = frame[3][prop];
- }
- }
-
- e.target = frame[2];
-
-
- switch (src.type) {
- case "mousewheel":
- fireScroll(frame);
- break;
- default:
- //jpf.console.info("playing... "+src.type+" - "+src.clientX+" "+src.clientY);
- frame[2].fireEvent(frame[1], e);
- break;
- }
-
- }
- else {
- switch(src.type) {
- case "mousemove":
- case "mouseup":
- case "mousedown":
- case "click":
- case "dblclick":
- case "mouseover":
- case "mouseout":
- e = document.createEvent("MouseEvents");
- e.initMouseEvent(src.type, src.bubbles, src.cancelable, src.view, src.detail, src.screenX,
- src.screenY, src.clientX, src.clientY, src.ctrlKey, src.altKey,
- src.shiftKey, src.metaKey, src.button, src.relatedTarget
- );
- /* Little workaround - that values are important for drag&drop (dragdrop.js) */
- jpf.event.layerX = src.layerX
- jpf.event.layerY = src.layerY
- break;
- case "keyup":
- case "keydown":
- case "keypress":
- e = document.createEvent("KeyboardEvent");
- e.initKeyEvent(src.type, src.bubbles, true, window,
- src.ctrlKey, src.altKey, src.shiftKey, src.metaKey,
- src.keyCode, src.charCode);
- break;
- case "select":
- case "change":
- case "submit":
- case "reset":
- e = document.createEvent("HTMLEvents");
- e.initEvent(src.type, src.bubbles, src.cancelable);
- break;
- case "DOMActivate":
- case "resize":
- case "focus":
- case "blur":
- e = document.createEvent("UIEvents");
- e.initUIEvent(src.type, src.bubbles, src.cancelable, e.view, e.detail);
- break;
- /*case "DOMAttrModified":
- case "DOMCharacterDataModified":
- case "DOMNodeInsertedIntoDocument":
- case "DOMNodeRemovedFromDocument":
- case "DOMNodeRemoved":
- case "DOMNodeInserted":
- case "DOMSubtreeModified":
- e = document.createEvent("MutationEvents");
- e.initMutationEvent(src.type, src.bubbles, src.cancelable, src.relatedNode, src.prevValue, src.newValue, src.attrName, src.attrChange);
- break;*/
- case "DOMMouseScroll": //mouse scroll
- fireScroll(frame);
- simulate = true;
- break;
- default:
- jpf.console.info("default: " + src.type);
- simulate = true;
- break;
- }
-
- if (!simulate) {
- frame[2].dispatchEvent(e);
- }
- }
-
- if (jpf.uirecorder.playStack.length && jpf.uirecorder.isPlaying) {
- timeout = setTimeout(function() {
- playFrame();
- }, jpf.uirecorder.playStack[0][0] - lastTime);
- }
- else {
- jpf.uirecorder.stop();
- clearInterval(timeout);
- }
-};
-
-/**
- * Actually supports only vertical scrolling
- *
- * @param {Object} frame
- */
-function fireScroll(frame) {
- var el = frame[2];
-
- while (el != document.body && el.scrollHeight == el.offsetHeight) {
- el = el.parentNode || el.parentElement;
- }
-
- // FF - 39
- // IE - el.offsetHeight / ~(6,7 - 6,8)
- // Chrome - 120
- el.scrollTop = el.scrollTop - (jpf.isGecko
- ? 39
- : (jpf.isChrome
- ? 120
- : (jpf.isIE
- ? Math.round(el.offsetHeight / 6.73)
- : 20))) * frame[3].delta;
-}
- - -/*FILEHEAD(/var/lib/jpf/src/core/lib/flow.js)SIZE(-1077090856)TIME(1238933677)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -/** - * This abstraction is using for creating block elements which can be move by - * mouse or keyboard, rotate with 90 degrees step, flip horizontal and vertical - * and resize on the fly using mouse. Each block could have inputs defined in - * template file. Inputs allows creating stiff connections between block - * elements. If block haven't inputs, connection is created in most optimal way. - * - * @event onmousedown Fires when mouse button is pressed on document body - * @event onmousemove Fires when mouse cursor is moving over document body - * @event onmouseup Fires when mouse button is hold off over the document body - * - * @attribute {Boolean} ismoved When connection is moving, this attribute is set to true. It gives information to other methods what happends with connection element. - * Possible values: - * true block moves - * false block don't move - * @attribute {Object} objCanvases storage workareas objects, it allows to easy access to them if need be - * @attribute {Object} connectionsTemp when work mode is set to "connection-add", it keeps informations about block and his input from which connection will be created to other block - * @attribute {Object} connectionsManager create connection when connectionsTemp variable is set - * @attribute {Number} sSize define connection line width - * @attrubite {Number} fsSize define size of first and last connection segment - * - * @default_private - * @constructor - * - * @author Lukasz Lipinski - * @version %I%, %G% - * @since 1.0 - * @namespace jpf - */ - -jpf.flow = { - ismoved : false, - objCanvases : {}, - connectionsTemp : null, - connectionsManager : null, - - sSize : 7, - fsSize : 15, - - init : function() { - jpf.flow.connectionsManager = new jpf.flow.connectionsManager; - - document.onmousedown = function(e) { - e = (e || event); - - /* Looking for Block element */ - var target = e.target || e.srcElement; - var isDraged = false; - - if (target.tagName == 'HTML') - return; - while (target != document.body && !jpf.flow.findBlock(target.id)) { - target = target.parentNode || target.parentElement; - } - /* Looking for Block element - End*/ - - var objBlock = jpf.flow.isBlock(target); - - if (!objBlock) - return; - if (!objBlock.draggable) - return; - - var sx = e.clientX, sy = e.clientY, - dx = 0, dy = 0, - l = parseInt(target.style.left), - t = parseInt(target.style.top); - - //objBlock.canvas.htmlElement.scrollLeft = Math.round(l+dx+target.offsetWidth); - - if (e.preventDefault) { - e.preventDefault(); - } - - document.onmousemove = function(e) { - e = (e || event); - - isDraged = true; - - dx = e.clientX - sx; - dy = e.clientY - sy; - - target.style.left = (l + dx) + "px"; - target.style.top = (t + dy) + "px"; - - objBlock.onMove(); - jpf.flow.onblockmove(); - - return false; - } - - document.onmouseup = function(e) { - document.onmousemove = null; - - if(jpf.flow.onaftermove && isDraged) { - jpf.flow.onaftermove(dy, dx); - isDraged = false; - } - } - }; - } -}; - -/** - * This class creates workarea on which possible is work with blocks and - * connections. - * - * @param {HTMLElement} htmlElement the html representation of a workarea - * @constructor - */ -jpf.flow.canvas = function(htmlElement) { - if (!htmlElement.getAttribute("id")) { - jpf.setUniqueHtmlId(htmlElement); - } - - this.id = htmlElement.getAttribute("id"); - this.htmlElement = htmlElement; - - this.htmlBlocks = {}; - this.htmlConnectors = {}; - - this.mode = "normal"; - this.disableremove = false; - - this.initCanvas = function() { - jpf.flow.objCanvases[this.htmlElement.getAttribute("id")] = this; - }; - - this.removeConnector = function(id) { - var c = this.htmlConnectors[id]; - c.htmlElement.parentNode.removeChild(c.htmlElement); - this.htmlConnectors[id] = c = null; - delete this.htmlConnectors[id]; - }; - - this.deselectConnections = function() { - for (var id in this.htmlConnectors) { - var con = this.htmlConnectors[id]; - if (con.selected) { - con.deselect("selected"); - con.deselectInputs("Selected"); - con.selected = false; - } - } - } - - this.setMode = function(mode) { - this.mode = mode; - }; - - this.getMode = function() { - return this.mode; - }; -}; - -/** - * Creates new block object which can be move by mouse or keyboard, rotate - * with 90 degrees step, flip horizontal and vertical and resize on the fly - * using mouse. Each block could have inputs, background picture and minimal - * dimension defined in template file. It's possible to create connections - * between blocks. - * - * @param {HTMLElement} htmlElement the html representation of block - * @param {Object} objCanvas object representation of workarea (canvas) element - * @param {Object} other the properties of the block element - * Properties: - * {Boolean} lock prohibit block move, default is false - * Possible values: - * false block element is unlocled - * true block element is locked - * {Boolean} flipv whether to mirror the block over the vertical axis, background image is flipped automaticly, default is false - * Possible values: - * true block element is flipped - * false block element is not flipped - * {Boolean} fliph whether to mirror the block over the horizontal axis, background image is flipped automaticly. default is false - * Possible values: - * true block element is flipped - * false block element is not flipped - * {Number} rotation the rotation in degrees clockwise, background image is rotated automaticly, default is 0 - * Possible values: - * 0 0 degrees rotation - * 90 90 degrees rotation - * 180 180 degrees rotation - * 270 270 degrees rotation - * {Object} inputList Block's inputs list, block could haven't any inputs - * Properties: - * {Number} x position in pixels relative to Block's horizontal dimension - * {Number} y position in pixels relative to Block's vertical dimension - * {String} position edge where input is placed - * Possible values: - * top input is placed on top edge of block - * right input is placed on right edge of block - * bottom input is placed on bottom edge of block - * left input is placed on left edge of block - * {String} type name of block with special abilities, which could set in template file - * {String} picture Path to image file. - * {Number} dwidth the minimal horizontal size of Block element - * {Number} dheight the minimal vertical size of Block element - * {Boolean} scalex resizing in horizontal plane - * {Boolean} scaley resizing in vertical plane - * {Boolean} scaleratio resizing in horizontal or vertical plane only is not allowed. Resizing in two dimensions plane at the same time is allowed. - * {XMLElement} xmlNode the xml representation of block from model - * {String} caption discription placed under block element - * @constructor - */ -jpf.flow.block = function(htmlElement, objCanvas, other) { - this.canvas = objCanvas; - this.htmlElement = htmlElement; - this.id = htmlElement.getAttribute("id"); - this.moveListeners = new Array(); - this.draggable = true; - this.htmlOutputs = {}; - - this.image = null; - this.other = other; - - var _self = this; - - this.destroy = function() { - //removing events - this.htmlElement.onmouseover = - this.htmlElement.onmouseout = - this.htmlElement.onclick = null; - - //removing connections - for (var i = this.moveListeners.length-1; i >= 0; i--) { - this.moveListeners[i].destroy(); - this.moveListeners.removeIndex(i); - } - //removing objBlock from canvas - delete this.canvas.htmlBlocks[this.id]; - } - - this.initBlock = function() { - this.canvas.htmlBlocks[this.id] = this; - - var bChilds = this.htmlElement.childNodes; - for (var i = 0, l = bChilds.length; i < l; i++) { - var tag = bChilds[i].tagName; - if (tag) { - if (tag.toLowerCase() == "div") { - var dChilds = bChilds[i].childNodes; - - for (var j = 0; j < dChilds.length; j++) { - if(dChilds[j].tagName.toLowerCase() == "img") { - this.imageContainer = bChilds[i]; - this.image = dChilds[j]; - } - } - } - else if (tag.toLowerCase() == "blockquote") { - this.caption = bChilds[i]; - } - } - } - - if (!this.other.type) { - jpf.setStyleClass(this.htmlElement, "empty"); - this.image.style.display = "none"; - } - else { - if (this.other.picture == null) { - this.image.style.display = "none"; - } - else { - this.image.style.display = "block"; - this.image.src = this.other.picture; - this.image.onload = function() { - _self.changeRotation(_self.other.rotation, - _self.other.fliph, _self.other.flipv, true); - } - } - } - /* Set last scale ratio */ - this.other.ratio = this.other.dwidth / this.other.dheight; - - this.changeRotation(_self.other.rotation, - _self.other.fliph, _self.other.flipv, true); - this.setCaption(this.other.caption); - this.setLock(this.other.lock, true) - - this.updateOutputs(); - }; - - this.updateOutputs = function() { - var inp = this.other.inputList; - - for (var id in inp) { - var input = this.htmlOutputs[id] - ? this.htmlOutputs[id] - : new jpf.flow.input(this, id); - - if (!this.htmlOutputs[id]) - this.htmlOutputs[id] = input; - var pos = this.updateInputPos(inp[id]); - - var _x = pos[0] - (pos[2] == "left" || pos[2] == "right" - ? Math.ceil(parseInt(jpf.getStyle(input.htmlElement, "width"))/2) - : Math.ceil(jpf.flow.sSize/2)); - var _y = pos[1] - (pos[2] == "top" || pos[2] == "bottom" - ? Math.ceil(parseInt(jpf.getStyle(input.htmlElement, "height"))/2) - : Math.ceil(jpf.flow.sSize/2)); - - input.lastUpdate = pos; - input.moveTo(_x, _y); - } - }; - - this.outputsVisibility = function(visible) { - var inp = this.htmlOutputs; - for (var id in inp) { - var input = inp[id]; - if (visible) - input.show(); - else - input.hide(); - } - }; - - /** - * Immobilise block element on workarea - * - * @param {Number} lock prohibit block move, default is false - * Possible values: - * true block is locked - * false block is unlocked - */ - this.setLock = function(lock, init) { - if (this.other.lock !== lock || init) { - this.draggable = !lock; - this.other.lock = lock; - this.outputsVisibility(!lock); - - if (lock) - jpf.setStyleClass(this.htmlElement, "locked"); - else - jpf.setStyleClass(this.htmlElement, "", ["locked"]); - } - }; - - /** - * Sets new discription which is placed under block element - * - * @param {String} caption block discription - */ - this.setCaption = function(caption) { - var c = this.caption; - c.innerHTML = caption; - if (this.other.capPos == "inside") { - if (c.offsetWidth !== 0 && c.offsetHeight !== 0) { - c.style.marginLeft = - "-" + (Math.ceil(c.offsetWidth / 2)) + "px"; - c.style.marginTop = - "-" + (Math.ceil(c.offsetHeight / 2)) + "px"; - } - } - } - - /** - * Moves block to new x, y position - * - * @param {Number} top vertical coordinate - * @param {Number} left horizontal coordinate - */ - this.moveTo = function(top, left) { - var t = parseInt(this.htmlElement.style.top); - var l = parseInt(this.htmlElement.style.left); - - if (t !== top || l !== left) { - this.htmlElement.style.top = top + "px"; - this.htmlElement.style.left = left + "px"; - } - } - - /** - * Resize block element - * - * @param {Number} width new vertical block size - * @param {Number} height new horizontal block size - */ - this.resize = function(width, height) { - var w = parseInt(this.htmlElement.style.width); - var h = parseInt(this.htmlElement.style.height); - - if (w !== width || h !== height) { - this.htmlElement.style.width = this.imageContainer.style.width - = width + "px"; - this.htmlElement.style.height = this.imageContainer.style.height - = height + "px"; - this.image.style.height = height + "px"; - this.image.style.width = width + "px"; - } - } - - /** - * Set rotation and flip and call to redraw image function. - * - * @param {Number} rotation the rotation in degrees clockwise, background image is rotated automaticly, Default is 0. - * Possible values: - * 0 0 degrees rotation - * 90 90 degrees rotation - * 180 180 degrees rotation - * 270 270 degrees rotation - * @param {Boolean} fliph whether to mirror the block over the vertical axis, background image is flipped automaticly. Default is false. - * Possible values: - * true block element is flipped - * false block element is not flipped - * @param {Boolean} flipv whether to mirror the block over the horizontal axis, background image is flipped automaticly. Default is false. - * Possible values: - * true block element is flipped - * false block element is not flipped - * @param {Boolean} init - */ - this.changeRotation = function(rotation, fliph, flipv, init) { - var o = this.other, prev = [o.rotation, o.fliph, o.flipv]; - if (!o.type) - return; - - o.rotation = parseInt(rotation) % 360 || 0; - o.fliph = String(fliph) == "true" ? true : false; - o.flipv = String(flipv) == "true" ? true : false; - - var flip = (o.fliph && !o.flipv - ? "horizontal" - : (!o.fliph && o.flipv - ? "vertical" - : "none")); - - if (init || (prev[0] != o.rotation || prev[1] != o.fliph || prev[2] != o.flipv)) { - this.repaintImage(flip, o.rotation, 'rel'); - } - }; - - /** - * Function repaint default block's image with new rotation and flip. - * - * @param {String} flip whether to mirror the image over the vertical or horizontal axis - * Possible values: - * none image is not flipped - * horizontal image is flipped horizontal - * vertical image is flipped vertical - * @param {Number} angle degrees angle - * Possible values: - * 0 0 degrees angle - * 90 90 degrees angle - * 180 180 degrees angle - * 270 270 degrees amgle - * @param {String} whence - */ - this.repaintImage = function(flip, angle, whence) { - var p = this.image; - if(p.style.display == "none") - return; - else - p.style.display = "block"; - - p.angle = !whence - ? ((p.angle == undefined ? 0 : p.angle) + angle) % 360 - : angle; - - var rotation = Math.PI *(p.angle >= 0 ? p.angle : 360 + p.angle)/ 180; - var costheta = Math.cos(rotation); - var sintheta = Math.sin(rotation); - - if (document.all && !window.opera) { - var canvas = document.createElement('img'); - canvas.src = p.src; - canvas.style.height = p.height + "px"; - canvas.style.width = p.width + "px"; - - canvas.style.filter = "progid:DXImageTransform.Microsoft.Matrix(M11=" - + costheta + ",M12=" + (-sintheta) - + ",M21=" + sintheta - + ",M22=" + costheta - + ",SizingMethod='auto expand')"; - - if (flip !== "none") { - canvas.style.filter += "progid:DXImageTransform.Microsoft.BasicImage(" - +(flip == "horizontal" - ? "mirror=1" - : "rotation=2, mirror=1") - +")"; - } - } - else { - var canvas = document.createElement('canvas'); - if (!p.oImage) { - canvas.oImage = new Image(); - canvas.oImage.src = p.src; - } - else { - canvas.oImage = p.oImage; - } - - canvas.style.width = canvas.width - = Math.abs(costheta * canvas.oImage.width) - + Math.abs(sintheta * canvas.oImage.height); - canvas.style.height = canvas.height - = Math.abs(costheta * canvas.oImage.height) - + Math.abs(sintheta * canvas.oImage.width); - - var context = canvas.getContext('2d'); - context.save(); - - switch (flip) { - case "vertical": - context.translate(0, canvas.oImage.height); - context.scale(1, -1); - break; - case "horizontal": - context.translate(canvas.oImage.height, 0); - context.scale(-1, 1); - break; - } - - if (rotation <= Math.PI / 2) { - context.translate(sintheta * canvas.oImage.height, 0); - } - else if (rotation <= Math.PI) { - context.translate(canvas.width, - -costheta * canvas.oImage.height); - } - else if (rotation <= 1.5 * Math.PI) { - context.translate(-costheta * canvas.oImage.width, - canvas.height); - } - else { - context.translate(0, -sintheta * canvas.oImage.width); - } - context.rotate(rotation); - - try { - context.drawImage(canvas.oImage, 0, 0, canvas.oImage.width, - canvas.oImage.height); - context.restore(); - } - catch (e) {} - } - canvas.angle = p.angle; - this.imageContainer.replaceChild(canvas, p); - this.image = canvas; - }; - - /** - * When Block change his position notify other elements about that fact - * (actualy notify only connections, but it's not important what type - * element have. Notified object must have onMove function). - */ - this.onMove = function() { - for (var i = 0, ml = this.moveListeners, l = ml.length; i < l; i++) { - ml[i].onMove(); - } - }; - - /** - * Calculate new input position if block is resized, flipped or rotated. - * Base on default informations about block element from template. - * - * @param {Object} input object representation of input element - * Properties: - * {Number} x x position in pixels based on Block's dimensions - * {Number} y y position in pixels based on Block's dimensions - * {String} position input orientation - * Possible values: - * top input is placed on top edge of block - * right input is placed on right edge of block - * bottom input is placed on bottom edge of block - * left input is placed on left edge of block - * @param {Object} [dPos] destination block position - * Properties: - * dPos[0] destination block horizontal coordinate - * dPos[1] destination block vertical coordinate - * dPos[2] horizontal size of destination block element - * dPos[3] vertical size of destination block element - * @return {Object} new input position - */ - this.updateInputPos = function(input, dPos) { - var b = this.htmlElement, - o = this.other, - w = parseInt(b.style.width), h = parseInt(b.style.height), - ior = input ? input.position : "auto", - x = input ? input.x : w / 2, y = input ? input.y : h / 2, - dw = o.dwidth, dh = o.dheight, - fv = o.flipv, fh = o.fliph, r = o.rotation; - var positions = {0 : "top", 1 : "right", 2 : "bottom", 3 : "left", - "top" : 0, "right" : 1, "bottom" : 2, "left" : 3}; - var sSize = jpf.flow.sSize, hSize = Math.floor(jpf.flow.sSize/2); - - /* Changing input floating */ - ior = ior == "auto" - ? "auto" - : positions[(positions[ior] + parseInt(r) / 90)%4]; - - if (ior !== "auto") { - if (fv) - ior = ior == "top" ? "bottom" : (ior == "bottom" ? "top" : ior); - if (fh) - ior = ior == "left" ? "right" : (ior == "right" ? "left" : ior); - - /* If block is resized, block keep proportion */ - x = r == 90 || r == 270 ? x*h / dh : x*w / dw; - y = r == 90 || r == 270 ? y*w / dw : y*h / dh; - - /* If rotate, change inputs coordinates */ - var _x = x, _y = y; - - _x = r == 90 - ? w - y - 1 - : (r == 180 - ? w - x - 1 - : (r == 270 - ? y - : x)); - _y = r == 90 - ? x - : (r == 180 - ? h - y - 1 - : (r == 270 - ? h - x - 1 - : y)); - - /* Flip Vertical and Horizontal */ - _x = fh ? w - _x : _x; - _y = fv ? h - _y : _y; - - _x = fh ? (ior == "top" || ior == "bottom" ? _x - 1 : _x) : _x - _y = fv ? (ior == "left" || ior == "right" ? _y - 1 : _y) : _y - - _x = ior == "top" || ior == "bottom" - ? _x - (sSize/2) + (jpf.isIE || jpf.isOpera || jpf.isChrome ? 1 : 0) - : _x; - _y = ior == "left" || ior == "right" - ? _y - (sSize/2) + (jpf.isIE || jpf.isOpera || jpf.isChrome ? 1 : 0) - : _y; - } - else { - var st = parseInt(b.style.top), sl = parseInt(b.style.left), - dt = dPos[1], dl = dPos[0], dw = dPos[2], dh = dPos[3]; - - if (st + h * 1.5 < dt) { - ior = "bottom"; - } - else if (st > dt + dh * 1.5) { - ior = "top"; - } - else { - if (sl > dl + dw / 2) { - ior = "left"; - } - else if (sl < dl) { - ior = "right"; - } - else { - ior = "left"; - } - } - - _x = ior == "top" || ior == "bottom" - ? w/2 - hSize - : ior == "right" - ? w - : 0; - _y = ior == "left" || ior == "right" - ? h/2 - hSize - : ior == "bottom" - ? h - : 0; - } - return [_x, _y, ior]; - }; - - this.htmlElement.onmouseup = function(e) { - if (!_self.other.type && _self.canvas.mode == "connection-add") { - jpf.flow.connectionsManager.addBlock(_self, 0); - } - } -}; - -/** - * Creates object representation of input element. Each block could have no - * limited number of inputs. - * - * @param {Object} objBlock object representation of block element - * @constructor - */ -jpf.flow.input = function(objBlock, number) { - this.objBlock = objBlock; - this.htmlElement = objBlock.htmlElement.appendChild(document.createElement("div")); - this.number = number; - this.lastUpdate = null; - - var _self = this; - - jpf.setStyleClass(this.htmlElement, "input"); - - this.hide = function() { - this.htmlElement.style.display = "none"; - }; - - this.show = function() { - this.htmlElement.style.display = "block"; - }; - - this.moveTo = function(x, y) { - this.htmlElement.style.left = x + "px"; - this.htmlElement.style.top = y + "px"; - }; - - var connection; - var vMB; - this.htmlElement.onmousedown = function(e) { - e = (e || event); - e.cancelBubble = true; - jpf.flow.ismoved = true; - - var pn = _self.htmlElement.parentNode, - canvas = _self.objBlock.canvas, - mode = canvas.mode; - - if (e.preventDefault) { - e.preventDefault(); - } - - vMB = new jpf.flow.virtualMouseBlock(canvas, e); - - var con = jpf.flow.findConnector(_self.objBlock, _self.number); - if (con) { - var source = con.source - ? con.connector.objDestination - : con.connector.objSource; - var destination = con.source - ? con.connector.objSource - : con.connector.objDestination; - var sourceInput = con.source - ? con.connector.other.input - : con.connector.other.output; - var destinationInput = con.source - ? con.connector.other.output - : con.connector.other.input; - /* Temporary connection must keeping output direction */ - vMB.other.inputList[1].position = destination.updateInputPos( - destination.other.inputList[destinationInput])[2]; - - _self.objBlock.onremoveconnection([con.connector.other.xmlNode]); - jpf.flow.removeConnector(con.connector.htmlElement); - - connection = new jpf.flow.addConnector(canvas , source, vMB, { - output : sourceInput, input : 1 - }); - jpf.flow.connectionsManager.addBlock(source, sourceInput); - canvas.setMode("connection-change"); - } - else { - connection = new jpf.flow.addConnector(canvas, _self.objBlock, vMB, { - output : _self.number - }); - jpf.flow.connectionsManager.addBlock(_self.objBlock, _self.number); - canvas.setMode("connection-add"); - } - connection.newConnector.virtualSegment = true; - vMB.onMove(e); - - document.onmousemove = function(e) { - e = (e || event); - - if(vMB) - vMB.onMove(e); - }; - - document.onmouseup = function(e) { - e = (e || event); - var t = e.target || e.srcElement; - document.onmousemove = null; - jpf.flow.ismoved = false; - - if (t && canvas.mode == "connection-change") { - if ((t.className || "").indexOf("input") == -1) { - jpf.flow.connectionsManager.addBlock(destination, destinationInput); - } - } - jpf.flow.connectionsManager.clear(); - - if (connection) { - jpf.flow.removeConnector(connection.newConnector.htmlElement); - } - if (vMB) { - vMB.destroy(); - vMB = null; - _self.objBlock.canvas.setMode("normal"); - } - }; - }; - - this.htmlElement.onmouseup = function(e) { - jpf.flow.connectionsManager.addBlock(_self.objBlock, _self.number); - }; - - this.htmlElement.onmouseover = function(e) { - var mode = _self.objBlock.canvas.mode; - if (mode == "connection-add" || mode == "connection-change") { - jpf.setStyleClass(_self.htmlElement, "inputHover"); - } - - }; - - this.htmlElement.onmouseout = function(e) { - jpf.setStyleClass(_self.htmlElement, "", ["inputHover"]); - }; -}; - -/** - * Manage informations about clicked blocks and/or inputs. If mode - * connection-add is active and if two blocks or inputs has clicked, new - * connection will be created. - * @constructor - */ -jpf.flow.connectionsManager = function() { - this.addBlock = function(objBlock, inputNumber) { - if (objBlock && (inputNumber || inputNumber == 0)) { - var s = jpf.flow.connectionsTemp; - - if (!s) { - jpf.flow.connectionsTemp = { - objBlock : objBlock, - inputNumber : inputNumber - }; - } - else { - if (s.objBlock.id !== objBlock.id || s.inputNumber !== inputNumber) { - objBlock.oncreateconnection(s.objBlock.other.xmlNode, - s.inputNumber, objBlock.other.xmlNode, inputNumber); - objBlock.canvas.setMode("normal"); - } - this.clear(); - } - } - }; - - this.clear = function() { - jpf.flow.connectionsTemp = null; - }; -}; - -/** - * Simulate block element. Temporary connection is created between source - * block and mouse cursor, until destination block is not clicked. - * - * @param {Object} canvas object representation of canvas element - * @constructor - */ -jpf.flow.virtualMouseBlock = function(canvas) { - var hook = [0, 0, "virtual"]; - this.canvas = canvas; - this.htmlElement = document.createElement('div'); - - this.canvas.htmlElement.appendChild(this.htmlElement); - - this.htmlElement.style.display = "block"; - this.moveListeners = new Array(); - this.draggable = 0; - this.htmlOutputs = {}; - this.htmlOutputs[1] = { - htmlElement : this.htmlElement.appendChild(document.createElement("div")), - number : 1, - lastUpdate : hook - }; - this.other = {}; - this.other.inputList = {}; - this.other.inputList[1] = {x : hook[0], y : hook[1], position : hook[2]}; - - jpf.setStyleClass(this.htmlElement, "vMB"); - - var sPos = jpf.getAbsolutePosition(this.htmlElement.parentNode); - - this.onMove = function(e) { - this.htmlElement.style.left = (e.clientX - sPos[0] + 2 + this.canvas.htmlElement.scrollLeft) + "px"; - this.htmlElement.style.top = (e.clientY - sPos[1] + 2 + this.canvas.htmlElement.scrollTop) + "px"; - - for (var i = 0, l = this.moveListeners.length; i < l; i++) { - this.moveListeners[i].onMove(); - } - }; - - this.destroy = function() { - this.htmlElement.parentNode.removeChild(this.htmlElement); - }; - - this.updateInputPos = function(input) { - return hook; - }; -}; - - -/** - * Creates connection between two block elements. To remove connection is needed - * select it by mouse and press delete button. - * - * @param {HTMLElement} htmlElement html representation of connector element - * @param {Object} objCanvas object representation of connector element - * @param {Object} objSource object representation of source block element - * @param {Object} objDestination object representation of destination block element - * @param {Object} other connection properties - * Properties: - * {Number} output source block input number - * {Number} input destination block input number - * {XMLElement} xmlNode xml representation of connection element - * @constructor - */ -jpf.flow.connector = function(htmlElement, objCanvas, objSource, objDestination, other) { - this.htmlSegments = []; - var htmlSegmentsTemp = []; - this.htmlLabel = null; - this.htmlStart = null; - this.htmlEnd = null; - - this.objSource = objSource; - this.objDestination = objDestination; - this.other = other; - - this.selected = false; - - this.htmlElement = htmlElement; - this.virtualSegment = null; - - var sSize = jpf.flow.sSize; //Segment size - var fsSize = jpf.flow.fsSize; //First segment size - var hSize = Math.floor(sSize/2); - - var sourceHtml = this.objSource.htmlElement; - var destinationHtml = this.objDestination.htmlElement; - - var _self = this; - - this.initConnector = function() { - if (!htmlElement.getAttribute("id")) { - jpf.setUniqueHtmlId(htmlElement); - } - objCanvas.htmlConnectors[htmlElement.getAttribute("id")] = this; - - this.objSource.moveListeners.push(this); - this.objDestination.moveListeners.push(this); - this.activateInputs(); - this.onMove(); - }; - - this.activateInputs = function() { - this.i1 = other.output && this.objSource.other.inputList[other.output] - ? this.objSource.other.inputList[other.output] - : {x : 0, y : 0, position : "auto"}; - - this.i2 = other.input && this.objDestination.other.inputList[other.input] - ? this.objDestination.other.inputList[other.input] - : {x : 0, y : 0, position : "auto"}; - } - - this.destroy = function() { - _self.deselectInputs("Selected"); - var sl = this.objSource.moveListeners; - for (var i = 0, l = sl.length; i < l; i++) { - if (sl[i] == this) { - this.objSource.moveListeners.removeIndex(i); - } - } - - var dl = this.objDestination.moveListeners; - for (var i = 0, l = dl.length; i < l; i++) { - if (dl[i] == this) { - this.objDestination.moveListeners.removeIndex(i); - } - } - objCanvas.removeConnector(this.htmlElement.getAttribute("id")); - }; - - this.onMove = function() { - this.draw(); - if (this.selected) { - this.deselectInputs("Hover"); - this.deselect("selected"); - this.deselectInputs("Selected"); - this.selected = false; - } - }; - - this.draw = function() { - var l = [], - s = [parseInt(sourceHtml.style.left), - parseInt(sourceHtml.style.top)], - d = [parseInt(destinationHtml.style.left), - parseInt(destinationHtml.style.top)]; - - htmlSegmentsTemp = this.htmlSegments; - /*for (var i = 0, l = this.htmlSegments.length; i < l; i++) { - htmlSegmentsTemp.push(this.htmlSegments[i]); - }*/ - this.htmlSegments = []; - - if (this.i1.position == "auto" || this.i2.position == "auto") { - var sIPos = this.objSource.updateInputPos(this.i1, d); - var dIPos = this.objDestination.updateInputPos(this.i2, s); - } - else { - var sIPos = this.objSource.htmlOutputs[other.output].lastUpdate; - var dIPos = this.objDestination.htmlOutputs[other.input].lastUpdate; - } - - var sO = sIPos[2]; - var dO = dIPos[2]; - - s[0] += sIPos[0]; - s[1] += sIPos[1]; - - d[0] += dIPos[0]; - d[1] += dIPos[1]; - - if (sO !== "virtual") { - s = this.createSegment(s, [fsSize, sO], true); - } - - if (dO !== "virtual") { - d = this.createSegment(d, [fsSize, dO], true); - } - - l = s; - position = s[0] > d[0] - ? (s[1] > d[1] - ? "TL" : (s[1] < d[1] ? "BL" : "ML")) - : (s[0] < d[0] - ? (s[1] > d[1] - ? "TR" : (s[1] < d[1] ? "BR" : "MR")) - : (s[1] > d[1] - ? "TM" : (s[1] < d[1] ? "MM" : "BM"))); - - var condition = position - + (sO == "left" - ? 1 - : (sO == "right" - ? 2 - : sO == "top" - ? 4 - : 8)) - + (dO == "left" - ? 1 - : (dO == "right" - ? 2 - : dO == "top" - ? 4 - : 8)); - //rot.setValue(condition) - - switch (condition) { - case "TR41": - l = this.createSegment(l, [jpf.isGecko ? s[1] - d[1] : Math.ceil(s[1] - d[1]), "top"]); - l = this.createSegment(l, [jpf.isGecko ? d[0] - s[0] : Math.ceil(d[0] - s[0]), "right"]); - break; - case "TR44": - case "TR14": - case "TR11": - l = this.createSegment(l, [jpf.isGecko ? s[1] - d[1] : Math.ceil(s[1] - d[1]), "top"]); - l = this.createSegment(l, [jpf.isGecko ? d[0] - s[0] : Math.floor(d[0] - s[0]), "right"]); - break; - case "BR22": - case "BR24": - case "BR42": - case "BR44": - l = this.createSegment(l, [jpf.isGecko ? d[0] - s[0] : Math.floor(d[0] - s[0]), "right"]); - l = this.createSegment(l, [Math.ceil(Math.abs(d[1] - s[1])), "bottom"]); - break; - case "BR41": - l = this.createSegment(l, [jpf.isGecko ? (d[0] - s[0]) / 2 : (d[0] - s[0]) / 2, "right"]); - l = this.createSegment(l, [d[1] - s[1], "bottom"]); - l = this.createSegment(l, [jpf.isGecko ? (d[0] - s[0]) / 2 : Math.ceil((d[0] - s[0]) / 2), "right"]); - break; - case "BR48": - case "BR28": - l = this.createSegment(l, [jpf.isGecko ? (d[0] - s[0]) / 2 : (d[0] - s[0]) / 2, "right"]); - l = this.createSegment(l, [jpf.isGecko ? d[1] - s[1] : Math.ceil(d[1] - s[1]), "bottom"]); - l = this.createSegment(l, [jpf.isGecko ? (d[0] - s[0]) / 2 : (d[0] - s[0]) / 2, "right"]); - break; - case "BR21": - l = this.createSegment(l, [jpf.isGecko ? (d[0] - s[0]) / 2 : (d[0] - s[0]) / 2, "right"]); - l = this.createSegment(l, [jpf.isGecko ? d[1] - s[1] : Math.ceil(d[1] - s[1]), "bottom"]); - l = this.createSegment(l, [parseInt((d[0] - s[0]) / 2)+1, "right"]); - break; - case "TL44": - case "TL42": - case "TL24": - case "TL22": - l = this.createSegment(l, [jpf.isGecko ? s[1] - d[1] : Math.ceil(s[1] - d[1]), "top"]); - l = this.createSegment(l, [jpf.isGecko ? s[0] - d[0] : Math.ceil(s[0] - d[0]), "left"]); - break; - case "TR21": - case "TR24": - case "TR81": - case "TR84": - case "TR21": - case "TR24": - case "TR81": - case "TR84": - l = this.createSegment(l, [jpf.isGecko ? (d[0] - s[0]) / 2 : (d[0] - s[0]) / 2, "right"]); - l = this.createSegment(l, [jpf.isGecko ? s[1] - d[1] : Math.ceil(s[1] - d[1]), "top"]); - l = this.createSegment(l, [jpf.isGecko ? (d[0] - s[0]) / 2 : (d[0] - s[0]) / 2, "right"]); - break; - case "BR18": - case "BR88": - case "BR81": - case "BR11": - l = this.createSegment(l, [d[1] - s[1], "bottom"]); - l = this.createSegment(l, [jpf.isGecko ? d[0] - s[0] : Math.ceil(d[0] - s[0]), "right"]); - break; - case "BR14": - l = this.createSegment(l, [jpf.isGecko ? (d[1] - s[1]) / 2 : Math.ceil((d[1] - s[1]) / 2) , "bottom"]); - l = this.createSegment(l, [jpf.isGecko ? d[0] - s[0] : Math.floor(d[0] - s[0]), "right"]); - l = this.createSegment(l, [Math.ceil((d[1] - s[1]) / 2), "bottom"]); - break; - case "BR84": - case "BR82": - case "BR12": - l = this.createSegment(l, [jpf.isGecko ? (d[1] - s[1]) / 2 : Math.ceil((d[1] - s[1]) / 2) , "bottom"]); - l = this.createSegment(l, [jpf.isGecko ? d[0] - s[0] : Math.floor(d[0] - s[0]), "right"]); - l = this.createSegment(l, [(d[1] - s[1]) / 2, "bottom"]); - break; - case "BL84": - case "BL24": - case "BL21": - l = this.createSegment(l, [jpf.isGecko ? (d[1] - s[1]) / 2 : Math.ceil((d[1] - s[1]) / 2), "bottom"]); - l = this.createSegment(l, [jpf.isGecko ? s[0] - d[0] : Math.ceil(s[0] - d[0]), "left"]); - l = this.createSegment(l, [jpf.isGecko ? (d[1] - s[1]) / 2 : Math.ceil((d[1] - s[1]) / 2), "bottom"]); - break; - case "BL11": - case "BL14": - case "BL41": - case "BL44": - case "BL81": - l = this.createSegment(l, [jpf.isGecko ? s[0] - d[0] : Math.ceil(s[0] - d[0]), "left"]); - l = this.createSegment(l, [jpf.isGecko ? d[1] - s[1] : Math.ceil(d[1] - s[1]), "bottom"]); - break; - case "BL12": - case "BL18": - case "BL42": - case "BL48": - l = this.createSegment(l, [jpf.isGecko ? (s[0] - d[0]) / 2 : (s[0] - d[0]) / 2, "left"]); - l = this.createSegment(l, [jpf.isGecko ? d[1] - s[1] : Math.ceil(d[1] - s[1]), "bottom"]); - l = this.createSegment(l, [jpf.isGecko ? (s[0] - d[0]) / 2 : (s[0] - d[0]) / 2, "left"]); - break; - case "BL88": - case "BL82": - case "BL28": - case "BL22": - l = this.createSegment(l, [jpf.isGecko ? d[1] - s[1] : Math.ceil(d[1] - s[1]), "bottom"]); - l = this.createSegment(l, [jpf.isGecko ? s[0] - d[0] : Math.ceil(s[0] - d[0]), "left"]); - break; - case "TL88": - case "TL81": - case "TL18": - case "TL11": - l = this.createSegment(l, [jpf.isGecko ? s[0] - d[0] : Math.ceil(s[0] - d[0]), "left"]); - l = this.createSegment(l, [jpf.isGecko ? s[1] - d[1] : Math.ceil(s[1] - d[1]), "top"]); - break; - case "TL41": - l = this.createSegment(l, [jpf.isGecko ? (s[1] - d[1]) / 2 : Math.floor((s[1] - d[1]) / 2), "top"]); - l = this.createSegment(l, [jpf.isGecko ? s[0] - d[0] : Math.ceil(s[0] - d[0]), "left"]); - l = this.createSegment(l, [jpf.isGecko ? (s[1] - d[1]) / 2 : Math.ceil((s[1] - d[1]) / 2), "top"]); - break; - case "TL48": - case "TL28": - case "TL21": - l = this.createSegment(l, [jpf.isGecko ? (s[1] - d[1]) / 2 : Math.floor((s[1] - d[1]) / 2), "top"]); - l = this.createSegment(l, [jpf.isGecko ? s[0] - d[0] : Math.ceil(s[0] - d[0]), "left"]); - l = this.createSegment(l, [jpf.isGecko ? (s[1] - d[1]) / 2 : Math.floor((s[1] - d[1]) / 2), "top"]); - break; - case "TL12": - case "TL14": - case "TL82": - case "TL84": - l = this.createSegment(l, [jpf.isGecko ? (s[0] - d[0]) / 2 : (s[0] - d[0]) / 2, "left"]); - l = this.createSegment(l, [jpf.isGecko ? s[1] - d[1] : Math.ceil(s[1] - d[1]), "top"]); - l = this.createSegment(l, [jpf.isGecko ? (s[0] - d[0]) / 2 : (s[0] - d[0]) / 2, "left"]); - break; - case "TR12": - case "TR18": - case "TR42": - case "TR48": - l = this.createSegment(l, [jpf.isGecko ? (s[1] - d[1]) / 2 : Math.floor((s[1] - d[1]) / 2), "top"]); - l = this.createSegment(l, [jpf.isGecko ? d[0] - s[0] : Math.floor(d[0] - s[0]), "right"]); - l = this.createSegment(l, [jpf.isGecko ? (s[1] - d[1]) / 2 : Math.floor((s[1] - d[1]) / 2), "top"]); - break; - case "TR22": - case "TR28": - case "TR82": - case "TR88": - l = this.createSegment(l, [jpf.isGecko ? d[0] - s[0] : Math.floor(d[0] - s[0]), "right"]); - l = this.createSegment(l, [jpf.isGecko ? s[1] - d[1] : Math.ceil(s[1] - d[1]), "top"]); - break; - default: - switch (position) { - case "ML": - l = this.createSegment(l, [jpf.isGecko ? s[0] - d[0] : Math.ceil(s[0] - d[0]), "left"]); - break; - case "MM": - l = this.createSegment(l, [jpf.isGecko ? s[0] - d[0] : Math.ceil(s[0] - d[0]), "left"]); - l = this.createSegment(l, [jpf.isGecko ? d[1] - s[1] : Math.ceil(d[1] - s[1]), "bottom"]); - break; - case "TM": - l = this.createSegment(l, [jpf.isGecko ? s[1] - d[1] : Math.ceil(s[1] - d[1]), "top"]); - l = this.createSegment(l, [jpf.isGecko ? s[0] - d[0] : Math.ceil(s[0] - d[0]), "left"]); - break; - case "MR": - // This part is not checked, MR41 needs only "right" - // line, else need them both - l = this.createSegment(l, [jpf.isGecko ? d[0] - s[0] : Math.floor(d[0] - s[0]), "right"]); - if (condition.substring(2,4) == "41") - break; - l = this.createSegment(l, [Math.abs(d[1] - s[1]), - "bottom"]); - break; - } - break; - } - - for (var i = htmlSegmentsTemp.length - 1; i >= 0; i--) { - htmlSegmentsTemp[i][0].style.display = "none"; - } - - if (this.other.label) { - this.htmlLabel = jpf.flow.label(this); - } - - if (this.other.type) { - var _type = this.other.type.split("-"); - - if (_type[0] !== "none") { - this.htmlStart = jpf.flow.connectorsEnds(this, "start", _type[0]); - } - if(_type[1] !== "none") { - this.htmlEnd = jpf.flow.connectorsEnds(this, "end", _type[1]); - } - } - }; - - this.createSegment = function(coor, lines, startSeg) { - var or = lines[1], l = lines[0], - sX = coor[0] || 0, sY = coor[1] || 0, - _temp = htmlSegmentsTemp.shift(), - segment = _temp ? _temp[0] : null; - var plane = or == "top" || or == "bottom" ? "ver" : "hor"; - - if (!segment) { - var segment = htmlElement.appendChild(document.createElement("div")); - - jpf.setUniqueHtmlId(segment); - jpf.setStyleClass(segment, "segment"); - - if (_self.selected) - _self.select("selected"); - - var canvas = this.objSource.canvas; - /* Segment events */ - segment.onmouseover = function(e) { - if (!jpf.flow.ismoved && ((canvas.mode == "connection-change" - && _self.selected) || canvas.mode == "connection-add")) { - _self.select("hover"); - } - } - - segment.onmouseout = function(e) { - _self.deselect("hover"); - } - - segment.onmousedown = function(e) { - e = e || event; - e.cancelBubble = true; - _self.deselect("selected"); - _self.select("clicked"); - } - - segment.onmouseup = function(e) { - e = (e || event); - e.cancelBubble = true; - var ctrlKey = e.ctrlKey; - var temp = _self.selected; - - if (!ctrlKey) { - _self.objSource.canvas.deselectConnections(); - } - - _self.selected = temp ? false : _self.selected ? false : true; - - if (_self.selected) { - _self.selectInputs("Selected"); - _self.deselect("clicked"); - _self.select("selected"); - canvas.setMode("connection-change"); - } - else { - _self.deselectInputs("Selected"); - _self.deselect("clicked"); - _self.deselect("selected"); - canvas.setMode("normal"); - } - } - } - - segment.plane = plane; - - var w = plane == "ver" ? sSize : l; - var h = plane == "ver" ? l : sSize; - var className = "segment "+"seg_" + plane; - - if (_self.virtualSegment) { - className += " seg_"+plane+"_virtual"; - } - - segment.className = className; - - if (or == "top") - sY -= l; - if (or == "left") - sX -=l; - - segment.style.display = "block"; - segment.style.left = sX - + (plane == "hor" && !startSeg || (or =="left" && startSeg) ? 3 : 0) - + "px"; - segment.style.top = sY + (plane == "ver" ? 3 : 0) + "px"; - segment.style.width = w + (or =="left" && startSeg ? -3 : (or == "right" && startSeg ? 3 : 0)) + "px"; - segment.style.height = h + "px"; - - /* Define the connection end point */ - if (or == "bottom") - sY += h; - if (or == "right") - sX += w; - - this.htmlSegments.push([segment, or]); - - return [sX, sY]; - }; - - this.deselect = function(type) { - var segments = _self.htmlElement.childNodes; - - for (var i = 0, l = segments.length; i < l; i++) { - if ((segments[i].className || "").indexOf("segment") != -1) { - jpf.setStyleClass(segments[i], "", - ["seg_" + segments[i].plane + "_" + type]); - } - } - if (!_self.selected) - _self.deselectInputs("Selected"); - - if (this.htmlLabel && type == "selected") - this.htmlLabel.className = "label"; - }; - - this.select = function(type) { - var segments = this.htmlElement.childNodes; - - for (var i = 0, l = segments.length; i < l; i++) { - if ((segments[i].className || "").indexOf("segment") != -1) { - jpf.setStyleClass(segments[i], - "seg_" + segments[i].plane + "_" + type); - } - } - _self.selectInputs(); - if (this.htmlLabel && type == "selected") - this.htmlLabel.className = "label labelSelected"; - }; - - this.selectInputs = function(type) { - if (_self.other.output && _self.objSource.htmlOutputs[other.output]) { - var output = _self.objSource.htmlOutputs[other.output].htmlElement; - jpf.setStyleClass(output, "input" + type); - } - if (_self.other.input && _self.objDestination.htmlOutputs[other.input]) { - var input = _self.objDestination.htmlOutputs[other.input].htmlElement; - jpf.setStyleClass(input, "input" + type); - } - }; - - this.deselectInputs = function(type) { - if (_self.other.output && _self.objSource.htmlOutputs[_self.other.output]) { - var output = _self.objSource.htmlOutputs[_self.other.output].htmlElement; - jpf.setStyleClass(output, "", ["input" + type]); - } - if (_self.other.input && _self.objDestination.htmlOutputs[_self.other.input]) { - var input = _self.objDestination.htmlOutputs[_self.other.input].htmlElement; - jpf.setStyleClass(input, "", ["input" + type]); - } - }; -}; - -jpf.flow.connectorsEnds = function(connector, place, type) { - var conEnd = place == "start" ? connector.htmlStart : connector.htmlEnd; - var segment = connector.htmlSegments[place == "start" ? 0 : 1]; - - var l = parseInt(segment[0].style.left); - var t = parseInt(segment[0].style.top); - - var htmlElement = conEnd ? conEnd : connector.htmlElement.appendChild(document.createElement("div")); - - t += segment[1] == "top" ? parseInt(segment[0].style.height) - 14 : 0; - l += segment[1] == "left" ? parseInt(segment[0].style.width) - 11 : (segment[1] == "right" ? 3 : 0); - - htmlElement.style.left = l + "px"; - htmlElement.style.top = t + "px"; - htmlElement.className = "connector-end " + type + " or"+segment[1]; - - return htmlElement; -} - -jpf.flow.label = function(connector, number) { - var number = number || Math.ceil(connector.htmlSegments.length/2); - var segment = connector.htmlSegments[number]; - var l = parseInt(segment[0].style.left); - var t = parseInt(segment[0].style.top); - - if (connector.htmlLabel) { - var htmlElement = connector.htmlLabel; - } - else { - var htmlElement = connector.htmlElement.appendChild(document.createElement("span")); - jpf.setStyleClass(htmlElement, "label"); - } - - l += segment[1] == "top" || segment[1] == "bottom" - ? segment[0].offsetWidth + 3 - : (segment[0].offsetWidth - htmlElement.offsetWidth) / 2; - t += segment[1] == "top" || segment[1] == "bottom" - ? (segment[0].offsetHeight - htmlElement.offsetHeight) / 2 - : segment[0].offsetHeight - 2; - - htmlElement.style.left = l + "px"; - htmlElement.style.top = t + "px"; - htmlElement.innerHTML = connector.other.label; - - return htmlElement; -} - -/* - * Utility functions - */ - -/** - * Looking for object representation of block element with given id. - * - * @param {String} blockId html representation of block element id - * @return {Object} object representation of block element - */ -jpf.flow.findBlock = function(blockId) { - var c = jpf.flow.objCanvases; - - for (var id in c) { - if (c[id].htmlBlocks[blockId]) { - return c[id].htmlBlocks[blockId]; - } - } -}; - -/** - * Looking for object representation of block element with given HTMLElement. - * - * @param {HTMLElement} htmlNode html representation of block element - * @return {Object} object representation of block element - */ -jpf.flow.isBlock = function(htmlNode) { - var c = jpf.flow.objCanvases; - - for (var id in c) { - var block = c[id].htmlBlocks[htmlNode.getAttribute("id")]; - if (block) { - return block; - } - } -}; - -/** - * Looking for object representation of canvas element with given HTMLElement. - * - * @param {HTMLElement} htmlNode html representation of canvas element - * @return {Object} object representation of canvas element - */ -jpf.flow.isCanvas = function(htmlNode) { - if (htmlNode) { - return jpf.flow.objCanvases[htmlNode.id]; - } -}; - -/** - * Looking for object representation of connector element with given object - * representation of source and destination block element and with source and - * destination input number. - * - * @param {Object} objBlock object representation of block element - * @param {Number} iNumber block bnput number - * @param {Object} objBlock2 object representation of block element - * @param {Number} iNumber2 block input number - * - * @return {Object} object representation of connector element and source discription - * Properties: - * {Object} connector object representation of connector element - * {Boolean} source infortmation about which block is a source block - * Possible values: - * true when objBlock is a source block - * false when objBlock isn't a source block - */ -jpf.flow.findConnector = function(objBlock, iNumber, objBlock2, iNumber2) { - var c = jpf.flow.objCanvases; - var connectors; - - for (var id in c) { - connectors = c[id].htmlConnectors; - for (var id2 in connectors) { - if (connectors[id2]) { - var cobjS = connectors[id2].objSource; - var cobjD = connectors[id2].objDestination; - var co = connectors[id2].other.output; - var ci = connectors[id2].other.input; - - if (objBlock2 && iNumber2) { - if (cobjS.id == objBlock.id && co == iNumber - && cobjD.id == objBlock2.id && ci == iNumber2) { - return {connector : connectors[id2], source : true}; - } - else if (cobjD.id == objBlock.id && ci == iNumber - && cobjS.id == objBlock2.id && co == iNumber2) { - return {connector : connectors[id2], source : false}; - } - } - else { - if (cobjS == objBlock && co == iNumber) { - return {connector : connectors[id2], source : true}; - } - else if (cobjD == objBlock && ci == iNumber) { - return {connector : connectors[id2], source : false}; - } - } - } - } - } -}; - -/** - * Looking for object representation of connector element with given HTMLElement. - * - * @param {HTMLElement} htmlNode html representation of connector element - * @return {Object} object representation of connector element - */ -jpf.flow.isConnector = function(htmlNode) { - var c = jpf.flow.objCanvases; - for (var id in c) { - if (c[id].htmlConnectors[htmlNode.id]) - return c[id].htmlConnectors[htmlNode.id]; - } -}; - -/** - * Creates object representation of canvas element - * - * @param {HTMLElement} htmlNode html representation of canvas element - * @return {Object} newCanvas object representation of canvas element - */ -jpf.flow.getCanvas = function(htmlNode) { - var newCanvas = jpf.flow.isCanvas(htmlNode); - - if (!newCanvas) { - newCanvas = new jpf.flow.canvas(htmlNode); - newCanvas.initCanvas(); - } - return newCanvas; -}; - -/** - * Removes html representation of canvas element with his all elements. - * - * @param {HTMLElement} htmlNode html representation of canvas element - * - */ -jpf.flow.removeCanvas = function(htmlNode) { - var canvas = jpf.flow.isCanvas(htmlNode); - canvas.destroy(); -}; - -/** - * Creates object representation of block - * - * @param {HTMLElement} htmlElement html representation of block element - * @param {Object} objCanvas object representation of Canvas element - * @param {Object} other block properties - * Properties: - * {Boolean} lock prohibit block move. Default is false. - * Possible values: - * false block element is unlocled - * true block element is locked - * {Boolean} flipv whether to mirror the block over the vertical axis, background image is flipped automaticly. Default is false. - * Possible values: - * true block element is flipped - * false block element is not flipped - * {Boolean} fliph whether to mirror the block over the horizontal axis, background image is flipped automaticly. Default is false. - * Possible values: - * true block element is flipped - * false block element is not flipped - * {Number} rotation the rotation in degrees clockwise, background image is rotated automaticly, Default is 0. - * Possible values: - * 0 0 degrees rotation - * 90 90 degrees rotation - * 180 180 degrees rotation - * 270 270 degrees rotation - * {Object} inputList Block's inputs list, block could haven't any inputs - * Properties: - * {Number} x position in pixels relative to Block's horizontal dimension - * {Number} y position in pixels relative to Block's vertical dimension - * {String} position edge where input is placed - * Possible values: - * top input is placed on top edge of block - * right input is placed on right edge of block - * bottom input is placed on bottom edge of block - * left input is placed on left edge of block - * {String} type name of block with special abilities, which could set in template file - * {String} picture Path to image file. - * {Number} dwidth the minimal horizontal size of Block element - * {Number} dheight the minimal vertical size of Block element - * {Boolean} scalex Allows only horizontal resizing - * {Boolean} scaley Allows only vertical resizing - * {Boolean} scaleratio Vertical or horiznotal resizing only is not allowed. It's possible to resizing in two dimensions plane at the same time. - * {XMLElement} xmlNode xml representation of block from model - * {String} caption discription placed under block element - * @return {Object} object representation of block element - */ -jpf.flow.addBlock = function(htmlElement, objCanvas, other) { - if (!jpf.flow.isBlock(htmlElement)) { - if (!htmlElement.getAttribute("id")) { - jpf.setUniqueHtmlId(htmlElement); - } - var newBlock = new jpf.flow.block(htmlElement, objCanvas, other); - newBlock.initBlock(); - return newBlock; - } -}; - -/** - * Removes html representation of block element with his all connections elements. - * - * @param {HTMLElement} htmlElement html representation of block element - * - */ -jpf.flow.removeBlock = function(htmlElement) { - var block = jpf.flow.isBlock(htmlElement); - block.destroy(); -}; - -/** - * Creates html representation of connector element between two blocks - * - * @param {Object} c object representation of canvas element - * @param {Object} s object representation of source block element - * @param {Object} d object representation of destination block element - * @param {Object} o connector properties - * Properties: - * {Number} output source block input number - * {Number} input destination block input number - * {XMLElement} xmlNode xml representation of connection element - */ -jpf.flow.addConnector = function(c, s, d, o) { - var htmlElement = c.htmlElement.appendChild(document.createElement("div")); - this.newConnector = new jpf.flow.connector(htmlElement, c, s, d, o); - this.newConnector.initConnector(); -}; - -/** - * Removes html representation of connector element from canvas. - * - * @param {HTMLElement} htmlElement html representation of connector element - */ -jpf.flow.removeConnector = function(htmlElement) { - var connector = jpf.flow.isConnector(htmlElement); - if (connector) { - connector.destroy(); - } - delete connector; -}; - - -/*FILEHEAD(/var/lib/jpf/src/core/lib/layout.js)SIZE(-1077090856)TIME(1238944816)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * Takes care of the spatial order of elements withing the display area
- * of the browser. Layouts can be saved to xml and loaded again. Window
- * elements are dockable, which means the user can change the layout as he/she
- * wishes. The state of the layout can be saved as xml at any time.
- *
- * Example:
- * This example shows 5 windows which have a layout defined in layout.xml.
- * <code>
- * <j:appsettings layout="url:layout.xml:layout[1]" />
- *
- * <j:window title="Main Window" id="b1" />
- * <j:window title="Tree Window" id="b2" />
- * <j:window title="Window of Oppertunity" id="b3" />
- * <j:window title="Small window" id="b4" />
- * <j:window title="Some Window" id="b5" />
- * </code>
- *
- * This is the layout file containing two layouts (layout.xml).
- * <code>
- * <layouts>
- * <layout name="Layout 1" margin="2,2,2,2">
- * <vbox edge="splitter">
- * <node name="b1" edge="2"/>
- * <hbox edge="2">
- * <vbox weight="1">
- * <node name="b2"/>
- * <node name="b3"/>
- * </vbox>
- * <node name="b4" weight="1" />
- * </hbox>
- * <node name="b5" height="20" />
- * </vbox>
- * </layout>
- *
- * <layout name="Layout 2">
- * <vbox edge="splitter">
- * <node name="b1" edge="2" />
- * <node name="b2" height="100" />
- * <hbox edge="2">
- * <node name="b3" width="20%" />
- * <node name="b4" width="100" />
- * </hbox>
- * <node name="b5" height="20" />
- * </vbox>
- * </layout>
- * </layouts>
- * </code>
- *
- * By binding on the layout.xml you can easily create a layout manager.
- * <code>
- * <j:list id="lstLayouts"
- * model = "mdlLayouts"
- * allowdeselect = "false"
- * onafterselect = "
- * if(!this.selected || jpf.layout.isLoadedXml(this.selected))
- * return;
- *
- * jpf.layout.saveXml();
- * jpf.layout.loadXml(this.selected);
- * "
- * onbeforeremove = "return confirm('Do you want to delete this layout?')">
- * <j:bindings>
- * <j:caption select="@name" />
- * <j:icon value="layout.png" />
- * <j:traverse select="layout" />
- * </j:bindings>
- * <j:actions>
- * <j:rename select="." />
- * <j:remove select="." />
- * </j:actions>
- * </j:list>
- * <j:button
- * onclick = "
- * if (!lstLayouts.selected)
- * return;
- *
- * var newLayout = jpf.layout.getXml(document.body);
- * newLayout.setAttribute("name", "New");
- * jpf.xmldb.appendChild(lstLayouts.selected.parentNode, newLayout);
- * lstLayouts.select(newLayout, null, null, null, null, true);
- * jpf.layout.loadXml(newLayout);
- * lstLayouts.startRename();
- * ">
- * Add Layout
- * </j:button>
- * </code>
- *
- * @default_private
- * @todo a __WITH_DOM_REPARENTING should be added which can remove many of the functions of this element.
- */
-jpf.layout = {
- layouts : {},
-
- addParent : function(oHtml, pMargin){
- if (!oHtml.getAttribute("id"))
- jpf.setUniqueHtmlId(oHtml);
-
- return this.layouts[oHtml.getAttribute("id")] = {
- layout : new jpf.layoutParser(oHtml, pMargin),
- controls : []
- };
- },
-
-
- splitters : {},
- freesplitters : [],
- vars : {},
-
- getSplitter : function(layout){
- if (!this.splitters[this.getHtmlId(layout.parentNode)])
- this.splitters[this.getHtmlId(layout.parentNode)] = [];
-
- if (this.freesplitters.length){
- var splitter = this.freesplitters.pop();
- }
- else {
- var splitter = new jpf.splitter(this.parentNode);
- splitter.$loadSkin();
- splitter.$draw();
- }
-
- this.splitters[this.getHtmlId(layout.parentNode)].push(splitter);
-
- return splitter;
- },
-
- clearSplitters : function(layout){
- var ar = this.splitters[this.getHtmlId(layout.parentNode)];
- if (!ar) return;
-
- for (var i = 0; i < ar.length; i++) {
- this.freesplitters.push(ar[i]);
- if (!ar[i].oExt.parentNode) continue;
-
- ar[i].oExt.parentNode.removeChild(ar[i].oExt);
- }
- ar.length = 0;
- },
-
-
- get : function(oHtml, pMargin){
- var layout = this.layouts[oHtml.getAttribute("id")];
- if (!layout)
- layout = this.addParent(oHtml, pMargin);
- return layout;
- },
-
- /**
- * Determines whether an xmlNode is of the layout that's currently loaded
- * @param {XMLElement} xmlNode the xml layout description node.
- */
- isLoadedXml : function(xmlNode){
- var nodes = xmlNode.childNodes;
- var node = xmlNode.selectSingleNode(".//node[@name]");//was node()
- var jmlNode = node ? self[node.getAttribute("name")] : null;
-
- if (!jmlNode) {
- throw new Error(jpf.formatErrorString(0, null,
- "Loading Alignment from XML",
- "Could not find JML node" + (node ? " by name '"
- + node.getAttribute("name") + "'" : ""), xmlNode));
- }
-
- var pNode = jmlNode.oExt.parentNode;
- var pId = this.getHtmlId(pNode);
-
- return (this.loadedXml[pId] == xmlNode);
- },
-
- /**
- * Loads a layout using a data instruction.
- * @param {String} instruction the data instruction specifying where to load the data from.
- * Example:
- * <code>
- * jpf.layout.loadFrom("mdlLayout:layout[1]");
- * </code>
- * Remarks:
- * The jml elements referenced in the layout definition should exist when
- * this function is called.
- */
- loadFrom : function(instruction){
- jpf.setModel(instruction, {
- load: function(xmlNode){
- if (!xmlNode || this.isLoaded) return;
-
- if (!xmlNode) {
- throw new Error(jpf.formatErrorString(0, null,
- "Loading default layout",
- "Could not find default layout using processing \
- instruction: '" + instruction + "'"));
-
- return;
- }
-
- jpf.layout.loadXml(xmlNode);
- this.isLoaded = true;
- },
-
- setModel: function(model, xpath){
- if (typeof model == "string")
- model = jpf.nameserver.get("model", model);
- model.register(this, xpath);
- }
- });
- },
-
- loadedXml : {},
- cacheXml : {},
- /**
- * Loads a layout from an xml element.
- * @param {XMLElement} xmlNode the xml element containing the layout description.
- * Remarks:
- * The jml elements referenced in the layout definition should exist when
- * this function is called.
- */
- loadXml : function(xmlNode){
- var nodes = xmlNode.childNodes;
- var node = xmlNode.selectSingleNode(".//node[@name]");//was node()
- var jmlNode = node ? self[node.getAttribute("name")] : null;
-
- if(!jmlNode) {
- throw new Error(jpf.formatErrorString(0, null,
- "Loading Alignment from XML",
- "Could not find JML node" + (node ? " by name '"
- + node.getAttribute("name") + "'" : ""), xmlNode));
- }
-
- var pNode = jmlNode.oExt.parentNode;
- var layout = this.get(pNode, jpf.getBox(xmlNode.getAttribute("margin") || ""));
- var pId = this.getHtmlId(pNode);
-
- this.metadata = [];
-
- for (var i = 0; i < nodes.length; i++) {
- if (nodes[i].nodeType != 1) continue;
-
- layout.root = this.parseXml(nodes[i], layout);
- break;
- }
-
- this.compile(pNode);
- if (jpf.JmlParser.inited)
- this.activateRules(pNode);
-
- this.loadedXml[pId] = xmlNode;
- },
-
- metadata : [],
- getData : function(type, layout){
- return {
- vbox : (type == "vbox"),
- hbox : (type == "hbox"),
- node : "vbox|hbox".indexOf(type) == -1,
- children : [],
- isRight : false,
- isBottom : false,
- edgeMargin : 0,
- splitter : null,
- minwidth : 0,
- minheight : 0,
- weight : 1,
- pHtml : layout.parentNode,
- size : [300,200],
- position : [0,0],
- last : {},
-
- toString : function(){
- var me = jpf.vardump(this, null, false);
- for (var i = 0; i < this.children.length; i++) {
- me += "\n{Child " + i + "\n===========\n"
- + this.children[i].toString() + "}";
- }
-
- return me;
- },
-
- copy : function(){
- var copy = jpf.extend({}, this);
- copy.toString = this.toString;
-
- if (!this.node) {
- copy.children = [];
- for (var i = 0; i < this.children.length; i++) {
- copy.children[i] = this.children[i].copy();
- copy.children[i].parent = copy;
- }
- }
- return copy;
- },
-
-
- setPosition : function(x, y){
- this.oHtml.style.left = x + "px";
- this.oHtml.style.top = y + "px";
-
- this.position = [x, y];
- },
-
- setFloat : function(){
- var diff = jpf.getDiff(this.oHtml);
-
- this.oHtml.style.width = (this.size[0]-diff[0]) + "px";
- if (this.state < 0)
- this.oHtml.style.height = (this.size[1] - diff[1]) + "px";
-
- this.prehide();
- this.hidden = 3;
-
- if (this.hid) {
- var jmlNode = jpf.lookup(this.hid);
- if (jmlNode.syncAlignment)
- jmlNode.syncAlignment(this);
- }
- },
-
- unfloat : function(){
- if (this.hidden != 3) return;
-
- this.show();
- },
-
- state : -1,
- minimize : function(height){
- if (this.state < 0) {
- this.lastfheight = this.fheight;
- this.fheight = "" + height;
- this.lastsplitter = this.splitter;
- if (this.parent.vbox)
- this.splitter = -1;
- this.state = 1;
- }
- },
-
- restore : function(){
- if (this.state > 0) {
- this.fheight = this.lastfheight;
- this.splitter = this.lastsplitter;
- this.state = -1;
- }
- },
-
- hidden : false,
- hiddenChildren : [],
- prehide : function(adminOnly){
- if (this.hidden == 3) {
- this.hidden = true;
- if (this.hid)
- jpf.lookup(this.hid).visible = false;
- if (this.oHtml)
- this.oHtml.style.display = "none";
- return;
- }
-
- if (this.hidden && !adminOnly)
- return;
-
- if (!this.parent)
- return; //I think we're done here...
-
- //Record current position
- this.hidepos = {
- prev : this.parent.children[this.stackId - 1],
- next : this.parent.children[this.stackId + 1]
- }
-
- this.hidden = true;
-
- //Check if parent is empty
- var nodes, child, c = 0, i, l, sets = ["children", "hiddenChildren"];
- while(sets.length) {
- nodes = this.parent[sets.pop()];
- for (i = 0, l = nodes.length; i < l; i++) {
- child = nodes[i];
- if (child != this && !child.hidden) { // || jpf.layout.dlist.contains(child)
- c = 1;
- break;
- }
- }
- }
- if (!c)
- this.parent.prehide(adminOnly);
-
- if (adminOnly)
- return this.hide(true);
-
- if (jpf.layout.dlist.contains(this)) {
- jpf.layout.dlist.remove(this);
- return false;
- }
- else
- jpf.layout.dlist.pushUnique(this);
- },
- preshow : function(adminOnly){
- if (!this.hidden)
- return;
-
- this.hidden = false;
-
- if (adminOnly)
- return this.show(true);
-
- //Check if parent is shown
- if (this.parent.hidden) // || jpf.layout.dlist.contains(this.parent) @todo please make hidden a 4 state property
- this.parent.preshow();
-
- if (jpf.layout.dlist.contains(this)) {
- jpf.layout.dlist.remove(this);
- return false;
- }
- else
- jpf.layout.dlist.pushUnique(this);
- },
-
- hide : function(adminOnly){
- //Remove from parent
- var nodes = this.parent.children;
- nodes.removeIndex(this.stackId);
- for (var i = 0; i < nodes.length; i++)
- nodes[i].stackId = i;
-
- //Add to hidden
- this.parent.hiddenChildren.push(this);
-
- if (adminOnly)
- return;
-
- if (this.hidden != 3) {
- if (this.hid)
- jpf.lookup(this.hid).visible = false;
- if (this.oHtml)
- this.oHtml.style.display = "none";
- }
- },
-
- show : function(adminOnly){
- //Check if position is still available
- var nodes = this.parent.children;
- if (this.hidepos.prev && this.hidepos.prev.parent == this.parent
- && !this.hidepos.prev.hidden && !jpf.layout.dlist.contains(this.hidepos.prev)) { //@todo please make hidden a 4 state property
- if (nodes.length < this.hidepos.prev.stackId+ 1 )
- nodes.push(this);
- else
- nodes.insertIndex(this, this.hidepos.prev.stackId + 1);
- }
- else if (this.hidepos.next && this.hidepos.next.parent == this.parent
- && !this.hidepos.next.hidden && !jpf.layout.dlist.contains(this.hidepos.next)) { //@todo please make hidden a 4 state property
- if (this.hidepos.next.stackId == 0)
- nodes.unshift(this);
- else if (nodes.length < this.hidepos.next.stackId - 1)
- nodes.push(this);
- else
- nodes.insertIndex(this, this.hidepos.next.stackId - 1);
- }
- else if (!this.hidepos.prev) {
- nodes.unshift(this);
- }
- else if(!this.hidepos.next) {
- nodes.push(this);
- }
- else {
- if (this.stackId < nodes.length)
- nodes.insertIndex(this, this.stackId);
- else
- nodes.push(this);
- }
-
- for (var i = 0; i < nodes.length; i++)
- if (nodes[i])
- nodes[i].stackId = i;
-
- //Remove from hidden
- this.parent.hiddenChildren.remove(this);
-
- if (!adminOnly) {
- if (this.hidden != 3) {
- if (this.hid)
- jpf.lookup(this.hid).visible = true;
- if (this.oHtml)
- this.oHtml.style.display = "block";
- }
- }
-
- this.hidden = false;
- this.hidepos = null;
- },
-
- remove : function(){
- var p = this.parent;
- if (!p)
- return;
-
- if (this.hidden || p.hiddenChildren.contains(this)) {
- p.hiddenChildren.remove(this);
- jpf.layout.dlist.remove(this);
- }
- else {
- var nodes = p.children;
- nodes.remove(this);
-
- for (var i = 0; i < nodes.length; i++)
- nodes[i].stackId = i;
- }
-
- for (var prop in this.last) {
- if (prop == "splitter") {
- if (p.originalMargin) {
- if (p.parent.pOriginalMargin) {
- p.parent.splitter = null;
- p.parent.edgeMargin = p.parent.pOriginalMargin[0];
- p.parent.pOriginalMargin = null;
- delete p.last.splitter;
- }
-
- p.splitter = null;
- p.edgeMargin = p.originalMargin[0];
- p.originalMargin = null;
- }
- }
-
- this[prop] = p[prop] || this.last[prop];
- }
- this.last = {};
-
- if (!p.children.length && !p.hiddenChildren.length)
- p.remove();
-
- this.parent = null;
- },
-
- add : function(parent){
- this.parent = parent;
-
- if (this.hidden) {
- var nodes = parent.hiddenChildren;
- nodes.push(this);
- //clear stack id?
- }
- else {
- var nodes = parent.children;
- nodes.push(this);
-
- for (var i = 0; i < nodes.length; i++) {
- if (nodes[i])
- nodes[i].stackId = i;
- }
- }
- }
- };
- },
-
- parseXml : function(x, layout, jmlNode, norecur){
- var aData = this.getData(typeof jmlNode == "string"
- ? jmlNode
- : x[jpf.TAGNAME], layout.layout);
-
- if (aData.node) {
- if (!jmlNode) {
- jmlNode = self[x.getAttribute("name")];
- if (!jmlNode) {
- throw new Error(jpf.formatErrorString(0, null,
- "Parsing Alignment from XML",
- "Could not find JML node" + x.getAttribute("name"), x));
- }
- }
-
- //if (!jmlNode.visible)
- //jmlNode.show(true);//jmlNode.setProperty("visible", true);//not the most optimal position
-
- aData.oHtml = jmlNode.oExt;
- jmlNode.aData = aData;
-
- if (!jmlNode.hasFeature(__ALIGNMENT__)) {
- jmlNode.inherit(jpf.Alignment);
- if (jmlNode.hasFeature(__ANCHORING__))
- jmlNode.disableAnchoring();
- }
-
- var jml = jmlNode.$jml;
- if (jml.getAttribute("width"))
- aData.fwidth = jml.getAttribute("width");
- if (jml.getAttribute("height"))
- aData.fheight = jml.getAttribute("height");
- /*if (jmlNode.minwidth)
- aData.minwidth = jmlNode.minwidth;
- if (jmlNode.minheight)
- aData.minheight = jmlNode.minheight;*/
-
- if (!this.getHtmlId(aData.oHtml))
- jpf.setUniqueHtmlId(aData.oHtml);
- aData.id = this.getHtmlId(aData.oHtml);
- if (aData.oHtml.style)
- aData.oHtml.style.position = "absolute";
- aData.hid = jmlNode.uniqueId;
- }
- else {
- aData.id = this.metadata.push(aData) - 1;
- }
-
- if (x.getAttribute("align"))
- aData.template = x.getAttribute("align");
- if (x.getAttribute("lean"))
- aData.isBottom = x.getAttribute("lean").match(/bottom/);
- if (x.getAttribute("lean"))
- aData.isRight = x.getAttribute("lean").match(/right/);
- if (x.getAttribute("edge") && x.getAttribute("edge") != "splitter")
- aData.edgeMargin = x.getAttribute("edge");
- if (x.getAttribute("weight"))
- aData.weight = parseFloat(x.getAttribute("weight"));
- if (x.getAttribute("splitter") || x.getAttribute("edge") == "splitter")
- aData.splitter = x.getAttribute("splitter")
- || (x.getAttribute("edge") == "splitter" ? 5 : false);
- if (x.getAttribute("width"))
- aData.fwidth = String(jpf.parseExpression(x.getAttribute("width")));
- if (x.getAttribute("height"))
- aData.fheight = String(jpf.parseExpression(x.getAttribute("height")));
- if (x.getAttribute("minwidth"))
- aData.minwidth = x.getAttribute("minwidth");
- //@todo calculate inner minheight en minwidth
- /*if (x.getAttribute("minheight"))
- aData.minheight = x.getAttribute("minheight");
- if (x.getAttribute("lastheight"))
- aData.lastfheight = x.getAttribute("lastheight");*/
- if (x.getAttribute("lastsplitter"))
- aData.lastsplitter = x.getAttribute("lastsplitter");
- if (x.getAttribute("hidden"))
- aData.hidden = (x.getAttribute("hidden") == 3)
- ? x.getAttribute("hidden")
- : jpf.isTrue(x.getAttribute("hidden"));
- if (x.getAttribute("state"))
- aData.state = x.getAttribute("state");
- if (x.getAttribute("stack"))
- aData.stackId = parseInt(x.getAttribute("stack"));
- if (x.getAttribute("position"))
- aData.position = x.getAttribute("position").split(",");
- if (x.getAttribute("size"))
- aData.size = x.getAttribute("size").split(",");
-
- //@todo Amazing hackery, can we please try to be consistent across all layout methods
- if (aData.fwidth && aData.fwidth.indexOf("/") > -1) {//match(/[\(\)\+\-=\/\*]/)){
- aData.fwidth = eval(aData.fwidth);
- if (aData.fwidth <= 1)
- aData.fwidth = (aData.fwidth * 100) + "%";
- }
- if (aData.fheight && aData.fheight.indexOf("/") > -1) {//.match(/[\(\)\+\-=\/\*]/)){
- aData.fheight = eval(aData.fheight);
- if (aData.fheight <= 1)
- aData.fheight = (aData.fheight * 100) + "%";
- }
-
- aData.edgeMargin = Math.max(aData.splitter || 0, aData.edgeMargin || 0);
-
- //guessing this is docking... unsure
- if (aData.node && jmlNode.syncAlignment)
- jmlNode.syncAlignment(aData);
-
- if (!norecur && !aData.node) {
- var nodes = x.childNodes;
- for (var last, a, i = 0; i < nodes.length; i++) {
- if (nodes[i].nodeType != 1) continue;
-
- a = this.parseXml(nodes[i], layout);
-
- if (last && last.hidden)
- last.hidepos.next = a;
-
- if (a.hidden) {
- if (a.hid) {
- var j = jpf.lookup(a.hid);
- if (a.hidden === true && j.visible) {
- j.visible = false;
- a.oHtml.style.display = "none";
- }
- if (a.hidden == 3) {
- var diff = jpf.getDiff(a.oHtml);
- a.oHtml.style.left = a.position[0] + "px";
- a.oHtml.style.top = a.position[1] + "px";
- a.oHtml.style.width = (a.size[0] - diff[0]) + "px";
- a.oHtml.style.height = ((!this.state || this.state < 0
- ? a.size[1]
- : a.fheight)-diff[1]) + "px";
- }
- }
-
- aData.hiddenChildren.push(a);
- a.hidepos = {
- prev : aData.children[aData.children.length-1]
- };
- }
- else {
- if (a.hid) {
- var j = jpf.lookup(a.hid);
- if (!j.visible) {
- j.visible = true;
- a.oHtml.style.display = "block";
- }
- }
- a.stackId = aData.children.push(a) - 1;
- }
-
- a.parent = aData;
- last = a;
- }
- }
-
- aData.xml = x;
-
- return aData;
- },
-
-
- /**
- * Makes a copy of the current state of the layout and encodes it in xml.
- * @param {HTMLElement} pNode the html parent for which the layout is expressed in xml.
- * @returns {XMLElement} the xml representation of the layout.
- */
- getXml : function(pNode){
- var l = jpf.layout.get(pNode);
- var xmlNode = l.root.xml
- ? l.root.xml.ownerDocument.createElement("layout")
- : jpf.xmldb.getXml("<layout />");
- jpf.layout.parseToXml(l.root, xmlNode);
- return xmlNode;
- },
-
- /**
- * Updates the current state of the layout to the xml from which the
- * original state was loaded from.
- */
- saveXml : function(){
- for (var pId in this.loadedXml) {
- var xmlNode = this.loadedXml[pId];
- var l = this.layouts[pId];
- var root = l.root;
-
- for (var i = xmlNode.childNodes.length - 1; i >= 0; i--)
- xmlNode.removeChild(xmlNode.childNodes[i]);
-
- //xmlNode.removeChild(root.xml);
- this.parseToXml(root, xmlNode);
- }
- },
-
- parseToXml : function(oItem, parentNode){
- var xmlNode = oItem.xml
- ? oItem.xml.cloneNode(false)
- : parentNode.ownerDocument.createElement(oItem.vbox
- ? "vbox"
- : (oItem.hbox ? "hbox" : "node"));
-
- parentNode.appendChild(xmlNode);
-
- if (oItem.template)
- xmlNode.setAttribute("align", oItem.template);
- if (oItem.edgeMargin)
- xmlNode.setAttribute("edge", oItem.edgeMargin);
- if (oItem.weight)
- xmlNode.setAttribute("weight", oItem.weight);
- if (oItem.splitter)
- xmlNode.setAttribute("splitter", oItem.splitter === false
- ? -1
- : oItem.splitter);
- if (oItem.fwidth)
- xmlNode.setAttribute("width", oItem.fwidth);
- if (oItem.fheight)
- xmlNode.setAttribute("height", oItem.fheight);
- if (oItem.minwidth)
- xmlNode.setAttribute("minwidth", oItem.minwidth);
- if (oItem.minheight)
- xmlNode.setAttribute("minheight", oItem.minheight);
- if (oItem.lastfheight)
- xmlNode.setAttribute("lastheight", oItem.lastfheight);
- if (oItem.lastsplitter)
- xmlNode.setAttribute("lastsplitter", oItem.lastsplitter);
- if (oItem.hidden)
- xmlNode.setAttribute("hidden", (oItem.hidden == 3) ? '3' : 'true');
- else if (xmlNode.getAttribute("hidden"))
- xmlNode.removeAttribute("hidden");
- if (oItem.stackId)
- xmlNode.setAttribute("stack", oItem.stackId);
- if (oItem.state > 0)
- xmlNode.setAttribute("state", oItem.state);
- else if (xmlNode.getAttribute("state"))
- xmlNode.removeAttribute("state");
- if (oItem.position)
- xmlNode.setAttribute("position", oItem.position.join(","));
- if (oItem.size)
- xmlNode.setAttribute("size", oItem.size.join(","));
- //if(oItem.isBottom || oItem.isRight) xmlNode.setAttribute("lean", oItem.minheight);
-
- var list = oItem.children.copy();
- for (var i = 0; i < oItem.hiddenChildren.length; i++) {
- var hidepos = oItem.hiddenChildren[i].hidepos;
- if (hidepos.prev) {
- var index = list.indexOf(hidepos.prev);
- if (index < 0)
- list.unshift(oItem.hiddenChildren[i]);
- else
- list.insertIndex(oItem.hiddenChildren[i], index);
- }
- else if(hidepos.next) {
- var index = list.indexOf(hidepos.next);
- if (index-1 < 0)
- list.unshift(oItem.hiddenChildren[i]);
- else
- list.insertIndex(oItem.hiddenChildren[i], index-1);
- }
- else {
- list.push(oItem.hiddenChildren[i]);
- }
- }
-
- for (var i = 0; i < list.length; i++) {
- this.parseToXml(list[i], xmlNode);
- }
- },
-
-
- checkInheritance : function(node){
- var lastNode = node.children[node.children.length - 1];
- if (node.originalMargin) {
- if (node.parent.pOriginalMargin) {
- node.parent.splitter = null;
- node.parent.edgeMargin = node.parent.pOriginalMargin[0];
- node.parent.pOriginalMargin = null;
- node.splitter = node.last.splitter;
- delete node.last.splitter;
- }
-
- node.splitter = null;
- var lNode = node.originalMargin[1];
- node.edgeMargin = node.originalMargin[0];
- lNode.splitter = lNode.splitter === false
- ? false
- : lNode.last.splitter;
- node.originalMargin = null;
- delete lNode.last.splitter;
- }
-
- if (lastNode && lastNode.template
- && (lastNode.splitter || lastNode.splitter === null
- && node.originalMargin) && node.parent) {
- if (!node.splitter) {
- lastNode.last.splitter =
- node.splitter = lastNode.splitter;
- node.originalMargin = [node.edgeMargin, lastNode];
- node.edgeMargin = Math.max(node.edgeMargin, node.splitter);
- }
- lastNode.splitter = null;
-
- if (node.parent && node.stackId == node.parent.children.length - 1
- && (node.parent.parent && node.parent.parent.children.length > 1)) {
- if (!node.parent.splitter) {
- node.last.splitter =
- node.parent.splitter = node.splitter;
- node.parent.last.splitter = null;
- node.parent.edgeMargin = Math.max(
- node.parent.edgeMargin, node.parent.splitter);
- node.parent.pOriginalMargin = [node.parent.edgeMargin];
- }
- node.splitter = null;
- }
- else if (node.parent.pOriginalMargin) {
- node.parent.splitter = null;
- node.parent.edgeMargin = node.parent.pOriginalMargin[0];
- node.parent.pOriginalMargin = null;
- node.splitter = node.last.splitter;
- delete node.last.splitter;
- }
- }
-
- for (var i = 0; i < node.children.length; i++) {
- if (!node.children[i].node)
- this.checkInheritance(node.children[i]);
- }
-
- var firstNode = node.children[0];
- if (firstNode && node.parent) {
- if (node.vbox) {
- /*
- Width is inherited when parent doesn't have width or it
- already inherited it and wasn't set later (and is thus
- different from cached version (in .last)
- */
- if (!node.fwidth && firstNode.fwidth
- || firstNode.last.fwidth && firstNode.fwidth !== null
- && firstNode.last.fwidth == node.fwidth) {
- firstNode.last.fwidth =
- node.fwidth = firstNode.fwidth;
- firstNode.fwidth = null;
- }
-
- //@todo test this with reparenting
- var pNode = node.parent;
- if ((pNode && !pNode.fheight && firstNode.fheight
- || firstNode.last.fheight && firstNode.fheight !== null
- && firstNode.last.fheight == pNode.fheight) && node.children.length == 1) {
- firstNode.last.fheight =
- pNode.fheight = firstNode.fheight;
- firstNode.fheight = null;
- }
- }
- else {
- /*
- Height is inherited when parent doesn't have height or it
- already inherited it and wasn't set later (and is thus
- different from cached version (in .last)
- */
- if ((!node.fheight && firstNode.fheight
- || firstNode.last.fheight && firstNode.fheight !== null
- && firstNode.last.fheight == node.fheight) && node.children.length == 1) {
- firstNode.last.fheight =
- node.fheight = firstNode.fheight;
- firstNode.fheight = null;
- }
- }
-
- //@todo oops parent is always overriden... :(
- if (firstNode.weight || firstNode.last.weight
- && firstNode.last.weight == node.weight) {
- firstNode.last.weight =
- node.weight = firstNode.weight;
- }
- }
- },
-
- compileAlignment : function(aData){
- if (!aData.children.length) {
- //All children were removed, we're removing the layout rule
- this.removeRule(aData.pHtml, "layout");
-
- var l = this.layouts[aData.pHtml.getAttribute("id")];
- if (l)
- jpf.layout.clearSplitters(l.layout);
-
- return;
- }
-
- var n = aData.children;
- for (var f = false, i = 0; i < n.length; i++) {
- if (n[i].template == "bottom") {
- if (n[i].splitter) {
- n[i - 1].splitter = n[i].splitter;
- n[i].splitter = null;
- }
-
- n[i - 1].edgeMargin = Math.max(n[i].edgeMargin,
- n[i - 1].edgeMargin || 0, n[i - 1].splitter || 0);
- n[i].edgeMargin = null;
- }
- }
-
- this.checkInheritance(aData);
-
-
- //this.compile(aData.pHtml); //oHtml
- var l = this.layouts[aData.pHtml.getAttribute("id")];
- l.layout.compile(aData.copy());
- l.layout.reset();
- },
-
- addAlignNode : function(jmlNode, pData){
- var align = (typeof jmlNode.align == "undefined"
- ? jmlNode.$jml.getAttribute("align")
- : jmlNode.align).split("-");
- var s = pData.children;
- var a = jmlNode.aData;
-
- if (typeof jmlNode.splitter == "undefined") {
- if (align[1] == "splitter")
- a.splitter = align[2] || 4
- else
- a.splitter = false;
- }
-
- a.edgeMargin = Math.max(a.edgeMargin, a.splitter || 0);
- align = align[0];
- a.template = align;
-
- if (align == "top") {
- for (var p = s.length, i = 0; i < s.length; i++) {
- if (s[i].template != "top") {
- p = i;
- break;
- }
- }
- for (var i = s.length - 1; i >= p; i--) {
- s[i + 1] = s[i];
- s[i].stackId = i + 1;
- }
-
- s[p] = a;
- s[p].stackId = p;
- a.parent = pData;
- }
- else if (align == "bottom") {
- a.stackId = s.push(a) - 1;
- a.parent = pData;
- }
- else {
- //find hbox
- var hbox = null;
- for (var p = -1, i = 0; i < s.length; i++) {
- if (s[i].hbox) {
- hbox = s[i];
- break;
- }
- else if (s[i].node && s[i].template == "top")
- p = i;
- }
-
- //create hbox
- if (!hbox) {
- var l = jpf.layout.get(pData.pHtml);
- hbox = jpf.layout.parseXml(jpf.xmldb.getXml("<hbox />"), l, null, true);
- hbox.parent = pData;
- if (p > -1) {
- for (var i = s.length - 1; i > p; i--) {
- s[i + 1] = s[i];
- s[i].stackId++;
- }
- s[p + 1] = hbox;
- hbox.stackId = p + 1;
- }
- else
- hbox.stackId = s.unshift(hbox) - 1;
- }
-
- //find col
- var col, n = hbox.children.concat(hbox.hiddenChildren);
- for (var i = 0; i < n.length; i++) {
- if (n[i].template == align) {
- col = n[i];
- break;
- }
- }
-
- n = hbox.children;
- //create col
- if (!col) {
- var l = jpf.layout.get(pData.pHtml);
- col = jpf.layout.parseXml(jpf.xmldb.getXml("<vbox />"), l, null, true);
- col.parent = hbox;
- col.template = align;
-
- if (align == "left") {
- if (!a.fwidth) {
- var ncol;
- for (var found = false, i = 0; i < n.length; i++) {
- if (n[i].template == "middle") {
- found = n[i];
- break;
- }
- }
-
- if (found && !found.children.length) {
- n.remove(found);
- for(var i = 0; i < n.length; i++)
- n[i].stackId = i;
- }
- }
-
- n.unshift(col);
- for (var i = 0; i < n.length; i++)
- n[i].stackId = i;
- }
- else if (align == "right") {
- if (a.fwidth) {
- var ncol;
- for (var found = false, i = 0; i < n.length; i++) {
- if (n[i].template == "middle" || n[i].template == "left" && !n[i].fwidth) {
- found = true;
- break;
- }
- }
-
- //create middle layer if none is specified
- if (!found) {
- ncol = jpf.layout.parseXml(jpf.xmldb.getXml("<vbox />"), l, null, true);
- ncol.parent = hbox;
- ncol.template = "middle";
-
- ncol.stackId = n.push(ncol) - 1;
- }
- }
-
- col.stackId = n.push(col) - 1;
- }
- else if (align == "middle") {
- for (var f, i = 0; i < n.length; i++)
- if (n[i].template == "right")
- f = i;
- var rcol = n[f];
- if (rcol) {
- n[f] = col;
- col.stackId = f;
- rcol.stackId = n.push(rcol) - 1;
- }
- else {
- col.stackId = n.push(col) - 1;
- }
- }
- }
-
- a.stackId = col.children.push(a) - 1;
- a.parent = col;
-
- if (col.hidden) {
- col.preshow(true);
- }
- }
- },
-
- compile : function(oHtml){
- var l = this.layouts[oHtml.getAttribute("id")];
- if (!l) return false;
-
- var root = l.root.copy();//is there a point to copying?
- l.layout.compile(root);
- l.layout.reset();
- },
-
- removeAll : function(aData) {
- aData.children.length = null
- this.compileAlignment(aData);
-
- var htmlId = this.getHtmlId(aData.pHtml);
- if (!this.rules[htmlId])
- delete this.qlist[htmlId];
- },
-
-
-
- timer : null,
- qlist : {},
- dlist : [],
-
- queue : function(oHtml, obj, compile){
- if (this.qlist[oHtml.getAttribute("id")]) {
- if (obj)
- this.qlist[oHtml.getAttribute("id")][2].push(obj);
- if (compile)
- this.qlist[oHtml.getAttribute("id")][1] = compile;
- return;
- }
-
- this.qlist[oHtml.getAttribute("id")] = [oHtml, compile, [obj]];
-
- if(!this.timer)
- this.timer = setTimeout("jpf.layout.processQueue()");
- },
-
- processQueue : function(){
- clearTimeout(this.timer);
- this.timer = null;
-
- var i, id, l, qItem, list;
-
- for (i = 0; i < this.dlist.length; i++) {
- if (this.dlist[i].hidden)
- this.dlist[i].hide();
- else
- this.dlist[i].show();
- }
-
- for (id in this.qlist) {
- qItem = this.qlist[id];
-
- if (qItem[1])
- jpf.layout.compileAlignment(qItem[1]);
-
- list = qItem[2];
- for (i = 0, l = list.length; i < l; i++) {
- if (list[i])
- list[i].$updateLayout();
- }
-
- jpf.layout.activateRules(qItem[0]);
- }
-
- if (jpf.hasSingleRszEvent)
- jpf.layout.forceResize();
-
- this.qlist = {};
- this.dlist = [];
- },
-
-
- rules : {},
- onresize : {},
-
- getHtmlId : function(oHtml){
- //if(jpf.hasSingleRszEvent) return 1;
- //else
- return oHtml.getAttribute ? oHtml.getAttribute("id") : 1;
- },
-
- /**
- * Adds layout rules to the resize event of the browser. Use this instead
- * of onresize events to add rules that specify determine the layout.
- * @param {HTMLElement} oHtml the element that triggers the execution of the rules.
- * @param {String} id the identifier for the rules within the resize function of this element. Use this to easily update or remove the rules added.
- * @param {String} rules the javascript code that is executed when the html element resizes.
- * @param {Boolean} [overwrite] whether the rules are added to the resize function or overwrite the previous set rules with the specified id.
- */
- setRules : function(oHtml, id, rules, overwrite){
- if (!this.getHtmlId(oHtml))
- jpf.setUniqueHtmlId(oHtml);
- if (!this.rules[this.getHtmlId(oHtml)])
- this.rules[this.getHtmlId(oHtml)] = {};
-
- var ruleset = this.rules[this.getHtmlId(oHtml)][id];
- if (!overwrite && ruleset) {
- this.rules[this.getHtmlId(oHtml)][id] = rules + "\n" + ruleset;
- }
- else
- this.rules[this.getHtmlId(oHtml)][id] = rules;
- },
-
- /**
- * Retrieves the rules set for the resize event of an html element specified by an identifier
- * @param {HTMLElement} oHtml the element that triggers the execution of the rules.
- * @param {String} id the identifier for the rules within the resize function of this element.
- */
- getRules : function(oHtml, id){
- return id
- ? this.rules[this.getHtmlId(oHtml)][id]
- : this.rules[this.getHtmlId(oHtml)];
- },
-
- /**
- * Removes the rules set for the resize event of an html element specified by an identifier
- * @param {HTMLElement} oHtml the element that triggers the execution of the rules.
- * @param {String} id the identifier for the rules within the resize function of this element.
- */
- removeRule : function(oHtml, id){
- if (!this.rules[this.getHtmlId(oHtml)])
- return;
-
- var ret = this.rules[this.getHtmlId(oHtml)][id] || false;
- delete this.rules[this.getHtmlId(oHtml)][id];
-
- var prop;
- for (prop in this.rules[this.getHtmlId(oHtml)]) {
-
- }
- if (!prop)
- delete this.rules[this.getHtmlId(oHtml)]
-
- return ret;
- },
-
- /**
- * Activates the rules set for an html element
- * @param {HTMLElement} oHtml the element that triggers the execution of the rules.
- */
- activateRules : function(oHtml, no_exec){
- if (!oHtml) { //!jpf.hasSingleRszEvent &&
- var prop, obj;
- for(prop in this.rules) {
- obj = document.getElementById(prop);
- if (!obj || obj.onresize) // || this.onresize[prop]
- continue;
- this.activateRules(obj);
- }
-
- if (jpf.hasSingleRszEvent && window.onresize)
- window.onresize();
- return;
- }
-
- var rsz, id, rule, rules, strRules = [];
- if (!jpf.hasSingleRszEvent) {
- rules = this.rules[this.getHtmlId(oHtml)];
- if (!rules){
- oHtml.onresize = null;
- return false;
- }
-
- for (id in rules) { //might need optimization using join()
- if (typeof rules[id] != "string")
- continue;
- strRules.push(rules[id]);
- }
-
- //jpf.console.info(strRules.join("\n"));
- rsz = jpf.needsCssPx
- ? new Function(strRules.join("\n"))
- : new Function(strRules.join("\n").replace(/ \+ 'px'|try\{\}catch\(e\)\{\}\n/g,""))
-
- oHtml.onresize = rsz;
- if (!no_exec)
- rsz();
- }
- else {
- var htmlId = this.getHtmlId(oHtml);
- rules = this.rules[htmlId];
- if (!rules){
- //@todo keep .children
- //delete this.onresize[htmlId];
- return false;
- }
-
- for (id in rules) { //might need optimization using join()
- if (typeof rules[id] != "string")
- continue;
- strRules.push(rules[id]);
- }
-
- var p = oHtml.parentNode;
- while (p && p.nodeType == 1 && !this.onresize[p.getAttribute("id")]) {
- p = p.parentNode;
- }
-
- var f = new Function(strRules.join("\n"));//.replace(/try\{/g, "").replace(/}catch\(e\)\{\s*\}/g, "\n")
- if (this.onresize[htmlId])
- f.children = this.onresize[htmlId].children;
- if (p && p.nodeType == 1) {
- var x = this.onresize[p.getAttribute("id")];
- (x.children || (x.children = {}))[htmlId] = f;
- }
- else this.onresize[htmlId] = f;
- if (!no_exec)
- f();
-
- if (!window.onresize) {
- /*var f = jpf.layout.onresize;
- window.onresize = function(){
- var s = [];
- for (var name in f)
- s.unshift(f[name]);
- for (var i = 0; i < s.length; i++)
- s[i]();
- }*/
-
- var rsz = function(f){
- var c = [];
- for (var name in f)
- c.unshift(f[name]);
- for (var i = 0; i < c.length; i++){
- c[i]();
- if (c[i].children) {
- rsz(c[i].children);
- }
- }
- }
-
- window.onresize = function(){
- rsz(jpf.layout.onresize);
- }
- }
- }
- },
-
- /**
- * Forces calling the resize rules for an html element
- * @param {HTMLElement} oHtml the element for which the rules are executed.
- */
- forceResize : function(oHtml){
- if (jpf.hasSingleRszEvent)
- return window.onresize && window.onresize();
-
- /* @todo this should be done recursive, old way for now
- jpf.hasSingleRszEvent
- ? this.onresize[this.getHtmlId(oHtml)]
- :
- */
-
- var rsz = oHtml.onresize;
- if (rsz)
- rsz();
- },
-
- paused : {},
-
- /**
- * Disables the resize rules for the html element temporarily.
- * @param {HTMLElement} oHtml the element for which the rules are paused.
- * @param {Function} func the resize code that is used temporarily for resize of the html element.
- */
- pause : function(oHtml, replaceFunc){
- if (jpf.hasSingleRszEvent) {
- var htmlId = this.getHtmlId(oHtml);
- this.paused[htmlId] = this.onresize[htmlId] || true;
-
- if (replaceFunc) {
- this.onresize[htmlId] = replaceFunc;
- this.onresize[htmlId].children = this.paused[htmlId].children;
- replaceFunc();
- }
- else
- delete this.onresize[htmlId];
- }
- else {
- this.paused[this.getHtmlId(oHtml)] = oHtml.onresize || true;
-
- if (replaceFunc) {
- oHtml.onresize = replaceFunc;
- replaceFunc();
- }
- else
- oHtml.onresize = null;
- }
- },
-
- /**
- * Enables paused resize rules for the html element
- * @param {HTMLElement} oHtml the element for which the rules have been paused.
- */
- play : function(oHtml){
- if (!this.paused[this.getHtmlId(oHtml)])
- return;
-
- if (jpf.hasSingleRszEvent) {
- var htmlId = this.getHtmlId(oHtml);
- var oldFunc = this.paused[htmlId];
- if (typeof oldFunc == "function") {
- this.onresize[htmlId] = oldFunc;
- //oldFunc();
- }
- else
- delete this.onresize[htmlId];
-
- if (window.onresize)
- window.onresize();
-
- this.paused[this.getHtmlId(oHtml)] = null;
- }
- else {
- var oldFunc = this.paused[this.getHtmlId(oHtml)];
- if (typeof oldFunc == "function") {
- oHtml.onresize = oldFunc;
- oldFunc();
- }
- else
- oHtml.onresize = null;
-
- this.paused[this.getHtmlId(oHtml)] = null;
- }
- }
-};
-
-
-
-jpf.getWindowWidth = function(){
- return jpf.isIE ? document.documentElement.offsetWidth : window.innerWidth;
-}
-jpf.getWindowHeight = function(){
- return jpf.isIE ? document.documentElement.offsetHeight : window.innerHeight;
-}
-
-/**
- * @constructor
- * @private
- */
-jpf.layoutParser = function(parentNode, pMargin){
- pMargin = (pMargin && pMargin.length == 4) ? pMargin : [0, 0, 0, 0];
- this.pMargin = pMargin;
- this.RULES = [];
-
- this.parentNode = parentNode;
- if (!this.parentNode.getAttribute("id"))
- jpf.setUniqueHtmlId(this.parentNode);
-
- var knownVars = {};
- var minWidth = 0;
- var minHeight = 0;
- this.createSplitters = true;
-
- this.setMargin = function(sMargin){
- pMargin = sMargin;
- };
-
- this.reset = function(){
- this.RULES = [];
- knownVars = {};
- this.lastType = this.globalEdge = this.globalSplitter = null;
- };
-
- this.compile = function(root, noapply){
- this.addRule("var v = jpf.layout.vars");
-
- this.globalSplitter = root.splitter;
- this.globalEdge = root.edgeMargin;
-
- if (this.globalSplitter || this.globalEdge)
- this.setglobals(root);
-
- this.preparse(root);
- this.parserules(root);
-
- if (this.createSplitters) {
- jpf.layout.clearSplitters(this);
- this.parsesplitters(root);
- }
-
- //Sort by checking dependency structure
- this.RULES = new DepTree().calc(this.RULES);
- var str = ("try{" + this.RULES.join("}catch(e){}\ntry{") + "}catch(e){}\n")
- .replace(/([^=]+\.style[^=]+) = (.*?)\}/g, "$1 = ($2) + 'px'}");
-
- if (!jpf.hasHtmlIdsInJs) //@todo speed?
- str = str.replace(/q([\w|]+)\.(offset|style)/g, 'document.getElementById("q$1").$2');
-
- //optimization
- //if(this.parentNode != document.body)
- //"if(document.getElementById('" + this.parentNode.id + "').offsetHeight){" + str + "};";
-
- this.lastRoot = root;
-
- if (!noapply)
- jpf.layout.setRules(this.parentNode, "layout", str, true);
- else
- return str;
-
- return false;
- };
-
- this.addRule = function(rule){
- this.RULES.push(rule);
- };
-
- this.setglobals = function(node){
- if (this.globalEdge && !node.edgeMargin) {
- if (!node.splitter)
- node.splitter = this.globalSplitter;
- node.edgeMargin = Math.max(this.globalSplitter, this.globalEdge);
- }
-
- if (node.node) return;
-
- for (var i = 0; i < node.children.length; i++) {
- this.setglobals(node.children[i]);
- }
- };
-
- this.preparse = function(node){
- /*
- Define:
- - minwidth
- - minheight
- - calcheight
- - calcwidth
- - restspace
- - innerspace
- */
-
- if (node.node) {
- return;
- }
- else {
- var type = node.vbox ? "height" : "width";
- var cmhwp = 0;
- var cmwwp = 0;
- var ctph = 0;
- //Calculate resultSpace
- node.childweight = 0;
- node.childminwidth = 0;
- node.childminheight = 0;
- var rules = ["v." + type + "_" + node.id], extra = [];
- var nodes = node.children;
-
- for (var i = 0; i < nodes.length; i++) {
- if (i < nodes.length-1)
- rules.push(" - " + nodes[i].edgeMargin);
- var f = nodes[i]["f" + type];
- if (f) {
- //if(f.indexOf("%") > -1) ctph += parseFloat(f);
-
- extra.push(
- (f.indexOf("%") > -1)
- ? " - (" + (nodes[i]["calc" + type] = "v.innerspace_"
- + node.id + " * " + parseFloat(f)/100) + ")"
- : " - (" + f + ")"
- );
- }
- else {
- node.childweight += nodes[i].weight;
- nodes[i]["calc" + type] = "Math." + (i%2 == 0 ? "ceil" : "floor")
- + "(v.restspace_" + node.id + " * (" + nodes[i].weight
- + "/v.weight_" + node.id + "))";
- }
-
- var g = (node.vbox ? "width" : "height");
- var v = nodes[i]["f" + g];
- if (!v)
- nodes[i]["calc" + g] = (node.vbox ? "v.width_" : "v.height_")
- + node.id;
- else
- nodes[i]["calc" + g] = v.indexOf("%") > -1 ? "v.innerspace_"
- + node.id + " * " + parseFloat(v)/100 : v
-
- if (nodes[i].node)
- nodes[i].oHtml.style.display = "block";
- else
- this.preparse(nodes[i]);
-
- if (node.vbox) {
- /*if(!nodes[i].fheight){
- cmhwp = Math.max(cmhwp, Math.max(nodes[i].childminheight || 0, nodes[i].minheight || 0, 10)/nodes[i].weight);
- node.childminheight += nodes[i].edgeMargin;
- }
- else */
- node.childminheight += Math.max(nodes[i].childminheight || 0,
- nodes[i].minheight || 0, 10) + nodes[i].edgeMargin;
- node.childminwidth = Math.max(node.childminwidth,
- nodes[i].minwidth || nodes[i].childminwidth || 10);
- }
- else {
- /*if(!nodes[i].fwidth){
- cmwwp = Math.max(cmwwp, Math.max(nodes[i].childminwidth || 0, nodes[i].minwidth || 0, 10)/nodes[i].weight);
- node.childminwidth += nodes[i].edgeMargin;
- }
- else */
- node.childminwidth += Math.max(nodes[i].minwidth || 0,
- nodes[i].childminwidth || 0, 10) + nodes[i].edgeMargin;
- node.childminheight = Math.max(node.childminheight,
- nodes[i].minheight || nodes[i].childminheight || 10);
- }
- }
-
- /*if (node.vbox) {
- if (cmhwp) {
- if (ctph)
- node.childminheight += (cmhwp * node.childweight / (100 - ctph)) * ctph;
- node.childminheight += cmhwp * node.childweight;
- }
- } else {
- if (cmwwp) {
- if (ctph)
- node.childminwidth += (cmwwp * node.childweight / (100 - ctph)) * ctph;
- node.childminwidth += cmwwp * node.childweight;
- }
- }*/
-
- node.innerspace = rules.join("");
- node.restspace = node.innerspace + " " + extra.join("");
-
- if (!node.parent) {
- var hordiff = 0, verdiff = 0;
- if (this.parentNode.tagName.toLowerCase() != "body") {
- var diff = jpf.getDiff(this.parentNode);
- verdiff = diff[0];
- hordiff = diff[1];
- }
-
- var strParentNodeWidth = (this.parentNode.tagName.toLowerCase() == "body"
- ? "jpf.getWindowWidth()"
- : "document.getElementById('" + this.parentNode.id + "').offsetWidth");
- var strParentNodeHeight = (this.parentNode.tagName.toLowerCase() == "body"
- ? "jpf.getWindowHeight()"
- : "document.getElementById('" + this.parentNode.id + "').offsetHeight");
- node.calcwidth = "Math.max(" + minWidth + ", " + strParentNodeWidth
- + " - " + (pMargin[1]) + " - " + pMargin[3] + " - " + hordiff + ")";
- node.calcheight = "Math.max(" + minHeight + ", " + strParentNodeHeight
- + " - " + (pMargin[2]) + " - " + pMargin[0] + " - " + verdiff + ")";
- }
- }
- };
-
- this.parserules = function(oItem){
- if (!oItem.node) {
- this.addRule("v.width_" + oItem.id + " = Math.max(" + oItem.childminwidth
- + "," + oItem.minwidth + "," + (oItem.calcwidth || oItem.fwidth) + ")");
- this.addRule("v.height_" + oItem.id + " = Math.max(" + oItem.childminheight
- + "," + oItem.minheight + "," + (oItem.calcheight || oItem.fheight) + ")");
- this.addRule("v.weight_" + oItem.id + " = " + oItem.childweight);
- this.addRule("v.innerspace_" + oItem.id + " = " + oItem.innerspace);
- this.addRule("v.restspace_" + oItem.id + " = " + oItem.restspace);
-
- var aData = jpf.layout.metadata[oItem.id];
- aData.calcData = oItem;
- oItem.original = aData;
-
- if (!oItem.parent) {
- this.addRule("v.left_" + oItem.id + " = " + pMargin[3]);
- this.addRule("v.top_" + oItem.id + " = " + pMargin[0]);
-
- for (var i = 0; i < oItem.children.length; i++)
- this.parserules(oItem.children[i]);
-
- return;
- }
- else {
- var vtop = ["v.top_" + oItem.id, " = "];
- var vleft = ["v.left_" + oItem.id, " = "];
- }
- }
- else {
- var vtop = [oItem.id, ".style.top = "];
- var vleft = [oItem.id, ".style.left = "];
-
- if (oItem.hid) {
- var aData = jpf.lookup(oItem.hid).aData;
- aData.calcData = oItem;
- oItem.original = aData;
- }
-
- var oEl = oItem.oHtml;//document.getElementById(oItem.id);
- var diff = jpf.getDiff(oEl);
- var verdiff = diff[1];
- var hordiff = diff[0];
-
- if (oItem.calcwidth)
- this.addRule(oItem.id + ".style.width = -" + hordiff
- + " + Math.max( " + oItem.calcwidth + ", " + oItem.minwidth + ")");
- else
- oEl.style.width = Math.max(0, oItem.fwidth - hordiff) + "px";
-
- if (oItem.calcheight)
- this.addRule(oItem.id + ".style.height = -" + verdiff
- + " + Math.max( " + oItem.calcheight + ", " + oItem.minheight + ")");
- else
- oEl.style.height = Math.max(0, oItem.fheight - verdiff) + "px";
- }
-
- var oLastSame = oItem.parent.children[oItem.stackId - 1];
- var oNextSame = oItem.parent.children[oItem.stackId + 1];
-
- //TOP
- if (oItem.parent.vbox) {
- if (oItem.parent.isBottom) {
- if (!oNextSame)
- vtop.push("v.top_", oItem.parent.id, " + v.height_",
- oItem.parent.id, " - ", oItem.id, ".offsetHeight");
- else {
- if (oNextSame.node)
- vtop.push(oNextSame.id, ".offsetTop - ", oNextSame.edgeMargin,
- " - ", oItem.id, ".offsetHeight");
- else
- vtop.push("v.top_" + oNextSame.id, " - ", oNextSame.edgeMargin,
- " - ", (oItem.node ? oItem.id + ".offsetHeight" : "v.height_" + oItem.id));
- }
- }
- else if (!oItem.stackId)
- vtop.push("v.top_" + oItem.parent.id);
- else if (oLastSame) {
- if (oLastSame.node)
- vtop.push(oLastSame.id, ".offsetTop + ", oLastSame.id,
- ".offsetHeight + ", oLastSame.edgeMargin);
- else
- vtop.push("v.top_", oLastSame.id, " + v.height_",
- oLastSame.id, " + ", oLastSame.edgeMargin);
- }
- }
- else
- vtop.push("v.top_" + oItem.parent.id);
-
- //LEFT
- if (oItem.parent.hbox) {
- if (oItem.parent.isRight) {
- if (!oNextSame)
- vleft.push("v.left_", oItem.parent.id, " + v.width_",
- oItem.parent.id, " - ", oItem.id, ".offsetWidth", null);
- else {
- if (oNextSame.node)
- vleft.push(oNextSame.id, ".offsetLeft - ",
- oNextSame.edgeMargin, " - ", oItem.id, ".offsetWidth");
- else
- vleft.push("v.left_" + oNextSame.id, " - ", oNextSame.edgeMargin,
- " - ", (oItem.node ? oItem.id + ".offsetWidth" : "v.width_" + oItem.id));
- }
- }
- else if (!oItem.stackId)
- vleft.push("v.left_" + oItem.parent.id);
- else if (oLastSame) {
- if (oLastSame.node)
- vleft.push(oLastSame.id, ".offsetLeft + ", oLastSame.id,
- ".offsetWidth + ", oLastSame.edgeMargin);
- else
- vleft.push("v.left_", oLastSame.id, " + v.width_",
- oLastSame.id, " + ", oLastSame.edgeMargin);
- }
- }
- else
- vleft.push("v.left_" + oItem.parent.id);
-
- if (vleft.length > 2)
- this.addRule(vleft.join(""));
- if (vtop.length > 2)
- this.addRule(vtop.join(""));
-
- if (!oItem.node) {
- for (var i = 0; i < oItem.children.length; i++)
- this.parserules(oItem.children[i]);
- }
- };
-
- this.parsesplitters = function(oItem){
- //&& oItem.stackId != oItem.parent.children.length - 1
- if (oItem.parent && oItem.splitter > 0) {
- jpf.layout.getSplitter(this).init(oItem.splitter, oItem.hid, oItem);
- }
-
- if (!oItem.node) {
- for (var i = 0; i < oItem.children.length; i++)
- this.parsesplitters(oItem.children[i]);
- }
- };
-
- function DepTree(){
- this.parselookup = {};
- this.nRules = [];
- this.doneRules = {};
-
- this.maskText = function(str, m1, m2, m3){
- return m1 + ".offset" + m2.toUpperCase();
- }
-
- this.handleVar = function(match, m1, m2, m3){
- var vname = "a" + m1.replace(/\|/g, "_") + "_style_" + m2.toLowerCase();
- return knownVars[vname] ? vname : match;
- }
-
- //@todo this function needs some serious optimization (according to the profiler)
- this.parseRule = function(rule){
- var aRule = rule.split(" = ");
- var id = aRule[0].replace(/^([_\w\d\|]+)\.style\.(\w)/, this.maskText);
- var vname = "a" + aRule[0].replace(/[\.\|]/g, "_");
- knownVars[vname] = true;
-
- var depsearch = aRule[1].split(/[ \(\)]/);// " "
- var deps = [];
- for (var i = 0; i < depsearch.length; i++) {
- if (depsearch[i].match(/^([_\w\d\|]+)\.offset(\w+)$/) && !depsearch[i].match(/PNODE/)) {
- deps.push(depsearch[i]);
- }
- }
-
- if (vname.match(/width|height/i)) {
- aRule[1] = aRule[1].replace(/^(\s*[\-\d]+[\s\-\+]+)/, "");
- ruleB = aRule[0] + " = " + RegExp.$1 + vname;
- }
- else
- ruleB = aRule[0] + " = " + vname;
-
- if (rule.match(/^v\./)) {
- return {
- id : id,
- rule_p1 : aRule[0] + " = ",
- rule_p2 : aRule[1],
- ruleb : null,
- deps : deps,
- processed : false
- };
- }
-
- return {
- id : id,
- rule_p1 : "var " + vname + " = ",
- rule_p2 : aRule[1],
- ruleb : ruleB,
- deps : deps,
- processed : false
- };
- }
-
- //@todo test safari
- this.calc = function(aRules){
- var str = "";
- for (var i = 0; i < aRules.length; i++) {
- if (aRules[i].match(/^var/)) {
- this.nRules.push(aRules[i]);
- continue;
- }
- var o = this.parseRule(aRules[i], i);
- this.parselookup[o.id] = o;
- }
-
- //build referential tree (graph)
- for (prop in this.parselookup) {
- this.processNode(this.parselookup[prop]);
- }
-
- //Walk Tree
- for (prop in this.parselookup) {
- var root = this.parselookup[prop];
- //if(root.processed) continue;
- this.walkRules(root);
- }
-
- //Set last rules
- for (prop in this.parselookup) {
- this.nRules.push(this.parselookup[prop].ruleb);
- }
-
- return this.nRules;
- }
-
- this.walkRules = function(root){
- if (this.doneRules[root.id]) return;
-
- for (var i = 0; i < root.deps.length; i++) {
- if (root.deps[i] && !root.deps[i].walked && !this.doneRules[root.deps[i].id]) {
- root.deps[i].walked = true;
- this.walkRules(root.deps[i]);
- }
- }
-
- this.doneRules[root.id] = true;
- this.nRules.push(root.rule_p1 + root.rule_p2
- .replace(/([_\w\d\|]+)\.offset(\w+)/g, this.handleVar));
- }
-
- this.processNode = function(o){
- for (var i = 0; i < o.deps.length; i++) {
- var l = typeof o.deps[i] == "string"
- ? this.parselookup[o.deps[i]]
- : o.deps[i];
- if (!l) {
- o.deps[i] = null;
- continue;
- }
-
- o.deps[i] = l;//.copy();
- if (!l.processed) {
- l.processed = true;
- this.processNode(l);
- }
- }
- }
- }
-};
- - -/*FILEHEAD(/var/lib/jpf/src/core/lib/storage.js)SIZE(-1077090856)TIME(1238933677)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-//@todo Use default storage provider (in memory)
-jpf.storage = {
- modules : {},
-
- /**
- * Initializes the main storage engine based on the specified provider.
- * @param {String} name the name of the provider that will provider storage
- * Possible values:
- * memory data is stored in memory and is lossed when the application exits.
- * air data is stored in the air name/value storage.
- * air.file data is stored in the air file based storage.
- * air.sql data is stored in the air sqlite storage.
- * flash data is stored in a small flash container.
- * gears data is stored using the sqlite interface of gears.
- * html5 data is stored in a local storage object specified by the WHATWG html5 standard.
- */
- init : function(name){
- if(!name) name = this.autodetect();
- var provider = this.getProvider(name);
-
- //Install the provider
- jpf.storage = jpf.extend(provider, this); /** @inherits jpf.storage.modules.memory */
- jpf.storage.init = null;
-
- jpf.console.info("Installed storage provider '" + name + "'");
-
- return provider;
- },
-
- /**
- * Retrieves a storage provider without installing it as the central storage provider.
- * @param {String} name the name of the storage provider.
- * Possible values:
- * memory data is stored in memory and is lossed when the application exits.
- * air data is stored in the air name/value storage.
- * air.file data is stored in the air file based storage.
- * air.sql data is stored in the air sqlite storage.
- * flash data is stored in a small flash container.
- * gears data is stored using the sqlite interface of gears.
- * html5 data is stored in a local storage object specified by the WHATWG html5 standard.
- */
- getProvider : function(name){
- var provider = jpf.storage.modules[name];
-
- if(!provider || typeof provider != "object") {
- jpf.console.warn("Could not find storage provider '" + name + "'");
-
- return false;
- }
-
- if (!provider.isAvailable()) {
- jpf.console.warn(
- "Storage provider '" + name + "' is not available");
-
- return false;
- }
-
- if(!provider.initialized
- && (!provider.init || provider.init() === false)) {
- jpf.console.warn(
- "Could not install storage provider '" + name + "");
-
- return false;
- }
-
- provider.name = name;
- jpf.extend(provider, this.base);
-
- return provider;
- },
-
- /**
- * This should also check if a provider has already been used
- * in a previous session
- */
- autodetect : function(){
- for (var name in this.modules) {
- if (name == "memory")
- continue;
-
- if (this.modules[name].isAvailable()) {
- return name;
- }
- }
-
- return this.modules.memory
- ? "memory"
- : null;
- },
-
- /**
- * @private
- */
- base : {
- namespace : "default",
-
- isValidKeyArray : function(keys) {
- return (!keys || !keys.join)
- ? false
- : /^[0-9A-Za-z_\.\-]*$/.test(keys.join(""));
- },
-
- isValidKey : function(keyName){
- return (keyName === null || keyName === undefined)
- ? false
- : /^[0-9A-Za-z_\.\-]*$/.test(keyName);
- },
-
- //Optimization for slow API's
- getAllPairs : function(namespace, store){
- var keys = this.getKeys(namespace);
-
- if (!keys.length)
- return;
-
- var values = this.getMultiple(keys, namespace);
- for (var i = 0; i < keys.length && values; i++) {
- if (values[i])
- store[keys[i]] = values[i];
- }
-
- return keys.length;
- }
- }
-};
- - -/*FILEHEAD(/var/lib/jpf/src/core/lib/animation.js)SIZE(-1077090856)TIME(1238944816)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -/** - * The animation library that is used for the animations inside elements - * @default_private - */ -jpf.tween = { - //Animation Modules - left: function(oHtml, value){ - oHtml.style.left = value + "px"; - }, - right: function(oHtml, value){ - oHtml.style.left = ""; - oHtml.style.right = value + "px"; - }, - top: function(oHtml, value){ - oHtml.style.top = value + "px"; - }, - bottom: function(oHtml, value){ - oHtml.style.top = ""; - oHtml.style.bottom = value + "px"; - }, - width: function(oHtml, value, center){ - oHtml.style.width = value + "px"; - }, - height: function(oHtml, value, center){ - oHtml.style.height = value + "px"; - }, - scrollTop: function(oHtml, value, center){ - oHtml.scrollTop = value; - }, - "height-rsz": function(oHtml, value, center){ - oHtml.style.height = value + "px"; - if (jpf.hasSingleResizeEvent) - window.onresize(); - }, - mwidth: function(oHtml, value, info) { - var diff = jpf.getDiff(oHtml); - oHtml.style.width = value + "px"; - oHtml.style.marginLeft = -1*(value/2 + (parseInt(jpf.getStyle(oHtml, "borderLeftWidth")) || diff[0]/2) + - (info.margin || 0)) + "px"; - }, - mheight: function(oHtml, value, info) { - var diff = jpf.getDiff(oHtml); - oHtml.style.height = value + "px"; - oHtml.style.marginTop = (-1*value/2 - (parseInt(jpf.getStyle(oHtml, "borderTopWidth")) || diff[1]/2) + - (info.margin || 0)) + "px"; - }, - scrollwidth: function(oHtml, value){ - oHtml.style.width = value + "px"; - oHtml.scrollLeft = oHtml.scrollWidth; - }, - scrollheight_old: function(oHtml, value){ - try { - oHtml.style.height = value + "px"; - oHtml.scrollTop = oHtml.scrollHeight; - } catch (e) { - alert(value) - } - }, - scrollheight: function(oHtml, value, info){ - var diff = jpf.getHeightDiff(oHtml); - oHtml.style.height = value + "px"; - var oInt = info.oInt || oHtml; - oInt.scrollTop = oInt.scrollHeight - oInt.offsetHeight - diff; - }, - scrolltop: function(oHtml, value){ - oHtml.style.height = value + "px"; - oHtml.style.top = (-1 * value - 2) + "px"; - oHtml.scrollTop = 0;//oHtml.scrollHeight - oHtml.offsetHeight; - }, - clipright: function(oHtml, value, center){ - oHtml.style.clip = "rect(auto, auto, auto, " + value + "px)"; - oHtml.style.marginLeft = (-1 * value) + "px"; - }, - fade: function(oHtml, value){ - if (jpf.hasStyleFilters) - oHtml.style.filter = "alpha(opacity=" + parseInt(value * 100) + ")"; - //else if(false && jpf.isGecko) oHtml.style.MozOpacity = value-0.000001; - else - oHtml.style.opacity = value; - }, - bgcolor: function(oHtml, value){ - oHtml.style.backgroundColor = value; - }, - textcolor: function(oHtml, value){ - oHtml.style.color = value; - }, - htmlcss : function(oHtml, value, obj){ - if (jpf.hasStyleFilters && obj.type == "filter") - oHtml.style.filter = "progid:DXImageTransform.Microsoft.Alpha(opacity=" + value + ")"; - else - oHtml.style[obj.type] = value + (obj.needsPx ? "px" : ""); - }, - - /** Linear tweening method */ - NORMAL: 0, - /** Ease-in tweening method */ - EASEIN: 1, - /** Ease-out tweening method */ - EASEOUT: 2, - - queue : {}, - - current: null, - - setQueue : function(oHtml, stepFunction){ - if(!oHtml.getAttribute("id")) - jpf.setUniqueHtmlId(oHtml); - - if(!this.queue[oHtml.getAttribute("id")]) - this.queue[oHtml.getAttribute("id")] = []; - - this.queue[oHtml.getAttribute("id")].push(stepFunction); - - if(this.queue[oHtml.getAttribute("id")].length == 1) - stepFunction(0); - }, - - nextQueue : function(oHtml){ - var q = this.queue[oHtml.getAttribute("id")]; - if(!q) return; - - q.shift(); //Remove current step function - - if(q.length) - q[0](0); - }, - - clearQueue : function(oHtml, bStop){ - var q = this.queue[oHtml.getAttribute("id")]; - if(!q) return; - - if (bStop && this.current && this.current.control) - this.current.control.stop = true; - q.length = 0; - }, - - /** - * Calculates all the steps of an animation between a - * begin and end value based on 3 tween strategies - */ - $calcSteps : function(animtype, fromValue, toValue, nrOfSteps){ - var i, value; - var steps = [fromValue]; //Compile steps - var step = 0; - var scalex = (toValue - fromValue) / ((Math.pow(nrOfSteps, 2) - + 2 * nrOfSteps + 1) / (4 * nrOfSteps)); - - for (i = 0; i < nrOfSteps; i++) { - if (!animtype && !value) - value = (toValue - fromValue) / nrOfSteps; - else if (animtype == 1) - value = scalex * Math.pow(((nrOfSteps - i)) / nrOfSteps, 3); - else if (animtype == 2) - value = scalex * Math.pow(i / nrOfSteps, 3); - - steps.push(steps[steps.length - 1] - + value);// - (i == 0 ? 1 : 0));//Math.max(0, ) - } - steps[steps.length - 1] = toValue;// - 1;//Math.max(1, ); - - return steps; - }, - - /** - * Calculates all the steps of an animation between a - * begin and end value for colors - */ - $calcColorSteps : function(animtype, fromValue, toValue, nrOfSteps){ - var beginEnd = [fromValue, toValue]; - for (var i = 0; i < 2; i++) { - if(beginEnd[i].match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/)){ - beginEnd[i] = [parseInt(RegExp.$1), parseInt(RegExp.$2), parseInt(RegExp.$3)]; - continue; - } - - beginEnd[i] = beginEnd[i].replace(/^#/, ""); - if(beginEnd[i].length == 3) beginEnd[i] += beginEnd[i]; - - beginEnd[i] = [ - Math.hexToDec(beginEnd[i].substr(0,2)), - Math.hexToDec(beginEnd[i].substr(2,2)), - Math.hexToDec(beginEnd[i].substr(4,2)) - ]; - } - - var stepParts = [ - jpf.tween.$calcSteps(animtype, beginEnd[0][0], beginEnd[1][0], nrOfSteps), - jpf.tween.$calcSteps(animtype, beginEnd[0][1], beginEnd[1][1], nrOfSteps), - jpf.tween.$calcSteps(animtype, beginEnd[0][2], beginEnd[1][2], nrOfSteps) - ]; - - for (var steps = [], i = 0; i < stepParts[0].length; i++) { - steps.push("#" + Math.decToHex(stepParts[0][i]) - + Math.decToHex(stepParts[1][i]) - + Math.decToHex(stepParts[2][i])); - } - - return steps; - }, - - /** - * Tweens a single property of a single element or html element from a - * start to an end value. - * Example: - * <code> - * jpf.tween.single(myDiv, { - * type : "left", - * from : 10, - * to : 100, - * anim : jpf.tween.EASEIN - * }); - * </code> - * Example: - * Multiple animations can be run after eachother - * by calling this function multiple times. - * <code> - * jpf.tween.single(myDiv, options).single(myDiv2, options2); - * </code> - * @param {Element} oHtml the object to animate. - * @param {Object} info the animation settings. - * Properties: - * {String} type the property to be animated. These are predefined property handlers and can be added by adding a method to jpf.tween with the name of the property modifier. Default there are several handlers available. - * Possible values: - * left Sets the left position - * right Sets the right position - * top Sets the top position - * bottom Sets the bottom position - * width Sets the horizontal size - * height Sets the vertical size - * scrollTop Sets the scoll position - * mwidth Sets the width and the margin-left to width/2 - * mheight Sets the height ant the margin-top to height/2 - * scrollwidth Sets the width an sets the scroll to the maximum size - * scrollheight Sets the height an sets the scroll to the maximum size - * scrolltop Sets the height and the top as the negative height value - * fade Sets the opacity property - * bgcolor Sets the background color - * textcolor Sets the text color - * {Number, String} from the start value of the animation - * {Number, String} to the end value of the animation - * {Number} [steps] the number of steps to divide the tween in - * {Number} [interval] the time between each step - * {Number} [anim] the distribution of change between the step over the entire animation - * {Boolean} [color] whether the specified values are colors - * {Mixed} [userdata] any data you would like to have available in your callback methods - * {Function} [onfinish] a function that is called at the end of the animation - * {Function} [oneach] a function that is called at each step of the animation - * {Object} [control] an object that can stop the animation at any point - * Properties: - * {Boolean} stop whether the animation should stop. - */ - single : function(oHtml, info){ - info = jpf.extend({steps: 3, interval: 20, anim: jpf.tween.NORMAL, control: {}}, info); - - if (oHtml.nodeFunc > 100) { - info.oInt = oHtml.oInt; - oHtml = oHtml.oExt; - } - - if ("fixed|absolute|relative".indexOf(jpf.getStyle(oHtml, "position")) == -1) - oHtml.style.position = "relative"; - - info.method = jpf.tween[info.type]; - - if(!info.method) - throw new Error(jpf.formatErrorString(0, this, - "Single Value Tween", - "Could not find method for tweening operation '" - + info.type + "'")); - - var steps = info.color - ? jpf.tween.$calcColorSteps(info.anim, info.from, info.to, info.steps) - : jpf.tween.$calcSteps(info.anim, parseFloat(info.from), parseFloat(info.to), info.steps); - - var _self = this; - var stepFunction = function(step){ - _self.current = info; - if (info.control && info.control.stop) { - info.control.stop = false; - jpf.tween.clearQueue(oHtml); - return; - } - - try { - info.method(oHtml, steps[step], info); - } catch (e) {} - - if (info.oneach) - info.oneach(oHtml, info.userdata); - - if (step < info.steps) - timer = setTimeout(function(){stepFunction(step + 1)}, info.interval); - else { - _self.current = null; - if (info.control) - info.control.stopped = true; - if (info.onfinish) - info.onfinish(oHtml, info.userdata); - - jpf.tween.nextQueue(oHtml); - } - }; - - this.setQueue(oHtml, stepFunction); - - return this; - }, - - /** - * Tweens multiple properties of a single element or html element from a - * start to an end value. - * Example: - * Animating both the left and width at the same time. - * <code> - * jpf.tween.multi(myDiv, { - * anim : jpf.tween.EASEIN - * tweens : [{ - * type : "left", - * from : 10, - * to : 100, - * }, - * { - * type : "width", - * from : 100, - * to : 400, - * }] - * }); - * </code> - * Example: - * Multiple animations can be run after eachother - * by calling this function multiple times. - * <code> - * jpf.tween.multi(myDiv, options).multi(myDiv2, options2); - * </code> - * @param {Element} oHtml the object to animate. - * @param {Object} info the settings of the animation. - * Properties: - * {Number} [steps] the number of steps to divide the tween in - * {Number} [interval] the time between each step - * {Number} [anim] the distribution of change between the step over the entire animation - * {Function} [onfinish] a function that is called at the end of the animation - * {Function} [oneach] a function that is called at each step of the animation - * {Object} [control] an object that can stop the animation at any point - * Properties: - * {Boolean} stop whether the animation should stop. - * {Array} [tweens] a collection of simple objects specifying the single value animations that are to be executed simultaneously. (for the properties of these single tweens see the single tween method). - */ - multi : function(oHtml, info){ - info = jpf.extend({steps: 3, interval: 20, anim: jpf.tween.NORMAL, control: {}}, info); - - if (oHtml.nodeFunc > 100) { - info.oInt = oHtml.oInt; - oHtml = oHtml.oExt; - } - - for (var steps = [], i = 0; i < info.tweens.length; i++) { - var data = info.tweens[i]; - - data.method = jpf.tween[data.type] || jpf.tween.htmlcss; - - if (!data.method) - throw new Error(jpf.formatErrorString(0, this, - "Multi Value Tween", - "Could not find method for tweening operation '" - + data.type + "'")); - - steps.push(data.color - ? jpf.tween.$calcColorSteps(info.anim, data.from, data.to, info.steps) - : jpf.tween.$calcSteps(info.anim, parseFloat(data.from), parseFloat(data.to), info.steps)); - } - - var tweens = info.tweens; - var _self = this; - var stepFunction = function(step){ - _self.current = info; - if (info.control && info.control.stop) { - info.control.stop = false; - return; - } - - try { - for (var i = 0; i < steps.length; i++) { - tweens[i].method(oHtml, steps[i][step], tweens[i]); - } - } catch (e) {} - - if (info.oneach) - info.oneach(oHtml, info.userdata); - - if (step < info.steps) - timer = setTimeout(function(){stepFunction(step + 1)}, info.interval); - else { - _self.current = null; - if (info.control) - info.control.stopped = true; - if (info.onfinish) - info.onfinish(oHtml, info.userdata); - - jpf.tween.nextQueue(oHtml); - } - }; - - this.setQueue(oHtml, stepFunction); - - return this; - }, - - /** - * Tweens an element or html element from it's current state to a css class. - * Example: - * Multiple animations can be run after eachother by calling this function - * multiple times. - * <code> - * jpf.tween.css(myDiv, 'class1').multi(myDiv2, 'class2'); - * </code> - * @param {Element} oHtml the object to animate. - * @param {String} className the classname that defines the css properties to be set or removed. - * @param {Object} info the settings of the animation. - * Properties: - * {Number} [steps] the number of steps to divide the tween in - * {Number} [interval] the time between each step - * {Number} [anim] the distribution of change between the step over the entire animation - * {Function} [onfinish] a function that is called at the end of the animation - * {Function} [oneach] a function that is called at each step of the animation - * {Object} [control] an object that can stop the animation at any point - * Properties: - * {Boolean} stop whether the animation should stop. - * @param {Boolean} remove whether the class is set or removed from the element or html element - */ - css : function(oHtml, className, info, remove){ - (info = info || {}).tweens = []; - - if (oHtml.nodeFunc > 100) - oHtml = oHtml.oExt; - - if(remove) - jpf.setStyleClass(oHtml, "", [className]); - - var callback = info.onfinish; - info.onfinish = function(){ - if(remove) - jpf.setStyleClass(oHtml, "", [className]); - else - jpf.setStyleClass(oHtml, className); - - //Reset CSS values - for(var i=0;i<info.tweens.length;i++){ - if (info.tweens[i].type == "filter") - continue; - - oHtml.style[info.tweens[i].type] = ""; - } - - if (callback) - callback.apply(this, arguments); - } - - var result, newvalue, curvalue, j, isColor, style, rules, i; - for(i = 0; i < document.styleSheets.length; i++){ - rules = document.styleSheets[i][jpf.styleSheetRules]; - for (j = 0; j < rules.length; j++) { - var rule = rules[j]; - - if (!rule.style || !rule.selectorText.match('\.' + className + '$')) - continue; - - for(style in rule.style){ - if(!rule.style[style] || this.cssProps.indexOf("|" + style + "|") == -1) - continue; - - if (style == "filter") { - if (!rule.style[style].match(/opacity\=([\d\.]+)/)) - continue; - newvalue = RegExp.$1; - - result = (jpf.getStyleRecur(oHtml, style) || "") - .match(/opacity\=([\d\.]+)/); - curvalue = result ? RegExp.$1 : 100; - isColor = false; - - if (newvalue == curvalue) { - if (remove) curvalue = 100; - else newvalue = 100; - } - } - else { - newvalue = remove && oHtml.style[style] || rule.style[style]; - if (remove) oHtml.style[style] = ""; - curvalue = jpf.getStyleRecur(oHtml, style); - isColor = style.match(/color/i) ? true : false; - } - - info.tweens.push({ - type : style, - from : (isColor ? String : parseFloat)(remove - ? newvalue - : curvalue), - to : (isColor ? String : parseFloat)(remove - ? curvalue - : newvalue), - color : isColor, - needsPx : jpf.tween.needsPix[style.toLowerCase()] || false - }); - } - } - } - - if(remove) - jpf.setStyleClass(oHtml, className); - - return this.multi(oHtml, info); - }, - - needsPix : { - "left" : true, - "top" : true, - "bottom" : true, - "right" : true, - "fontSize" : true, - "lineHeight" : true, - "textIndent" : true - }, - - cssProps : "|backgroundColor|backgroundPosition|color|width|filter|\ - |height|left|top|bottom|right|fontSize|\ - |letterSpacing|lineHeight|textIndent|opacity|\ - |paddingLeft|paddingTop|paddingRight|paddingBottom|\ - |borderLeftWidth|borderTopWidth|borderRightWidth|borderBottomWidth|\ - |borderLeftColor|borderTopColor|borderRightColor|borderBottomColor|\ - |marginLeft|marginTop|marginRight|marginBottom|" -}; - - - -/*FILEHEAD(/var/lib/jpf/src/core/lib/printer.js)SIZE(-1077090856)TIME(1238944816)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * @define printer
- * Element providing printer control.
- * Example:
- * <code>
- * <j:appsettings>
- * <j:printer onbeforeprint="jpf.printer.preview(getHtml())" />
- * </j:appsettings>
- * </code>
- */
-jpf.printer = {
- tagName : "printer",
- nodeFunc : jpf.NODE_HIDDEN,
-
- lastContent : "",
- inited : false,
-
- init : function(jml){
- this.inited = true;
- this.$jml = jml;
-
- this.contentShower = document.body.appendChild(document.createElement("DIV"));
- this.contentShower.id = "print_content"
-
- with (this.contentShower.style) {
- width = "100%";
- height = "100%";
- backgroundColor = "white";
- zIndex = 100000000;
- }
-
- jpf.importCssString(document, "#print_content{display:none}");
- jpf.importCssString(document,
- "body #print_content, body #print_content *{display:block} body *{display:none}", "print");
-
- if (jml) {
- //Events
- var a, i, attr = jml.attributes;
- for (i = 0; i < attr.length; i++) {
- a = attr[i];
- if (a.nodeName.indexOf("on") == 0)
- jpf.addEventListener(a.nodeName, new Function(a.nodeValue));
- }
- }
-
- function printPNGFix(disable) {
- if (jpf.supportPng24) return;
- if (!jpf.appsettings.iePngFix) return;
- for (var e, i = 0, j = document.all.length; i < j; i++) {
- e = document.all[i];
- if (e.filters['DXImageTransform.Microsoft.AlphaImageLoader'] || e._png_print) {
- if (disable) {
- e._png_print = e.style.filter;
- e.style.filter = '';
- }
- else {
- e.style.filter = e._png_print;
- e._png_print = '';
- }
- }
- }
- }
-
- window.onbeforeprint = function(){
- printPNGFix(true);
- jpf.dispatchEvent("onbeforeprint");
- };
-
- window.onafterprint = function(){
- printPNGFix(false);
- jpf.dispatchEvent("onafterprint");
- };
- },
-
- preview : function(strHtml){
- if (!this.inited)
- this.init();
-
- if (typeof strHtml != "string")
- strHtml = strHtml.outerHTML || strHtml.xml || strHtml.serialize();
-
- this.lastContent = strHtml;
- this.contentShower.innerHTML = strHtml;
- }
-};
-
-/**
- * Sents html to a printer in formatted form.
- * @param {String} strHtml the html to be printed.
- */
-jpf.print = function(strHtml){
- if (!jpf.printer.inited)
- jpf.printer.init();
-
- jpf.printer.preview(strHtml);
- window.print();
-}
-
- - -/*FILEHEAD(/var/lib/jpf/src/core/lib/offline/detector.js)SIZE(-1077090856)TIME(1238944816)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * Object detecting if the application has network, the detection moments can
- * be manual, automatic or only when a communication error occurs. In most
- * cases the functionality of this object will be managed from within the
- * offline element in JML.
- * Example:
- * <code>
- * <j:offline
- * detect-url = "netork.txt"
- * detection = "auto"
- * interval = "2000" />
- * </code>
- *
- * @define offline
- * @attribute {String} [detect-url] a datainstruction for getting a version number of the current application
- * @attribute {String} [detection] a pipe seperated list of possible providers.
- * Possible values:
- * auto Automatically detect whether the network is available by retrieving the file specified in the detect-url attribute
- * manual Disable automatic or error based detection
- * error Only detect network state when a communication timeout occurs.
- * @attribute {Boolean} [interval] whether the required plugin is installed when it's not installed yet.
- *
- * @default_private
- */
-jpf.namespace("offline.detector", {
- detectUrl : jpf.basePath + "core/lib/offline/network_check.txt",
- detection : "auto", //manual|auto|error
- interval : 5000,
-
- init : function(jml){
- if (jml.nodeType) {
- if (jml.getAttribute("detect-url"))
- this.detectUrl = jml.getAttribute("detect-url");
- else
- this.detectUrl = (jpf.appsettings.resourcePath || jpf.basePath)
- + "resources/network_check.txt";
-
- this.detection = jpf.isTrue(jml.getAttribute("detection"))
- ? "auto"
- : jml.getAttribute("detection") || "auto";
-
- if (jml.getAttribute("interval"))
- this.interval = parseInt(jml.getAttribute("interval"));
- }
-
- if ("error|auto".indexOf(this.detection) > -1) {
- jpf.addEventListener("error", function(e){
- //Timeout detected.. Network is probably gone
- if (e.state == jpf.TIMEOUT) {
- //Let's try to go offline and return false to cancel the error
- return !jpf.offline.goOffline();//callback //@todo callback???
- }
- });
- }
-
- this.oHttp = new jpf.http();
- this.oHttp.timeout = this.interval;
-
- //Check if we have connection right now
- this.isSiteAvailable();
-
- if (this.detection == "auto")
- this.start();
- },
-
- isSiteAvailable : function(callback){
- this.oHttp.get(jpf.getNoCacheUrl(this.detectUrl),
- function(data, state, extra){
- if(state != jpf.SUCCESS || !window.navigator.onLine){
- jpf.offline.goOffline(callback); //retry here??
- }
- else{
- jpf.offline.goOnline(callback);
- }
- }, {
- ignoreOffline : true,
- hideLogMessage : true
- });
- },
-
- /**
- * Start automatic network availability detection
- */
- start : function(){
- clearInterval(this.timer);
-
- jpf.console.info("Automatic detection of network state is activated");
-
- var _self = this;
- this.timer = setInterval(function(){
- _self.isSiteAvailable();
- }, this.interval);
- },
-
- /**
- * Stop automatic network availability detection
- */
- stop : function(){
- clearInterval(this.timer);
-
- jpf.console.info("Detection of network state is deactivated");
- }
-});
-
- - -/*FILEHEAD(/var/lib/jpf/src/core/lib/offline/transactions.js)SIZE(-1077090856)TIME(1238944816)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * Object recording the state of actiontrackers. When an application goes
- * offline, the state is maintained such that it can be synced at a later date.
- * The actiontracker state can be maintained even when the application restarts.
- * In most cases the functionality of this object will be managed from within
- * the offline element in JML.
- * Example:
- * <code>
- * <j:offline ontransactioncancel="alert('You are currently offline')" />
- * </code>
- *
- * @define offline
- * @event transactioncancel Fires before installation of an offline provider
- * enableable Cancels the installation of the offline provider
- *
- * @default_private
- * @todo remove serialize here
- */
-jpf.namespace("offline.transactions", {
- enabled : false,
-
- init : function(){
- this.namespace = jpf.appsettings.name + ".jpf.offline.transactions";
- this.enabled = true;
-
- jpf.addEventListener("load", function(){
- jpf.offline.transactions.rebuildActionQueues();
- });
- },
-
- /**
- * data GET requests aren't synced but disallowed,
- * such as j:load/j:insert bindings and model load=""
- * This function will sent the ontransactioncancel event which
- * can be used to notify the user that we're offline.
- */
- actionNotAllowed : function(){
- jpf.offline.dispatchEvent("transactioncancel", {
- message : "Transaction is not allowed",
- bubbles : true
- });
-
- return;
- },
-
- //@todo you might want to error on dotts in the at name
- addAction : function(at, qItem, type){
- if (!at.name || !jpf.storage.base.isValidKey(at.name)) {
- //@todo
- throw new Error("Invalid or missing name for actiontracker \
- used for offline transactions '" + at.name + "'.");
- }
-
- var namespace = this.namespace + "." + at.name + "." + type;
- var storage = jpf.offline.storage;
- var len = parseInt(storage.get("length", namespace)) || 0;
-
- storage.put(len, jpf.serialize(type == "queue"
- ? {
- undo : qItem.undo,
- undoObj : qItem.undoObj.$export()
- }
- : qItem.$export()), namespace);
- storage.put("length", ++len, namespace);
- },
-
- removeAction : function(at, fromTop, type){
- var namespace = this.namespace + "." + at.name + "." + type;
- var storage = jpf.offline.storage;
-
- //@todo add checks for stack sanity
- if (fromTop) {
- var len = parseInt(storage.get("length", namespace)) - 1;
- var start = parseInt(storage.get("start", namespace)) || 0;
-
- if (len < 0) {//@todo
- throw new Error("something went terribly wrong");
- }
-
- if (start == len || len < 0) {
- storage.clear(namespace);
- return;
- }
-
- storage.remove(len, namespace);
- storage.put("length", len, namespace);
- }
- else {
- var start = parseInt(storage.get("start", namespace)) || 0;
- var len = parseInt(storage.get("length", namespace)) || 0;
-
- if (start + 1 == len) {
- storage.clear(namespace);
- return;
- }
-
- storage.remove(start, namespace)
- storage.put("start", ++start, namespace);
- }
- },
-
- rebuildActionQueues : function(){
- var storage = jpf.offline.storage;
- var namespaces = storage.getNamespaces();
- var lookup, re = new RegExp(this.namespace + "\\.([^\\.]*)\\.([^\\.]*)");
-
- for (var ats = [], i = 0;i < namespaces.length; i++) {
- if (namespaces[i].match(re))
- ats.push([RegExp.$1, RegExp.$2]);
- }
-
- var i, j, qItem, stack, namespace, at, start, len, type;
- for (i = 0; i < ats.length; i++) {
- at = jpf.nameserver.get("actiontracker", ats[i][0]);
- type = ats[i][1];
-
- if (!at) { //@todo
- throw new Error(jpf.formatErrorString(0, null,
- "Rebuilding Action Queue",
- "An actiontracker could not be found by the name of '"
- + ats[i][0] + "'"));
- }
-
- lookup = {};
- namespace = this.namespace + "." + at.name + "." + type;
- storage.getAllPairs(namespace, lookup);
-
- start = parseInt(lookup["start"]) || 0;
- len = parseInt(lookup["length"]) || 0;
- stack = [];
-
- jpf.console.info("Restoring " + type + " stack for "
- + (at.name == "default"
- ? "the default actiontracker"
- : "the '" + at.name + "' actiontracker")
- + " of " + len + " items.");
-
- if (type == "queue") {
- for (j = len - 1; j >= start; j--) {
- qItem = jpf.unserialize(lookup[j]);
- qItem.undoObj = new jpf.UndoData(qItem.undoObj, at).$import();
- stack.unshift(qItem);
- }
- }
- else {
- for (j = len - 1; j >= start; j--) {
- qItem = jpf.unserialize(lookup[j]);
- stack.unshift(new jpf.UndoData(qItem, at).$import());
- }
- }
-
- at.$loadQueue(stack, type);
-
- jpf.offline.sLookup = null;
- }
- },
-
- clearActions : function(at, type){
- jpf.offline.storage.clear(this.namespace + "." + at.name + "." + type);
- },
-
- clear : function(queues){
- if (!queues)
- queues = "undo|redo|queue";
-
- var storage = jpf.offline.storage;
- var namespaces = storage.getNamespaces();
- var re = new RegExp(this.namespace + "\\.([^\\.]*)\\.(" + queues + ")");
-
- for (var i = 0; i < namespaces.length; i++) {
- if (namespaces[i].match(re))
- storage.clear(namespaces[i]);
- }
- },
-
- stopSync : function(callback){
- //No stopping here.. the queue will fill itself automatically
- callback();
- },
-
- getSyncLength : function(){
- var ats = jpf.nameserver.getAll("actiontracker");
-
- var len = 0;
- for (var i = 0; i < ats.length; i++)
- len += ats[i].$getQueueLength();
-
- return len;
- },
-
- sync : function(callback){
- var ats = jpf.nameserver.getAll("actiontracker");
-
- var qNr = 0, len = 0;
- for (var i = 0; i < ats.length; i++) {
- if (ats[i].$getQueueLength()) {
- len += ats[i].$getQueueLength();
- ats[i].$startQueue(function(last){
- if (qNr >= len - 1)
- return false; //silently ignore later changes... (might be wrong)
-
- if (last)
- qNr = len;
-
- callback({
- position : ++qNr,
- length : len
- });
-
- if(qNr >= len - 1)
- callback({finished: true});
- });
- }
- }
- }
-});
-
-jpf.namespace("offline.canTransact", function(){
- if(!jpf.offline.enabled || this.onLine || this.transactions.enabled)
- return true;
-
- //Transactions can be enabled from this event
- if(this.dispatchEvent("transactioncancel", {
- message : "Could not execute transaction whilst being offline,\
- silently doing nothing",
- bubbles : true
- }) === true)
- return true;
-
- return false;
-});
- - -/*FILEHEAD(/var/lib/jpf/src/core/lib/offline/queue.js)SIZE(-1077090856)TIME(1224578766)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * Object handling queuing of actions that can only be executed whilst online.
- * These actions are stored in the queue and executed in serie when the
- * application comes online again. This is done after jpf.auth has logged the
- * user into the application again, if necesary. This object is used for HTTP
- * XMPP and Webdav, but is general purpose and can be used to store any
- * action that should only be executed while online.
- *
- * @default_private
- */
-jpf.namespace("offline.queue", {
- enabled : false,
- stack : [],
-
- init : function(){
- this.namespace = jpf.appsettings.name + ".jpf.offline.queue";
- this.enabled = true;
- },
-
- add : function(commInfo){
- var namespace = this.namespace;
- var storage = jpf.offline.storage;
- var len = parseInt(storage.get("length", namespace)) || 0;
-
- //Add the commInfo to the stack
- this.stack[len] = commInfo; //retry this on sync
-
- //Check here for xml nodes in storeInfo??
-
- //Store http info
- storage.put(len, jpf.serialize(commInfo), namespace);
- storage.put("length", ++len, namespace);
-
- /*
- If there's a callback, we'll inform it that we're not
- executing the call because we're offline.
- */
- var callback = commInfo.callback;
- if (!commInfo.undoObj && callback) {
- var strWarn = "The application is currently offline. Your \
- request will be retried when the application \
- goes online again. Please be aware that when the\
- request is finally made, this callback might\
- not be available anymore. Therefore the state of\
- the data should already represent the state of\
- the application that a succesfull execution of\
- the request communicates. You might want to look\
- at using an actiontracker.";
-
- jpf.console.warn(strWarn);
-
- callback(null, jpf.OFFLINE, jpf.extend({
- offline : true
- , message : strWarn
- }, commInfo));
- }
- },
-
- stopSync : function(callback){
- this.stop = callback;
- },
-
- getSyncLength : function(){
- return parseInt(jpf.offline.storage.get("length", this.namespace)) || 0;
- },
-
- //Sync all transactions, let offline decide when
- sync : function(callback, isStarted){
- if (this.stop) {
- this.stop();
- this.stop = null;
- return
- }
-
- var namespace = this.namespace;
- var storage = jpf.offline.storage;
- var len = parseInt(storage.get("length", namespace)) || 0;
- var start = parseInt(storage.get("start", namespace)) || 0;
- var commInfo;
-
- if (this.stack[start]) {
- commInfo = this.stack[start];
- }
- else {
- commInfo = this.$getCommInfo(storage.get(start, namespace));
- if (!commInfo) {
- jpf.console.error("Error syncing queue items. This is a serious\
- error. The queue stack has become corrupted. It will now be \
- cleared and the queued offline messages will be lost!"); //@todo
-
- this.clear();
- jpf.offline.stopSync();
-
- return callback({finished: true});
- }
-
- this.stack[start] = commInfo;
- }
-
- if (!commInfo.callback2) {
- commInfo.callback2 = commInfo.callback;
-
- commInfo.callback = function(data, state, extra){
- //We'll let the main callback decide if this one should be retries
- if (commInfo.callback2 &&
- commInfo.callback2.apply(window, arguments) === true) {
- //@todo: Warning here??
-
- return true;
- }
-
- // We're done with this one
- storage.remove(start, namespace);
- storage.put("start", start+1, namespace);
- jpf.offline.queue.stack[start] = null;
-
- callback({
- position : start,
- length : len,
- info : commInfo
- });
-
- if (start == len - 1) {
- //Sync is completely done
- storage.clear(namespace);
-
- callback({
- finished : true
- });
- }
- else {
- //Next!
- jpf.offline.queue.sync(callback, true);
- }
- }
- }
-
- this.stack[start].retry();
- },
-
- clear : function(){
- jpf.offline.storage.clear(this.namespace);
- },
-
- $getCommInfo : function(strCommItem){
- if (!strCommItem)
- return false;
-
- var commObject, commInfo = jpf.unserialize(strCommItem);
- for (var i = 0; i < commInfo.$object.length; i++) {
- commObject = self[commInfo.$object[i]] || eval(commInfo.$object[i]);
- if (commObject)
- break;
- }
-
- if (!commObject) {
- //@todo
- }
-
- commInfo.object = commObject;
- commInfo.retry = new Function(commInfo.$retry);
-
- return commInfo;
- }
-});
-
- - -/*FILEHEAD(/var/lib/jpf/src/core/lib/offline/models.js)SIZE(-1077090856)TIME(1238944816)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * Object dealing with the storing the state of models for use offline. In
- * most cases the functionality of this object will be managed from within the
- * offline element in JML.
- * Example:
- * <code>
- * <j:offline realtime="true" />
- * </code>
- *
- * @define offline
- * @attribute {Boolean} [realtime] whether changes are stored realtime.
- *
- * @default_private
- */
-jpf.namespace("offline.models", {
- enabled : false,
- timer : null,
- models : {},
- initQueue : [],
- realtime : true,
-
- init : function(jml){
- this.namespace = jpf.appsettings.name + ".jpf.offline.models";
-
- if (jml.nodeType && jml.getAttribute("realtime"))
- this.realtime = !jpf.isFalse(jml.getAttribute("realtime"));
-
- if (!this.realtime) {
- jpf.addEventListener("exit", function(){
- jpf.offline.models.search();
- });
- }
-
- //@todo what to do if we're not realtime
-
- this.enabled = true;
- },
-
- markForUpdate : function(model){
- this.models[model.uniqueId] = model;
-
- if(!this.timer){
- var _self = this;
- this.timer = setTimeout(function(){
- _self.timer = null;
- var models = _self.models;
-
- for (var mId in models) {
- _self.updateModel(models[mId]);
- }
-
- _self.models = {};
- }, 2000);
- }
- },
-
- clear : function(){
- jpf.offline.storage.clear(this.namespace);
- },
-
- removeModel : function(model){
- var name = model.name || model.uniqueId + ".model";
-
- //Remove recorded data of this model
- jpf.offline.storage.remove(name, this.namespace);
-
- //Remove the model from the init queue
- this.initQueue.remove(model);
- },
-
- updateModel : function(model){
- var name = model.name || model.uniqueId + ".model";
-
- jpf.console.info("Updating model '" + name + "'");
-
- /*
- This could be optimized by only recording the changes to the
- data. At load/exit these could be purged.
- */
-
- var docId = model.data.getAttribute(jpf.xmldb.xmlDocTag);
- model.data.setAttribute(jpf.xmldb.xmlDocTag + "_length",
- jpf.xmldb.nodeCount[docId]);
-
- jpf.offline.storage.put(name, model.data.xml || model.data.serialize(), this.namespace);
- },
-
- loadModel : function(model){
- var name = model.name || model.uniqueId + ".model";
-
- var data = jpf.offline.storage.get(name, this.namespace);
- if (!data) return false;
-
- jpf.console.info("Loading model '" + name + "' from local storage");
-
- var xmlNode = jpf.getXmlDom(data).documentElement;
- var docId = xmlNode.getAttribute(jpf.xmldb.xmlDocTag);
- jpf.xmldb.nodeCount[docId]
- = parseInt(xmlNode.getAttribute(jpf.xmldb.xmlDocTag + "_length"));
-
- model.load(xmlNode);
- return true;
- },
-
- search : function(){
- //Save all the models
-
- var done = {}, models = jpf.nameserver.getAll("model");
- for (var i = 0; i < models.length; i++) {
- if (done[models[i].uniqueId])
- continue;
-
- done[models[i].uniqueId] = true;
- this.updateModel(models[i]);
- }
-
- return true;
- },
-
- addToInitQueue : function(model){
- this.initQueue.pushUnique(model);
- model.session = false;
- },
-
- stopSync : function(callback){
- //No stopping here.. the queue will fill itself automatically
- callback();
- },
-
- getSyncLength : function(){
- return this.initQueue.length;
- },
-
- sync : function(callback){
- //We assume we're online now, but just in case we clear the queue
- var queue = this.initQueue.slice();
- this.initQueue.length = 0;
-
- var qNr = 0, len = queue.length;
- for (var i = 0; i < queue.length; i++) {
- queue[i].init(function(){
- callback({
- position : ++qNr,
- length : len
- });
-
- if(qNr == len - 1)
- callback({finished: true});
- });
- }
- }
-});
-
- - -/*FILEHEAD(/var/lib/jpf/src/core/lib/offline/application.js)SIZE(-1077090856)TIME(1238944816)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * Object handling the offline state of the application resources. This includes
- * the files that contain application logic themselve. In most cases the
- * functionality of this object will be managed from within the offline
- * element in JML.
- * Example:
- * <code>
- * <j:offline
- * version-get = "url:version.php"
- * providers = "gears|air"
- * auto-install = "true" />
- * </code>
- *
- * @define offline
- * @event beforeinstall Fires before installation of an offline provider
- * cancellable: Cancels the installation of the offline provider
- * @event afterinstall Fires after installation of an offline provider
- *
- * @attribute {String} [version-get] a datainstruction for getting a version number of the current application
- * @attribute {String} [providers] a pipe seperated list of possible providers.
- * Possible values:
- * gears Uses the Google Gears plugin for storage of application files
- * @attribute {Boolean} [auto-install] whether the required plugin is installed when it's not installed yet.
- *
- * @default_private
- * @todo a later version should also clear models and thus undo state
- */
-jpf.namespace("offline.application", {
- enabled : false,
- urls : [],
- providers : ["deskrun", "gears"],
-
- init : function(jml){
- if (this.enabled)
- return;
-
- this.namespace = jpf.appsettings.name + ".jpf.offline.application";
-
- if (typeof jml == "string") {
- this.providers = jml.split("|");
- }
- else if (jml.nodeType) {
- if (jml.getAttribute("version-get"))
- this.application.versionGet = jml.getAttribute("version-get");
-
- if (jml.getAttribute("providers"))
- this.providers = jml.getAttribute("providers").split("|");
-
- if (jml.getAttribute("auto-install"))
- this.autoInstall = jpf.isTrue(jml.getAttribute("auto-install"));
- }
-
- //Check for an available offline provider
- for (var i = 0; i < this.providers.length; i++) {
- if (!this[this.providers[i]]) {
- jpf.console.warn("Module not loaded for offline provider: "
- + this.providers[i]);
- continue;
- }
-
- if (this[this.providers[i]].isAvailable()) {
- this.provider = this[this.providers[i]].init(this.storeName);
-
- if (this.provider !== false) {
- this.provider.name = this.providers[i];
- break;
- }
- }
- }
-
- //@todo if online please check if the latest version is loaded here
-
- if (!this.provider) {
- if (this.autoInstall) {
- if (this.install() === false) {
- jpf.console.warn("Could not install any of the preferred \
- offline providers:"
- + this.providers.join(", "));
-
- jpf.offline.application = null; //Can't put the app offline
- return this.providers[0];
- }
- }
- else {
- jpf.console.warn("Could not find any of the specified \
- offline providers:"
- + this.providers.join(", "));
-
- jpf.offline.application = null; //Can't put the app offline
- return this.providers[0];
- }
- }
-
- if (!jpf.loaded) { //@todo you might want to consider creating single run events
- jpf.addEventListener("load", function(){
- if (jpf.offline.application.enabled)
- jpf.offline.application.save();
- });
- }
- else {
- jpf.offline.addEventListener("load", function(){
- jpf.offline.application.save();
- });
- }
-
- this.enabled = true;
-
- return this.provider.name;
- },
-
- install : function(){
- if (jpf.offline.dispatchEvent("beforeinstall") === false) {
- jpf.console.warn("Installation cancelled");
- return false;
- }
-
- for (var i = 0; i < this.providers.length; i++) {
- if (!this[this.providers[i]])
- continue;
-
- if (this[this.providers[i]].install()) {
- this.provider = this[this.providers[i]].init(this.storeName);
-
- if (this.provider !== false)
- break;
- }
- }
-
- jpf.offline.dispatchEvent("afterinstall");
-
- if (!this.provider)
- return false;
- },
-
- clear : function(){
- if (this.provider)
- this.provider.clear();
- },
-
- cache : function(url){
- //if(!new jpf.url(url).isSameLocation())
- //return;
- if (url.indexOf(":") > -1 && url.indexOf("http://" + location.host) == -1)
- return;
-
- this.urls.pushUnique(url.replace(/\#.*$/, ""));
- },
-
- remove : function(url){
- this.urls.remove(url)
- },
-
- refresh : function(callback){
- var storage = jpf.offline.storage;
-
- if(this.versionGet){
- var oldVersion = storage.get("oldVersion", this.namespace);
- var newVersion = null;
- var _self = this;
-
- jpf.getData(this.versionGet, null, null,
- function(newVersion, state, extra){
- if (state == jpf.TIMEOUT)
- return extra.tpModule.retryTimeout(extra, state, jpf.offline);
-
- if (state == jpf.OFFLINE)
- return;
-
- if (state == jpf.ERROR)
- storage.remove("oldVersion", _self.namespace);
-
- if (jpf.debug || !newVersion || !oldVersion
- || oldVersion != newVersion){
-
- jpf.console.info("Refreshing offline file list");
-
- if (jpf.offline.state.enabled) {
- jpf.offline.state.clear();
-
- if (jpf.offline.state.realtime)
- jpf.offline.state.search();
- }
-
- _self.search();
- _self.provider.store(_self.urls,
- callback, newVersion);
- }
- else{
- jpf.console.info("No need to refresh offline file list");
-
- callback({
- finished : true
- });
- }
- });
- }
- else{
- jpf.console.info("Refreshing offline file list");
-
- this.search();
- this.provider.store(this.urls, callback);
- }
- },
-
- //forEach???
- search : function(){
- //Html based sources
- this.cache(window.location.href);
-
- var i, nodes = document.getElementsByTagName("script");
- for (i = 0; i < nodes.length; i++)
- this.cache(nodes[i].getAttribute("src"));
-
- nodes = document.getElementsByTagName("link");
- for (i = 0; i < nodes.length; i++){
- if((nodes[i].getAttribute("rel") || "").toLowerCase() == "stylesheet")
- continue;
-
- this.cache(nodes[i].getAttribute("href"));
- }
-
- nodes = document.getElementsByTagName("img");
- for (i = 0; i < nodes.length; i++)
- this.cache(nodes[i].getAttribute("src"));
-
- nodes = document.getElementsByTagName("a");
- for (i = 0; i < nodes.length; i++)
- this.cache(nodes[i].getAttribute("href"));
-
- // @todo handle 'object' and 'embed' tag
-
- // parse our style sheets for inline URLs and imports
- var _self = this, j, rule, sheet, sheets = document.styleSheets;
- for (i = 0; i < sheets.length; i++) {
- sheet = sheets[i];
- if (jpf.isIE) { //@todo multibrowser test this
- if (sheet.readOnly) {
- sheet.cssText.replace(/url\(\s*([^\) ]*)\s*\)/gi, function(m, url){
- _self.cache(url);
- return "";
- });
- }
- }
- else {
- if (sheet.ownerNode.tagName == "STYLE")
- continue;
-
- for (j = 0; j < sheet.cssRules.length; j++) {
- rule = sheet.cssRules[j].cssText;
- if(!rule)
- continue;
-
- rule.replace(/url\(\s*([^\) ]*)\s*\)/gi, function(m, url){
- _self.cache(url);
- return "";
- });
- }
- }
- }
-
- //Cache Skin CSS
- jpf.skins.loadedCss.replace(/url\(\s*([^\) ]*)\s*\)/gi, function(m, url){
- _self.cache(url);
- return "";
- });
-
- //Jml based sources
- if (jpf.JmlParser.$jml) {
- function callback(item){
- if(!item.nodeType) return;
-
- var nodes = item.selectNodes("//include/@src|//skin/@src");
- for (var i = 0; i < nodes.length; i++) {
- _self.cache(nodes[i].nodeValue);
- }
- }
-
- callback(jpf.JmlParser.$jml);
- jpf.includeStack.forEach(callback);
- }
-
- //Cached resources??
- },
-
- save : function(callback){
- if (!jpf.offline.onLine) {
- var func = function(){
- jpf.offline.application.save();
- jpf.offline.removeEventListener("afteronline", func)
- }
- jpf.offline.addEventListener("afteronline", func);
-
- return;
- }
-
- this.refresh(callback);
- }
-});
- - -/*FILEHEAD(/var/lib/jpf/src/core/lib/offline/gears.js)SIZE(-1077090856)TIME(1225628611)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * Offline provider that uses Google gears.
- * @default_private
- */
-jpf.namespace("offline.application.gears", {
- localServer : null,
- lastStore : null,
- cancelID : null,
- refreshing : false,
- fileIndex : 0,
-
- init : function(){
- // clip at 64 characters, the max length of a resource store name
- this.name = this.storeName.truncate(64);
- this.storeName = jpf.appsettings.name + ".jpf.offline";
-
- try{
- this.localServer = jpf.nameserver.get("google", "gears").create("beta.localserver", "1.0");
- }
- catch(e){
- jpf.console.warn("Error loading gears: " + e.message);
- return false;
- }
-
- return this;
- },
-
- install : function(){
- //@todo make a script to install gears here
-
- jpf.isGears = true;
- },
-
- isAvailable : function(){
- return jpf.isGears && location.protocol != "file:";
- },
-
- clear : function(){
- this.localServer.removeStore(this.name);
- },
-
- store : function(listOfURLs, callback, newVersion){
- // refresh everything by simply removing
- // any older stores
- this.localServer.removeStore(this.name);
-
- // open/create the resource store
- this.localServer.openStore(this.name);
-
- try {
- var store = this.lastStore = this.localServer.createStore(this.name);
- }
- catch(e) {
- jpf.console.warn("Gears failed to start local storage: " + e.message);
-
- return false;
- }
-
- // add our list of files to capture
- var _self = this;
- this.refreshing = true;
- this.fileIndex = 0;
- this.cancelID = store.capture(listOfURLs,
- function(url, success, captureId){
- if (!success && _self.refreshing) {
- _self.cancelID = null;
- _self.refreshing = false;
-
- if (callback) {
- callback({
- error : true,
- message : "Unable to capture " + url
- });
- }
-
- return;
- }
- else if (success) {
- _self.fileIndex++;
-
- if (callback) {
- callback({
- position : _self.fileIndex,
- length : listOfURLS.length // @fixme: where is listOfURLS ???
- });
- }
- }
-
- if (success && _self.fileIndex >= listOfURLs.length) {
- _self.cancelID = null;
- _self.refreshing = false;
-
- if(newVersion)
- jpf.storage.put("oldVersion", newVersion, null,
- jpf.offline.application.storeName);
-
- if (callback) {
- callback({
- finished : true
- });
- }
- }
- });
- },
-
- abort: function(){
- // summary:
- // For advanced usage; most developers can ignore this.
- // Aborts and cancels a refresh.
- if (!this.refreshing)
- return;
-
- this.lastStore.abortCapture(this.cancelID);
- this.refreshing = false;
- }
-});
-
- - -/*FILEHEAD(/var/lib/jpf/src/core/lib/offline/state.js)SIZE(-1077090856)TIME(1238944816)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-
-/**
- * Object recording the state of all elements. If the realtime attribute is
- * set the state of the elements is recorded realtime. Otherwise it is
- * recorded only when the application exits. During startup the state of the
- * application can be restored by cancelling the 'restore' event. In most cases
- * the functionality of this object will be managed from within the offline
- * element in JML.
- * Example:
- * <code>
- * <j:offline
- * realtime = "true"
- * set = "url:store_session.jsp"
- * onrestore = "return confirm('Would you like to continue where you left of?')" />
- * </code>
- *
- * @event restore Fires before restoring the application to the predefined state.
- * cancellable: Loads the stored state into the applicaton.
- *
- * @define offline
- * @attribute {String} [set] a datainstruction that stores the state of the application to an external data store.
- *
- * @default_private
- * @todo optimize by not getting the default values from the jml
- */
-jpf.namespace("offline.state", {
- enabled : false,
- states : {},
- realtime : true,
- lookup : {}, -
- init : function(jml){
- this.namespace = jpf.appsettings.name + ".jpf.offline.state";
-
- if (jml.nodeType) {
- if (jml.getAttribute("realtime"))
- this.realtime = !jpf.isFalse(jml.getAttribute("realtime"));
-
- if (jml.getAttribute("set"))
- this.setInstruction = jml.getAttribute("set");
- }
-
- jpf.addEventListener("exit", function(){
- if (!jpf.offline.state.realtime) {
- //jpf.offline.state.search();
- var lookup = jpf.offline.state.lookup;
- var storage = jpf.offline.storage;
- var ns = jpf.offline.state.namespace;
-
- for (var key in lookup) {
- var ns = jpf.offline.state.namespace;
- storage.put(key, lookup[key], ns);
- }
- }
-
- if (jpf.offline.state.setInstruction)
- jpf.offline.state.send();
- });
-
- var registry = jpf.extend({}, jpf.offline.storage || jpf.storage);
- registry.namespace = jpf.appsettings.name + ".jpf.registry";
- jpf.registry.$export(registry);
- jpf.registry = registry;
-
- //@todo This could be optimized if needed
- if (jpf.offline.storage.getAllPairs(this.namespace, this.lookup)) {
- /*
- This is the moment the developer should do something like:
- return confirm("Would you like to continue your previous session?");
- */
- if (jpf.offline.dispatchEvent("restore") === false) {
- this.clear();
- this.lookup = {};
-
- jpf.offline.transactions.clear("undo|redo");
- }
- }
-
-
- jpf.offline.transactions.doStateSync = true;
-
- this.enabled = true;
- },
-
- warned : false,
- timeout : {},
- set : function(obj, key, value){
- if (!obj.name && !this.warned) {
- this.warned = true;
- jpf.console.warn("Components found without name. This means that \
- when the application changes the state \
- serialization can break.");
- }
-
- if (!obj.tagName)
- return;
-
- var name = obj.name || obj.uniqueId + "_" + obj.tagName;
- var storage = jpf.offline.storage;
-
- if (!name || !storage.isValidKey(name)) { //@todo
- throw new Error("invalid")
- }
-
- if (!storage.isValidKey(key)) { //@todo
- throw new Error("invalid")
- }
-
- /*
- Using a timeout here, is an optimization for fast changing
- properties such as slider values.
- */
- key = name + "." + key;
- this.lookup[key] = value;
-
- if (!this.realtime)
- return;
-
- var ns = this.namespace;
- clearTimeout(this.timeout[key]);
- this.timeout[key] = setTimeout(function(){
- storage.put(key, value, ns);
- }, 200);
- },
-
- get : function(obj, key, value){
- return this.lookup[(obj.name || obj.uniqueId + "_" + obj.tagName) + "." + key];
-
- /*return jpf.offline.storage.get(
- (obj.name || obj.uniqueId + "." + obj.tagName) + "." + key,
- this.namespace);*/
- },
-
- //blrgh.. unoptimized
- getAll : function(obj) {
- var res = {}, x, name = obj.name || obj.uniqueId + "_" + obj.tagName;
- for (prop in this.lookup) {
- x = prop.split(".");
- if (x[0] == name)
- res[x[1]] = this.lookup[prop];
- }
-
- return res;
- },
-
- clear : function(){
- jpf.offline.storage.clear(this.namespace);
-
- var ns = jpf.registry.getNamespaces();
- for (var i = 0; i < ns.length; i++) {
- jpf.registry.clear(ns[i]);
- }
-
- jpf.offline.transactions.clear("undo|redo");
- },
- - search : function(){
- var storage = jpf.offline.storage;
-
- //Search for dynamic properties
- var props, i, j, nodes = jpf.all;
- for (i = 0; i < nodes.length; i++) {
- if (nodes[i].name && nodes[i].getAvailableProperties) {
- props = nodes[i].getAvailableProperties();
- for (j = 0; j < props.length; j++) {
- if (nodes[i][props[j]])
- this.set(nodes[i], props[j], nodes[i][props[j]]);
- }
- }
- }
-
- //@todo Search for actiontracker stacks
-
- //@todo Search for selection states
- },
-
- send : function(){
- var storage = jpf.offline.storage;
-
- var data = {};
- var keys = storage.getKeys(this.namespace);
-
- for (var i = 0; i < keys.length; i++) {
- data[keys[i]] = storage.get(keys[i], this.namespace);
- }
-
- jpf.saveData(this.setInstruction, null, {
- ignoreOffline : true,
- data : jpf.serialize(data)
- }, function(data, state, extra){
- if (extra.tpModule.retryTimeout(extra, state, jpf.offline) === true)
- return true;
- });
- }
-});
- - -/*FILEHEAD(/var/lib/jpf/src/core/lib/util/flash.js)SIZE(-1077090856)TIME(1228077595)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - -/** - * Helper class that aids in creating and controlling Adobe Flash - * elements. - * - * @author Mike de Boer - * @version %I%, %G% - * @since 1.0 - * @namespace jpf - */ -jpf.flash = (function(){ - /** - * Flash Player Version Detection, version 1.7 - * Detect Client Browser type - * - * @type {String} - */ - function getControlVersion(){ - var version, axo, e; - - // NOTE : new ActiveXObject(strFoo) throws an exception if strFoo isn't in the registry - try { - // version will be set for 7.X or greater players - axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7"); - version = axo.GetVariable("$version"); - } - catch (e) {} - if (!version) { - try { - // version will be set for 6.X players only - axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6"); - // installed player is some revision of 6.0 - // GetVariable("$version") crashes for versions 6.0.22 through 6.0.29, - // so we have to be careful. - // default to the first public version - version = "WIN 6,0,21,0"; - // throws if AllowScripAccess does not exist (introduced in 6.0r47) - axo.AllowScriptAccess = "always"; - // safe to call for 6.0r47 or greater - version = axo.GetVariable("$version"); - } - catch (e) {} - } - - if (!version) { - try { - // version will be set for 4.X or 5.X player - axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3"); - version = axo.GetVariable("$version"); - } - catch (e) {} - } - - if (!version) { - try { - // version will be set for 3.X player - axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3"); - version = "WIN 3,0,18,0"; - } - catch (e) {} - } - - if (!version) { - try { - // version will be set for 2.X player - axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash"); - version = "WIN 2,0,0,11"; - } - catch (e) { - version = -1; - } - } - - return version; - } - - /** - * JavaScript helper, required to detect Flash Player PlugIn version - * information. - * @see getControlVersion() for Internet Explorer (ActiveX detection) - * - * @type {String} - */ - function getSwfVersion(){ - // NS/Opera version >= 3 check for Flash plugin in plugin array - var flashVer = -1; - var sAgent = navigator.userAgent.toLowerCase(); - - if (navigator.plugins != null && navigator.plugins.length > 0) { - if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) { - var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : ""; - var swfDescr = navigator.plugins["Shockwave Flash" + swVer2].description; - var aDescr = swfDescr.split(" "); - var aTempMaj = aDescr[2].split("."); - var nMajor = aTempMaj[0]; - var nMinor = aTempMaj[1]; - var sRev = aDescr[3]; - if (sRev == "") - sRev = aDescr[4]; - if (sRev[0] == "d") - sRev = sRev.substring(1); - else if (sRev[0] == "r") { - sRev = sRev.substring(1); - if (sRev.indexOf("d") > 0) - sRev = sRev.substring(0, sRev.indexOf("d")); - } - var flashVer = nMajor + "." + nMinor + "." + sRev; - } - } - // MSN/WebTV 2.6 supports Flash 4 - else if (sAgent.indexOf("webtv/2.6") != -1) - flashVer = 4; - // WebTV 2.5 supports Flash 3 - else if (sAgent.indexOf("webtv/2.5") != -1) - flashVer = 3; - // older WebTV supports Flash 2 - else if (sAgent.indexOf("webtv") != -1) - flashVer = 2; - else if (jpf.isIE && !jpf.isOpera) - flashVer = getControlVersion(); - - return flashVer; - } - - /** - * When called with reqMajorVer, reqMinorVer, reqRevision returns true if - * that version or greater is available on the clients' system. - * - * @param {Number} reqMajorVer - * @param {Number} reqMinorVer - * @param {Number} reqRevision - * @type {Boolean} - */ - function detectFlashVersion(reqMajorVer, reqMinorVer, reqRevision){ - var versionStr = getSwfVersion(); - if (versionStr == -1) - return false; - else if (versionStr != 0) { - var aVersions; - if (jpf.isIE && !jpf.isOpera) { - // Given "WIN 2,0,0,11" - var aTemp = versionStr.split(" "); // ["WIN", "2,0,0,11"] - var sTemp = aTemp[1]; // "2,0,0,11" - aVersions = sTemp.split(","); // ['2', '0', '0', '11'] - } - else - aVersions = versionStr.split("."); - var nMajor = aVersions[0]; - var nMinor = aVersions[1]; - var sRev = aVersions[2]; - - // is the major.revision >= requested major.revision AND the minor version >= requested minor - if (nMajor > parseFloat(reqMajorVer)) - return true; - else if (nMajor == parseFloat(reqMajorVer)) { - if (nMinor > parseFloat(reqMinorVer)) - return true; - else if (nMinor == parseFloat(reqMinorVer)) { - if (sRev >= parseFloat(reqRevision)) - return true; - } - } - return false; - } - } - - /** - * Generate ActiveContent for a Flash or Shockwave movie, while ensuring - * compatibility with the clients' browser. - * - * @param {Object} objAttrs - * @param {Object} params - * @param {Object} embedAttrs - * @param {Boolean} stdout If TRUE, the resulting string will be passed to the output buffer through document.write() - * @type {String} - */ - function generateObj(objAttrs, params, embedAttrs, stdout){ - if (stdout == "undefined") - stdout = false; - var str = []; - if (jpf.isIE && !jpf.isOpera) { - str.push('<object '); - for (var i in objAttrs) - str.push(i, '="', objAttrs[i], '" '); - str.push('>'); - for (var i in params) - str.push('<param name="', i, '" value="', params[i], '" /> '); - str.push('</object>'); - } else { - str.push('<embed '); - for (var i in embedAttrs) - str.push(i, '="', embedAttrs[i], '" '); - str.push('> </embed>'); - } - var sOut = str.join(''); - - if (stdout === true) - document.write(sOut); - - return sOut; - } - - /** - * Use this function to generate the HTML tags for a Flash movie object. - * It takes any number of arguments as parameters: - * arguments: 'name1', 'value1', 'name2', 'value2', etc. - * - * @type {String} - */ - function AC_FL_RunContent(){ - var ret = AC_GetArgs(arguments, - "movie", "clsid:d27cdb6e-ae6d-11cf-96b8-444553540000", - "application/x-shockwave-flash"); - return generateObj(ret.objAttrs, ret.params, ret.embedAttrs); - } - - /** - * Generate the HTML for a Flash movie, with checks for general availability - * of a compatible Flash Player. If not, it will redirect to the installer - * (a seperate Flash Movie to upgrade) or diplay a link. - * - * @type {String} - */ - function buildContent() { - var hasRequestedVersion = isEightAvailable(); - if (isAvailable() && !hasRequestedVersion) - return jpf.flash.buildInstaller(); - if (hasRequestedVersion) - return AC_FL_RunContent.apply(null, Array.prototype.slice.call(arguments)); - return 'This content requires the \ - <a href="http://www.adobe.com/go/getflash/">Adobe Flash Player</a>.'; - } - - /** - * Build the <OBJECT> tag that will load the Adobe installer for Flash - * upgrades. - */ - function buildInstaller() { - var MMPlayerType = (jpf.isIE == true) ? "ActiveX" : "PlugIn"; - var MMredirectURL = window.location; - document.title = document.title.slice(0, 47) + " - Flash Player Installation"; - var MMdoctitle = document.title; - - return AC_FL_RunContent( - "src", "playerProductInstall", - "FlashVars", "MMredirectURL=" + MMredirectURL + "&MMplayerType=" - + MMPlayerType + "&MMdoctitle=" + MMdoctitle + "", - "width", "100%", - "height", "100%", - "align", "middle", - "id", this.name, - "quality", "high", - "bgcolor", "#000000", - "name", this.name, - "allowScriptAccess","always", - "type", "application/x-shockwave-flash", - "pluginspage", "http://www.adobe.com/go/getflashplayer" - ); - } - - /** - * Transforms arguments from AC_FL_RunContent and AC_SW_RunContent to sane - * object that can be used to generate <OBJECT> and <EMBED> tags (depending - * on the clients' browser, but this function will generate both) - * - * @param {Object} args - * @param {Object} ext - * @param {Object} srcParamName - * @param {Object} classid - * @param {Object} mimeType - * @type {Object} - */ - function AC_GetArgs(args, srcParamName, classid, mimeType){ - var ret = {}; - ret.embedAttrs = {}; - ret.params = {}; - ret.objAttrs = {}; - for (var i = 0; i < args.length; i = i + 2) { - var currArg = args[i].toLowerCase(); - - switch (currArg) { - case "classid": - break; - case "pluginspage": - ret.embedAttrs[args[i]] = args[i + 1]; - break; - case "src": - case "movie": - ret.embedAttrs["src"] = args[i + 1]; - ret.params[srcParamName] = args[i + 1]; - break; - case "onafterupdate": - case "onbeforeupdate": - case "onblur": - case "oncellchange": - case "onclick": - case "ondblClick": - case "ondrag": - case "ondragend": - case "ondragenter": - case "ondragleave": - case "ondragover": - case "ondrop": - case "onfinish": - case "onfocus": - case "onhelp": - case "onmousedown": - case "onmouseup": - case "onmouseover": - case "onmousemove": - case "onmouseout": - case "onkeypress": - case "onkeydown": - case "onkeyup": - case "onload": - case "onlosecapture": - case "onpropertychange": - case "onreadystatechange": - case "onrowsdelete": - case "onrowenter": - case "onrowexit": - case "onrowsinserted": - case "onstart": - case "onscroll": - case "onbeforeeditfocus": - case "onactivate": - case "onbeforedeactivate": - case "ondeactivate": - case "type": - case "codebase": - case "id": - ret.objAttrs[args[i]] = args[i + 1]; - break; - case "width": - case "height": - case "align": - case "vspace": - case "hspace": - case "class": - case "title": - case "accesskey": - case "name": - case "tabindex": - ret.embedAttrs[args[i]] = ret.objAttrs[args[i]] = args[i + 1]; - break; - default: - ret.embedAttrs[args[i]] = ret.params[args[i]] = args[i + 1]; - } - } - ret.objAttrs["classid"] = classid; - if (mimeType) - ret.embedAttrs["type"] = mimeType; - return ret; - } - - /** - * Utility method; get an element from the browser's document object, by ID. - * - * @param {Object} id - * @type {HTMLDomElement} - */ - function getElement(id) { - var elem; - - if (typeof id == "object") - return id; - if (jpf.isIE) - return window[id]; - else { - elem = document[id] ? document[id] : document.getElementById(id); - if (!elem) - elem = jpf.lookup(id); - return elem; - } - } - - /* ---------------------------------------------------- - * FAVideoManager - * - * This manages the collection of FAVideo instances on the HTML page. It directs calls from embedded - * FAVideo SWFs to the appropriate FAVideo instance in Javascript. - *----------------------------------------------------- */ - var hash = {}; - var uniqueID = 1; - - /** - * FAVideoManager: add a FAVideo instance to the stack for callbacks later on - * and return a unique Identifier for the FAVideo instance to remember. - * - * @param {Object} player - * @type {Number} - */ - function addPlayer(player) { - hash[++uniqueID] = player; - return uniqueID; - } - - /** - * FAVideoManager: retrieve the FAVideo instance that is paired to the - * unique identifier (id). - * - * @param {Object} id - * @type {FAVideo} - */ - function getPlayer(id) { - return hash[id]; - } - - /** - * Directs a call from embedded FAVideo SWFs to the appropriate FAVideo - * instance in Javascript - * - * @param {Object} id - * @param {Object} methodName - * @type {void} - */ - function callMethod(id, methodName) { - var player = hash[id]; - if (player == null) - throw new Error(jpf.formatErrorString(0, this, "Player with id: " + id + " not found")); - if (player[methodName] == null) - throw new Error(jpf.formatErrorString(0, this, "Method " + methodName + " Not found")); - - // Unable to use slice on arguments in some browsers. Iterate instead: - var args = []; - for (var i = 2; i < arguments.length; i++) - args.push(decode(arguments[i])); - player[methodName].apply(player, args); - } - - /** - * Encodes our data to get around ExternalInterface bugs that are still - * present even in Flash 9. - * - * @param {Object} data - */ - function encode(data) { - if (!data || typeof data != "string") - return data; - // double encode all entity values, or they will be mis-decoded - // by Flash when returned - data = data.replace(/\&([^;]*)\;/g, "&$1;"); - - // entity encode XML-ish characters, or Flash's broken XML serializer - // breaks - data = data.replace(/</g, "<"); - data = data.replace(/>/g, ">"); - - // transforming \ into \\ doesn't work; just use a custom encoding - data = data.replace("\\", "&custom_backslash;"); - - data = data.replace(/\0/g, "\\0"); // null character - data = data.replace(/\"/g, """); - - return data; - } - - /** - * Decodes our data to get around ExternalInterface bugs that are still - * present even in Flash 9. - * - * @param {String} data - */ - function decode(data) { - // wierdly enough, Flash sometimes returns the result as an - // 'object' that is actually an array, rather than as a String; - // detect this by looking for a length property; for IE - // we also make sure that we aren't dealing with a typeof string - // since string objects have length property there - if (data && data.length && typeof data != "string") - data = data[0]; - if (!data || typeof data != "string") - return data; - - // certain XMLish characters break Flash's wire serialization for - // ExternalInterface; these are encoded on the - // DojoExternalInterface side into a custom encoding, rather than - // the standard entity encoding, because otherwise we won't be able to - // differentiate between our own encoding and any entity characters - // that are being used in the string itself - data = data.replace(/\&custom_lt\;/g, "<"); - data = data.replace(/\&custom_gt\;/g, ">"); - data = data.replace(/\&custom_backslash\;/g, '\\'); - - // needed for IE; \0 is the NULL character - data = data.replace(/\\0/g, "\0"); - - return data; - } - - var aIsAvailable = {}; - /* - * Checks whether a valid version of Adobe Flash is available on the clients' - * system. Default version to check for is 6.0.65. - * - * @param {String} sVersion - * @type {Boolean} - */ - function isAvailable(sVersion) { - if (typeof sVersion != "string") - sVersion = "6.0.65"; - var aVersion = sVersion.split('.'); - while (aVersion.length < 3) - aVersion.push('0'); - if (typeof aIsAvailable[sVersion] == "undefined") - aIsAvailable[sVersion] = detectFlashVersion(parseInt(aVersion[0]), - parseInt(aVersion[1]), parseInt(aVersion[2])); - return aIsAvailable[sVersion]; - } - - /* - * Shorthand function to call and cache isAvailable() with version - * number 8.0.0 - * - * @type {Boolean} - */ - function isEightAvailable() { - return isAvailable('8.0.0'); - } - - var oSandboxTypes = { - remote : 'remote (domain-based) rules', - localwithfile : 'local with file access (no internet access)', - localwithnetwork: 'local with network (internet access only, no local access)', - localtrusted : 'local, trusted (local + internet access)' - }; - - function getSandbox(sType) { - var oSandbox = { - type : null, - description: null, - noRemote : false, - noLocal : false, - error : null - }; - oSandbox.type = sType.toLowerCase(); - oSandbox.description = oSandboxTypes[(typeof oSandboxTypes[oSandbox.type] != 'undefined' - ? oSandbox.type - : 'unknown')]; - if (oSandbox.type == 'localwithfile') { - oSandbox.noRemote = true; - oSandbox.noLocal = false; - oSandbox.error = "Flash security note: Network/internet URLs will not \ - load due to security restrictions.\ - Access can be configured via Flash Player Global Security\ - Settings Page: \ - http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html"; - } - else if (oSandbox.type == 'localwithnetwork') { - oSandbox.noRemote = false; - oSandbox.noLocal = true; - } - else if (oSandbox.type == 'localtrusted') { - oSandbox.noRemote = false; - oSandbox.noLocal = false; - } - - return oSandbox; - } - - return { - isAvailable : isAvailable, - isEightAvailable: isEightAvailable, - buildContent : buildContent, - encode : encode, - decode : decode, - getElement : getElement, - addPlayer : addPlayer, - getPlayer : getPlayer, - callMethod : callMethod, - getSandbox : getSandbox - }; -})(); - - -/*FILEHEAD(/var/lib/jpf/src/core/lib/util/utilities.js)SIZE(-1077090856)TIME(1238933677)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * Formats an xml string with good indentation. Also known as pretty printing.
- * @param {String} strXml the xml to format.
- * @return {String} the formatted string.
- */
-jpf.formatXml = function(strXml){
- if (!strXml) return "";
- strXml = strXml.trim();
-
- var lines = strXml.split("\n");
- for (var i = 0; i < lines.length; i++)
- lines[i] = lines[i].trim();
- lines = lines.join("\n").replace(/\>\n/g, ">").replace(/\>/g, ">\n")
- .replace(/\n\</g, "<").replace(/\</g, "\n<").split("\n");
- lines.removeIndex(0);//test if this is actually always fine
- lines.removeIndex(lines.length);
-
- for (var depth = 0, i = 0; i < lines.length; i++)
- lines[i] = "\t".repeat((lines[i].match(/^\s*\<\//)
- ? --depth
- : (lines[i].match(/^\s*\<[^\?][^>]+[^\/]\>/) ? depth++ : depth))) + lines[i];
-
- return lines.join("\n");
-};
-
-/**
- * Syntax highlights an xml string using html.
- * @param {String} strXml the xml to highlight.
- * @return {String} the highlighted string.
- */
-jpf.highlightXml = function(str){
- return str.replace(/^[\r\n]/g,"").replace(/</g, "_@A@_")
- .replace(/>/g, "_@B@_")
- .replace(/(\s[\w-]+)(\s*=\s*)("[^"]*")/g, '<span style="color:#e61414">$1</span>$2<span style="color:black">$3</span>')
- .replace(/(\s[\w-]+)(\s*=\s*)('[^']*')/g, "<span style='color:#e61414'>$1</span>$2<span style='color:black'>$3</span>")
- .replace(/\t/g, " ")
- .replace(/\n/g, "<br />")
- .replace(/_@B@_/g, "<span style='color:#0866ab'>></span>")
- .replace(/_@A@_([\-\!\[\\/\w:\.]+)?/g, "<span style='color:#0866ab'><$1</span>");
-}
-
-/**
- * Syntax highlights a code string using html.
- * @param {String} strCode the code to highlight.
- * @return {String} the highlighted string.
- */
-jpf.highlightCode = function(strCode){
- return strCode.replace(/^[\r\n]/g,"").replace(/</g, "_@A@_")
- .replace(/>/g, "_@B@_")
- .replace(/((?:\s|^)[\w-]+)(\s*=\s*)("[^"]*")/g, '<span style="color:red">$1</span>$2<span style="color:black">$3</span>')
- .replace(/((?:\s|^)[\w-]+)(\s*=\s*)('[^']*')/g, "<span style='color:red'>$1</span>$2<span style='color:black'>$3</span>")
- .replace(/(_@A@_[\s\S]*?_@B@_|<[\s\S]*?>)|(\/\/.*)$|("(?:[^"]+|\\.)*")|('(?:[^']+|\\.)*')|(\W)(break|continue|do|for|import|new|this|void|case|default|else|function|in|return|typeof|while|comment|delete|export|if|label|switch|var|with|abstract|implements|protected|boolean|instanceOf|public|byte|int|short|char|interface|static|double|long|synchronized|false|native|throws|final|null|transient|float|package|true|goto|private|catch|enum|throw|class|extends|try|const|finally|debugger|super)(\W)|(\W)(\w+)(\s*\()/gm,
- function(m, tag, co, str1, str2, nw, kw, nw2, fW, f, fws) {
- if (tag) return tag;
- else if (f)
- return fW + '<span style="color:#ff8000">' + f + '</span>' + fws;
- else if (co)
- return '<span style="color:green">' + co + '</span>';
- else if (str1 || str2)
- return '<span style="color:#808080">' + (str1 || str2) + '</span>';
- else if (nw)
- return nw + '<span style="color:#127ac6">' + kw + '</span>' + nw2;
- })
- .replace(/_@A@_(!--[\s\S]*?--)_@B@_/g, '<span style="color:green"><$1></span>')
- .replace(/\t/g, " ")
- .replace(/\n/g, "<br />")
- .replace(/_@B@_/g, "<span style='color:#127ac6'>></span>")
- .replace(/_@A@_([\-\!\[\\/\w:\.]+)?/g, "<span style='color:#127ac6'><$1</span>")
-}
-
-jpf.highlightCode2 = function(strCode){
- var comment=[];
- return strCode
- .replace(/(\/\*[\s\S]*?\*\/|\/\/.*)/g, function(a){ comment.push(a); return '###n'+(comment.length-1)+'###';})
- .replace(/(\<)|(\>)/g,function(n,a,b){ return "<span stylecolorwhite>"+(a?'@lt@':'@gt@')+"</span>"})
- .replace(/(\'.*?\'|\".*?\")/g, "<span stylecolorgray>$1</span>")
- .replace(/(\W)-?([\d\.]+)(\W)/g, "$1<span stylecolor#127ac6>$2</span>$3")
- .replace(/([\|\&\=\;\,\:\?\+\*\-]+)/g, "<span stylecolorwhite>$1</span>")
- .replace(/(\W)(break|continue|do|for|import|new|this|void|case|default|else|function|in|return|typeof|while|comment|delete|export|if|label|switch|var|with|abstract|implements|protected|boolean|instanceOf|public|byte|int|short|char|interface|static|double|long|synchronized|false|native|throws|final|null|transient|float|package|true|goto|private|catch|enum|throw|class|extends|try|const|finally|debugger|super)(\W)/g,
- "$1<span stylecolorgreen>$2</span>$3")
-
- .replace(/([\(\)\{\}\[\]])/g, "<span stylecoloryellow>$1</span>")
- .replace(/###n(\d+)###/g,function(a,b){ return "<span stylecolorpurple>"+comment[b]+"</span>"; } )
- .replace(/stylecolor(.*?)\>/g,"style='color:$1'>")
- .replace(/@(.*?)@/g,"&$1;");
-}
-
-/**
- * Formats a javascript string with good indentation. Also known as pretty printing.
- * @param {String} strJs the javascript to format.
- * @return {String} the formatted string.
- */
-jpf.formatJS = function(strJs){
- var d = 0, r = 0;
- var comment=[];
- return strJs
- .replace(/(\/\*[\s\S]*?\*\/|\/\/.*)/g, function(a){ comment.push(a); return '###n'+(comment.length-1)+'###';})
- .replace(/;+/g, ';').replace(/{;/g, '{').replace(/({)|(})|(\()|(\))|(;)/g,
- function(m, co, cc, ro, rc, e){
- if (co) d++;
- if (cc) d--;
- if (ro){ r++; return ro;}
- if (rc){ r--; return rc;}
-
- var o = '';
- for (var i = 0; i < d; i++)
- o += '\t';
- if (co) return '{\n' + o;
- if (cc) return '\n' + o + '}';
- if (e) return (r>0)?e:(';\n' + o);
- }).replace(/;\s*\n\s*\n/g, ';\n').replace(/}var/g, '}\nvar').replace(/([\n\s]*)###n(\d+)###[\n\s]*/g,function(a,b,c){ return b+comment[c]+b; } );
-};
-
-/**
- * Opens a window with the string in it
- * @param {String} str the html string displayed in the new window.
- */
-jpf.pasteWindow = function(str){
- var win = window.open("about:blank");
- win.document.write(str);
-};
-
-
-/**
- * @private
- */
-jpf.xmlEntityMap = {
- 'quot': '34', 'amp': '38', 'apos': '39', 'lt': '60', 'gt': '62',
- 'nbsp': '160', 'iexcl': '161', 'cent': '162', 'pound': '163', 'curren': '164',
- 'yen': '165', 'brvbar': '166', 'sect': '167', 'uml': '168', 'copy': '169',
- 'ordf': '170', 'laquo': '171', 'not': '172', 'shy': '173', 'reg': '174', 'macr': '175',
- 'deg': '176', 'plusmn': '177', 'sup2': '178', 'sup3': '179', 'acute': '180',
- 'micro': '181', 'para': '182', 'middot': '183', 'cedil': '184', 'sup1': '185',
- 'ordm': '186', 'raquo': '187', 'frac14': '188', 'frac12': '189', 'frac34': '190',
- 'iquest': '191', 'Agrave': '192', 'Aacute': '193', 'Acirc': '194', 'Atilde': '195',
- 'Auml': '196', 'Aring': '197', 'AElig': '198', 'Ccedil': '199', 'Egrave': '200',
- 'Eacute': '201', 'Ecirc': '202', 'Euml': '203', 'Igrave': '204', 'Iacute': '205',
- 'Icirc': '206', 'Iuml': '207', 'ETH': '208', 'Ntilde': '209', 'Ograve': '210',
- 'Oacute': '211', 'Ocirc': '212', 'Otilde': '213', 'Ouml': '214', 'times': '215',
- 'Oslash': '216', 'Ugrave': '217', 'Uacute': '218', 'Ucirc': '219', 'Uuml': '220',
- 'Yacute': '221', 'THORN': '222', 'szlig': '223', 'agrave': '224', 'aacute': '225',
- 'acirc': '226', 'atilde': '227', 'auml': '228', 'aring': '229', 'aelig': '230',
- 'ccedil': '231', 'egrave': '232', 'eacute': '233', 'ecirc': '234', 'euml': '235',
- 'igrave': '236', 'iacute': '237', 'icirc': '238', 'iuml': '239', 'eth': '240',
- 'ntilde': '241', 'ograve': '242', 'oacute': '243', 'ocirc': '244', 'otilde': '245',
- 'ouml': '246', 'divide': '247', 'oslash': '248', 'ugrave': '249', 'uacute': '250',
- 'ucirc': '251', 'uuml': '252', 'yacute': '253', 'thorn': '254', 'yuml': '255',
- 'OElig': '338', 'oelig': '339', 'Scaron': '352', 'scaron': '353', 'Yuml': '376',
- 'fnof': '402', 'circ': '710', 'tilde': '732', 'Alpha': '913', 'Beta': '914',
- 'Gamma': '915', 'Delta': '916', 'Epsilon': '917', 'Zeta': '918', 'Eta': '919',
- 'Theta': '920', 'Iota': '921', 'Kappa': '922', 'Lambda': '923', 'Mu': '924',
- 'Nu': '925', 'Xi': '926', 'Omicron': '927', 'Pi': '928', 'Rho': '929', 'Sigma': '931',
- 'Tau': '932', 'Upsilon': '933', 'Phi': '934', 'Chi': '935', 'Psi': '936', 'Omega': '937',
- 'alpha': '945', 'beta': '946', 'gamma': '947', 'delta': '948', 'epsilon': '949',
- 'zeta': '950', 'eta': '951', 'theta': '952', 'iota': '953', 'kappa': '954',
- 'lambda': '955', 'mu': '956', 'nu': '957', 'xi': '958', 'omicron': '959', 'pi': '960',
- 'rho': '961', 'sigmaf': '962', 'sigma': '963', 'tau': '964', 'upsilon': '965',
- 'phi': '966', 'chi': '967', 'psi': '968', 'omega': '969', 'thetasym': '977', 'upsih': '978',
- 'piv': '982', 'ensp': '8194', 'emsp': '8195', 'thinsp': '8201', 'zwnj': '8204',
- 'zwj': '8205', 'lrm': '8206', 'rlm': '8207', 'ndash': '8211', 'mdash': '8212',
- 'lsquo': '8216', 'rsquo': '8217', 'sbquo': '8218', 'ldquo': '8220', 'rdquo': '8221',
- 'bdquo': '8222', 'dagger': '8224', 'Dagger': '8225', 'bull': '8226', 'hellip': '8230',
- 'permil': '8240', 'prime': '8242', 'Prime': '8243', 'lsaquo': '8249', 'rsaquo': '8250',
- 'oline': '8254', 'frasl': '8260', 'euro': '8364', 'image': '8465', 'weierp': '8472',
- 'real': '8476', 'trade': '8482', 'alefsym': '8501', 'larr': '8592', 'uarr': '8593',
- 'rarr': '8594', 'darr': '8595', 'harr': '8596', 'crarr': '8629', 'lArr': '8656',
- 'uArr': '8657', 'rArr': '8658', 'dArr': '8659', 'hArr': '8660', 'forall': '8704',
- 'part': '8706', 'exist': '8707', 'empty': '8709', 'nabla': '8711', 'isin': '8712',
- 'notin': '8713', 'ni': '8715', 'prod': '8719', 'sum': '8721', 'minus': '8722',
- 'lowast': '8727', 'radic': '8730', 'prop': '8733', 'infin': '8734', 'ang': '8736',
- 'and': '8743', 'or': '8744', 'cap': '8745', 'cup': '8746', 'int': '8747', 'there4': '8756',
- 'sim': '8764', 'cong': '8773', 'asymp': '8776', 'ne': '8800', 'equiv': '8801', 'le': '8804',
- 'ge': '8805', 'sub': '8834', 'sup': '8835', 'nsub': '8836', 'sube': '8838',
- 'supe': '8839', 'oplus': '8853', 'otimes': '8855', 'perp': '8869', 'sdot': '8901',
- 'lceil': '8968', 'rceil': '8969', 'lfloor': '8970', 'rfloor': '8971', 'lang': '9001',
- 'rang': '9002', 'loz': '9674', 'spades': '9824', 'clubs': '9827', 'hearts': '9829',
- 'diams': '9830'
-};
-
-/**
- * see string#escapeHTML
- * @param {String} str the html to be escaped.
- * @return {String} the escaped string.
- */
-jpf.htmlentities = function(str){
- return str.escapeHTML();
-};
-
-/**
- * Escape an xml string making it ascii compatible.
- * @param {String} str the xml string to escape.
- * @return {String} the escaped string.
- */
-jpf.xmlentities = function(str) {
- return str.replace(/&([a-z]+);/gi, function(a, m) {
- if (jpf.xmlEntityMap[m])
- return '&#' + jpf.xmlEntityMap[m] + ';';
- return a;
- });
-};
-
-/**
- * Unescape an html string.
- * @param {String} str the string to unescape.
- * @return {String} the unescaped string.
- */
-jpf.html_entity_decode = function(str){
- return (str || "").replace(/\&\#38;/g, "&").replace(/</g, "<")
- .replace(/>/g, ">").replace(/&/g, "&").replace(/ /g, " ");
-};
-
-
-/**
- * This random number generator has been added to provide a more robust and
- * reliable random number spitter than the native Ecmascript Math.random()
- * function.
- * is an implementation of the Park-Miller algorithm. (See 'Random Number
- * Generators: Good Ones Are Hard to Find', by Stephen K. Park and Keith W.
- * Miller, Communications of the ACM, 31(10):1192-1201, 1988.)
- * @author David N. Smith of IBM's T. J. Watson Research Center.
- * @author Mike de Boer (mdeboer AT javeline DOT com)
- * @class randomGenerator
- */
-jpf.randomGenerator = {
- d: new Date(),
- seed: null,
- A: 48271,
- M: 2147483647,
- Q: null,
- R: null,
- oneOverM: null,
-
- /**
- * Generates a random Number between a lower and upper boundary.
- * The algorithm uses the system time, in minutes and seconds, to 'seed'
- * itself, that is, to create the initial values from which it will generate
- * a sequence of numbers. If you are familiar with random number generators,
- * you might have reason to use some other value for the seed. Otherwise,
- * you should probably not change it.
- * @param {Number} lnr Lower boundary
- * @param {Number} unr Upper boundary
- * @result A random number between <i>lnr</i> and <i>unr</i>
- * @type Number
- */
- generate: function(lnr, unr) {
- if (this.seed == null)
- this.seed = 2345678901 + (this.d.getSeconds() * 0xFFFFFF) + (this.d.getMinutes() * 0xFFFF);
- this.Q = this.M / this.A;
- this.R = this.M % this.A;
- this.oneOverM = 1.0 / this.M;
- return Math.floor((unr - lnr + 1) * this.next() + lnr);
- },
-
- /**
- * Returns a new random number, based on the 'seed', generated by the
- * <i>generate</i> method.
- * @type Number
- */
- next: function() {
- var hi = this.seed / this.Q;
- var lo = this.seed % this.Q;
- var test = this.A * lo - this.R * hi;
- if (test > 0)
- this.seed = test;
- else
- this.seed = test + this.M;
- return (this.seed * this.oneOverM);
- }
-};
-
-/**
- * Adds a time stamp to the url to prevent the browser from caching it.
- * @param {String} url the url to add the timestamp to.
- * @return {String} the url with timestamp.
- */
-jpf.getNoCacheUrl = function(url){
- return url
- + (url.indexOf("?") == -1 ? "?" : "&")
- + "nocache=" + new Date().getTime();
-};
-
-/**
- * Checks if the string contains curly braces at the start and end. If so it's
- * processed as javascript, else the original string is returned.
- * @param {String} str the string to parse.
- * @return {String} the result of the parsing.
- */
-jpf.parseExpression = function(str){
- if (!jpf.parseExpression.regexp.test(str))
- return str;
-
- try {
- return eval(RegExp.$1);
- }
- catch(e) {
- throw new Error(jpf.formatErrorString(0, null,
- "Parsing Expression",
- "Invalid expression given '" + str + "'"));
- }
-};
-jpf.parseExpression.regexp = /^\{(.*)\}$/;
-
-/**
- * @private
- */
-jpf.formatNumber = function(num, prefix){
- var nr = parseFloat(num);
- if (!nr) return num;
-
- var str = new String(Math.round(nr * 100) / 100).replace(/(\.\d?\d?)$/, function(m1){
- return m1.pad(3, "0", jpf.PAD_RIGHT);
- });
- if (str.indexOf(".") == -1)
- str += ".00";
-
- return prefix + str;
-};
-
-// Serialize Objects
-/**
- * @private
- */
-jpf.JSONSerialize = {
- object: function(o){
- //XML support - NOTICE: Javeline PlatForm specific
- if (o.nodeType && o.cloneNode)
- return "jpf.xmldb.getXml("
- + this.string(jpf.xmldb.serializeNode(o)) + ")";
-
- //Normal JS object support
- var str = [];
- for (var prop in o) {
- str.push('"' + prop.replace(/(["\\])/g, '\\$1') + '": '
- + jpf.serialize(o[prop]));
- }
-
- return "{" + str.join(", ") + "}";
- },
-
- string: function(s){
- s = '"' + s.replace(/(["\\])/g, '\\$1') + '"';
- return s.replace(/(\n)/g, "\\n").replace(/\r/g, "");
- },
-
- number: function(i){
- return i.toString();
- },
-
- "boolean": function(b){
- return b.toString();
- },
-
- date: function(d){
- var padd = function(s, p){
- s = p + s;
- return s.substring(s.length - p.length);
- };
- var y = padd(d.getUTCFullYear(), "0000");
- var m = padd(d.getUTCMonth() + 1, "00");
- var D = padd(d.getUTCDate(), "00");
- var h = padd(d.getUTCHours(), "00");
- var min = padd(d.getUTCMinutes(), "00");
- var s = padd(d.getUTCSeconds(), "00");
-
- var isodate = y + m + D + "T" + h + ":" + min + ":" + s;
-
- return '{"jsonclass":["sys.ISODate", ["' + isodate + '"]]}';
- },
-
- array: function(a){
- for (var q = [], i = 0; i < a.length; i++)
- q.push(jpf.serialize(a[i]));
-
- return "[" + q.join(", ") + "]";
- }
-};
-
-/**
- * Creates a json string from a javascript object.
- * @param {mixed} the javascript object to serialize.
- * @return {String} the json string representation of the object.
- * @todo allow for XML serialization
- */
-jpf.serialize = function(args){
- if (typeof args == "function" || jpf.isNot(args))
- return "null";
- return jpf.JSONSerialize[args.dataType || "object"](args);
-};
-
-/**
- * Evaluate a serialized object back to JS with eval(). When the 'secure' flag
- * is set to 'TRUE', the provided string will be validated for being valid
- * JSON.
- *
- * @param {String} str the json string to create an object from.
- * @param {Boolean} secure whether the json string should be checked to prevent malice.
- * @return {Object} the object created from the json string.
- */
-jpf.unserialize = function(str, secure){
- if (!str) return str;
- if (secure && !(/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/)
- .test(str.replace(/\\./g, '@').replace(/"(?:\\"|[^"])*"|'(?:\\'|[^'])*'/g, '')))
- return str;
- return eval('(' + str + ')');
-};
-
-/**
- * Execute a script in the global scope.
- *
- * @param {String} str the javascript code to execute.
- * @return {String} the javascript code executed.
- */
-jpf.exec = function(str, win){
- if (!str)
- return str;
- if (!win)
- win = self;
-
- if (jpf.hasExecScript) {
- win.execScript(str);
- }
- else {
- var head = win.document.getElementsByTagName("head")[0];
- if (head) {
- var script = win.document.createElement('script');
- script.setAttribute('type', 'text/javascript');
- script.text = str;
- head.appendChild(script);
- head.removeChild(script);
- } else
- eval(str, win);
- }
-
- return str;
-};
-
-/**
- * Shorthand for an empty function.
- */
-jpf.K = function(){};
-
-
-/**
- * Determines whether a variable is null or empty string.
- *
- * @param {mixed} value the variable to check
- * @return {Boolean}
- */
-jpf.isNull = function(value){
- if (value)
- return false;
- return (value == null || !String(value).length);
-};
-
-/**
- * Reliably determines whether a variable is a Number.
- *
- * @param {mixed} value The variable to check
- * @type {Boolean}
- */
-jpf.isNumber = function(value){
- return parseFloat(value) == value;
-};
-
-/**
- * Reliably determines whether a variable is an array.
- * @see http://thinkweb2.com/projects/prototype/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/
- *
- * @param {mixed} value The variable to check
- * @type {Boolean}
- */
-jpf.isArray = function(value) {
- return Object.prototype.toString.call(value) === "[object Array]";
-};
-
-/**
- * Determines whether a string is true in the html attribute sense.
- * @param {mixed} value the variable to check
- * Possible values:
- * true The function returns true.
- * 'true' The function returns true.
- * 'on' The function returns true.
- * 1 The function returns true.
- * '1' The function returns true.
- * @return {Boolean} whether the string is considered to imply truth.
- */
-jpf.isTrue = function(c){
- return (c === true || c === "true" || c === "on" || typeof c == "number" && c > 0 || c === "1");
-};
-
-/**
- * Determines whether a string is false in the html attribute sense.
- * @param {mixed} value the variable to check
- * Possible values:
- * false The function returns true.
- * 'false' The function returns true.
- * 'off' The function returns true.
- * 0 The function returns true.
- * '0' The function returns true.
- * @return {Boolean} whether the string is considered to imply untruth.
- */
-jpf.isFalse = function(c){
- return (c === false || c === "false" || c === "off" || c === 0 || c === "0");
-};
-
-/**
- * Determines whether a value should be considered false. This excludes amongst
- * others the number 0.
- * @param {mixed} value the variable to check
- * @return {Boolean} whether the variable is considered false.
- */
-jpf.isNot = function(c){
- // a var that is null, false, undefined, Infinity, NaN and c isn't a string
- return (!c && typeof c != "string" && c !== 0 || (typeof c == "number" && !isFinite(c)));
-};
-
-/**
- * Returns the directory portion of a url
- * @param {String} url the url to retrieve from.
- * @return {String} the directory portion of a url.
- */
-jpf.getDirname = function(url){
- return ((url || "").match(/^(.*\/)[^\/]*$/) || {})[1]; //Mike will check out how to optimize this line
-};
-
-/**
- * Returns the file portion of a url
- * @param {String} url the url to retrieve from.
- * @return {String} the file portion of a url.
- */
-jpf.getFilename = function(url){
- return ((url || "").split("?")[0].match(/(?:\/|^)([^\/]+)$/) || {})[1];
-};
-
-/**
- * Returns an absolute url based on url.
- * @param {String} base the start of the url to which relative url's work.
- * @param {String} url the url to transform.
- * @return {String} the absolute url.
- */
-jpf.getAbsolutePath = function(base, url){
- return !url || url.match(/^\w+\:\/\//) ? url : base + url;
-};
-
-/**
- * Creates a relative url based on an absolute url.
- * @param {String} base the start of the url to which relative url's work.
- * @param {String} url the url to transform.
- * @return {String} the relative url.
- */
-jpf.removePathContext = function(base, url){
- if (!url) return "";
-
- if (url.indexOf(base) > -1)
- return url.substr(base.length);
-
- return url;
-};
-
-/**
- * @private
- * @todo why is this done like this?
- */
-jpf.cancelBubble = function(e, o){
- e.cancelBubble = true;
- if (o.$focussable && !o.disabled)
- jpf.window.$focus(o);
-};
-
-
-
-/**
- * Queries an xml node using xpath for a string value.
- * @param {XMLElement} xmlNode the xml element to query.
- * @param {String} xpath the xpath query.
- * @return {String} the value of the query result or empty string.
- */
-jpf.getXmlValue = function (xmlNode, xpath){
- if (!xmlNode) return "";
- xmlNode = xmlNode.selectSingleNode(xpath);
- if (xmlNode && xmlNode.nodeType == 1)
- xmlNode = xmlNode.firstChild;
- return xmlNode ? xmlNode.nodeValue : "";
-};
-
-/**
- * Queries an xml node using xpath for a string value.
- * @param {XMLElement} xmlNode the xml element to query.
- * @param {String} xpath the xpath query.
- * @return {Arary} list of values which are a result of the query.
- */
-jpf.getXmlValues = function(xmlNode, xpath){
- var out = [];
- if (!xmlNode) return out;
-
- var nodes = xmlNode.selectNodes(xpath);
- if (!nodes.length) return out;
-
- for (var i = 0; i < nodes.length; i++) {
- var n = nodes[i];
- if (n.nodeType == 1)
- n = n.firstChild;
- out.push(n.nodeValue || "");
- }
- return out;
-};
-
-
-/**
- * Attempt to fix memory leaks
- * @private
- */
-jpf.removeNode = function (element) {
- if (!element) return;
-
- if (!jpf.isIE || element.ownerDocument != document) {
- if (element.parentNode)
- element.parentNode.removeChild(element);
- return;
- }
-
- var garbageBin = document.getElementById('IELeakGarbageBin');
- if (!garbageBin) {
- garbageBin = document.createElement('DIV');
- garbageBin.id = 'IELeakGarbageBin';
- garbageBin.style.display = 'none';
- document.body.appendChild(garbageBin);
- }
-
- // move the element to the garbage bin
- garbageBin.appendChild(element);
- garbageBin.innerHTML = '';
-};
-
-/**
- * @private
- */
-jpf.getRules = function(node){
- var rules = {};
-
- for (var w = node.firstChild; w; w = w.nextSibling){
- if (w.nodeType != 1)
- continue;
- else {
- if (!rules[w[jpf.TAGNAME]])
- rules[w[jpf.TAGNAME]] = [];
- rules[w[jpf.TAGNAME]].push(w);
- }
- }
-
- return rules;
-};
-
-/**
- * @private
- */
-jpf.getBox = function(value, base){
- if (!base) base = 0;
-
- if (value == null || (!parseInt(value) && parseInt(value) != 0))
- return [0, 0, 0, 0];
-
- var x = value.split(" ");
- for (var i = 0; i < x.length; i++)
- x[i] = parseInt(x[i]) || 0;
- switch (x.length) {
- case 1:
- x[1] = x[0];
- x[2] = x[0];
- x[3] = x[0];
- break;
- case 2:
- x[2] = x[0];
- x[3] = x[1];
- break;
- case 3:
- x[3] = x[1];
- break;
- }
-
- return x;
-};
-
-/**
- * @private
- */
-jpf.getNode = function(data, tree){
- var nc = 0;//nodeCount
- //node = 1
- if (data != null) {
- for (var i = 0; i < data.childNodes.length; i++) {
- if (data.childNodes[i].nodeType == 1) {
- if (nc == tree[0]) {
- data = data.childNodes[i];
- if (tree.length > 1) {
- tree.shift();
- data = this.getNode(data, tree);
- }
- return data;
- }
- nc++
- }
- }
- }
-
- return null;
-};
-
-/**
- * Retrieves the first xml node with nodeType 1 from the children of an xml element.
- * @param {XMLElement} xmlNode the xml element that is the parent of the element to select.
- * @return {XMLElement} the first child element of the xml parent.
- * @throw error when no child element is found.
- */
-jpf.getFirstElement = function(xmlNode){
- try {
- xmlNode.firstChild.nodeType == 1
- ? xmlNode.firstChild
- : xmlNode.firstChild.nextSibling
- }
- catch (e) {
- throw new Error(jpf.formatErrorString(1052, null,
- "Xml Selection",
- "Could not find element:\n"
- + (xmlNode ? xmlNode.xml : "null")));
- }
-
- return xmlNode.firstChild.nodeType == 1
- ? xmlNode.firstChild
- : xmlNode.firstChild.nextSibling;
-};
-
-/**
- * Retrieves the last xml node with nodeType 1 from the children of an xml element.
- * @param {XMLElement} xmlNode the xml element that is the parent of the element to select.
- * @return {XMLElement} the last child element of the xml parent.
- * @throw error when no child element is found.
- */
-jpf.getLastElement = function(xmlNode){
- try {
- xmlNode.lastChild.nodeType == 1
- ? xmlNode.lastChild
- : xmlNode.lastChild.nextSibling
- }
- catch (e) {
- throw new Error(jpf.formatErrorString(1053, null,
- "Xml Selection",
- "Could not find last element:\n"
- + (xmlNode ? xmlNode.xml : "null")));
- }
-
- return xmlNode.lastChild.nodeType == 1
- ? xmlNode.lastChild
- : xmlNode.lastChild.previousSibling;
-};
-
-/**
- * Selects the content of an html element. Currently only works in
- * internet explorer.
- * @param {HTMLElement} oHtml the container in which the content receives the selection.
- */
-jpf.selectTextHtml = function(oHtml){
- if (!jpf.hasMsRangeObject) return;// oHtml.focus();
-
- var r = document.selection.createRange();
- try {r.moveToElementText(oHtml);} catch(e){}
- r.select();
-};
-
- - -/*FILEHEAD(/var/lib/jpf/src/core/lib/util/popup.js)SIZE(-1077090856)TIME(1238933677)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -/** - * @private - */ -jpf.popup = { - cache : {}, - focusFix : {"INPUT":1,"TEXTAREA":1,"SELECT":1}, - - setContent : function(cacheId, content, style, width, height){ - if (!this.popup) this.init(); - - this.cache[cacheId] = { - content : content, - style : style, - width : width, - height : height - }; - content.style.position = "absolute"; - //if(content.parentNode) content.parentNode.removeChild(content); - //if(style) jpf.importCssString(this.popup.document, style); - - content.onmousedown = function(e) { - if (!e) e = event; - - if (jpf.hasFocusBug - && !jpf.popup.focusFix[(e.srcElement || e.target).tagName]) { - jpf.window.$focusfix(); - } - - (e || event).cancelBubble = true; - }; - - return content.ownerDocument; - }, - - removeContent : function(cacheId){ - this.cache[cacheId] = null; - delete this.cache[cacheId]; - }, - - init : function(){ - //consider using iframe - this.popup = {}; - - jpf.addEventListener("hotkey", function(e){ - if (e.keyCode == "27" || e.altKey) - jpf.popup.forceHide(); - }); - }, - - show : function(cacheId, options){ - options = jpf.extend({ - x : 0, - y : 0, - animate : false, - ref : null, - width : null, - height : null, - callback : null, - draggable : false, - resizable : false, - allowTogether: false - }, options); - if (!this.popup) - this.init(); - if ((!options.allowTogether || options.allowTogether != this.last) && this.last != cacheId) - this.hide(); - - var o = this.cache[cacheId]; - o.options = options; - //if(this.last != cacheId) - //this.popup.document.body.innerHTML = o.content.outerHTML; - - var popup = o.content; - if (!o.content.style.zIndex) - o.content.style.zIndex = 10000000; - if (o.content.style.display && o.content.style.display.indexOf('none') > -1) - o.content.style.display = ""; - - if (options.ref) { - var pos = jpf.getAbsolutePosition(options.ref, - o.content.offsetParent || o.content.parentNode);//[ref.offsetLeft+2,ref.offsetTop+4];// - var top = (options.y || 0) + pos[1]; - var p = jpf.getOverflowParent(o.content); - - if (options.width || o.width) - popup.style.width = ((options.width || o.width) - 3) + "px"; - - var moveUp = false;//(top + (height || o.height || o.content.offsetHeight) + y) > (p.offsetHeight + p.scrollTop); - - if (moveUp) - popup.style.top = (pos[1] - (options.height || o.height || o.content.offsetHeight)) + "px" - else - popup.style.top = top + "px"; - popup.style.left = ((options.x || 0) + pos[0]) + "px"; - } - - if (options.animate) { - if (options.animate == "fade") { - jpf.tween.single(popup, { - type : 'fade', - from : 0, - to : 1, - anim : jpf.tween.NORMAL, - steps : jpf.isIE ? 5 : 10 - }); - } - else { - var iVal, steps = 7, i = 0; - - iVal = setInterval(function(){ - var value = ++i * ((options.height || o.height) / steps); - - popup.style.height = value + "px"; - if (moveUp) - popup.style.top = (top - value - options.y) + "px"; - else - popup.scrollTop = 10000;//-1 * (i - steps - 1) * ((options.height || o.height) / steps); - popup.style.display = "block"; - - if (i >= steps) { - clearInterval(iVal) - - if (options.callback) - options.callback(popup); - } - }, 10); - } - } - else { - if (options.height || o.height) - popup.style.height = (options.height || o.height) + "px"; - - if (options.callback) - options.callback(popup); - } - - setTimeout(function(){ - jpf.popup.last = cacheId; - }); - - if (options.draggable) { - options.id = cacheId; - this.makeDraggable(options); - } - }, - - hide : function(){ - if (this.isDragging) return; - - var o = this.cache[this.last]; - if (o) { - if (o.content) - o.content.style.display = "none"; - - if (o.options.onclose) { - o.options.onclose(jpf.extend(o.options, {htmlNode: o.content})); - o.options.onclose = false; - } - } - }, - - isShowing : function(cacheId){ - return this.last && this.last == cacheId - && this.cache[this.last] - && this.cache[this.last].content.style.display != "none"; - }, - - isDragging : false, - - makeDraggable: function(options) { - if (!jpf.Interactive || this.cache[options.id].draggable) - return; - - var oHtml = this.cache[options.id].content; - this.cache[options.id].draggable = true; - var o = { - $propHandlers : {}, - minwidth : 10, - minheight : 10, - maxwidth : 10000, - maxheight : 10000, - dragOutline : false, - resizeOutline : false, - draggable : true, - resizable : options.resizable, - oExt : oHtml, - oDrag : oHtml.firstChild - }; - - oHtml.onmousedown = - oHtml.firstChild.onmousedown = function(e){ - if (!e) e = event; - - if (jpf.hasFocusBug - && !jpf.popup.focusFix[(e.srcElement || e.target).tagName]) { - jpf.window.$focusfix(); - } - - (e || event).cancelBubble = true; - } - - jpf.inherit.call(o, jpf.Interactive); - - o.$propHandlers["draggable"].call(o, true); - o.$propHandlers["resizable"].call(o, true); - }, - - forceHide : function(){ - if (this.last && !jpf.plane.current && this.isShowing(this.last)) { - var o = jpf.lookup(this.last); - if (!o) - this.last = null; - - else if (o.dispatchEvent("popuphide") !== false) - this.hide(); - } - }, - - destroy : function(){ - for (var cacheId in this.cache) { - if (this.cache[cacheId]) { - this.cache[cacheId].content.onmousedown = null; - jpf.removeNode(this.cache[cacheId].content); - this.cache[cacheId].content = null; - this.cache[cacheId] = null; - } - } - - if (!this.popup) return; - //this.popup.document.body.c = null; - //this.popup.document.body.onmouseover = null; - } -} - - -/*FILEHEAD(/var/lib/jpf/src/core/lib/util/ecmaext.js)SIZE(-1077090856)TIME(1238933677)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -// start closure: -//(function(){ - -if (typeof isFinite == "undefined") { - function isFinite(val){ - return val + 1 != val; - } -} - -Array.prototype.dataType = "array"; -Number.prototype.dataType = "number"; -Date.prototype.dataType = "date"; -Boolean.prototype.dataType = "boolean"; -String.prototype.dataType = "string"; -RegExp.prototype.dataType = "regexp"; -Function.prototype.dataType = "function"; - -jpf.getCgiString = function(args, multicall, mcallname){ - var vars = []; - - function recur(o, stack) { - if (jpf.isArray(o)) { - for (var j = 0; j < o.length; j++) - recur(o[j], stack + "%5B%5D");//" + j + " - } - else if (typeof o == "object") { - for (prop in o) { - if (jpf.isSafariOld && (!o[prop] || typeof p[prop] != "object")) - continue; - - if (typeof o[prop] == "function") - continue; - recur(o[prop], stack + "%5B" + encodeURIComponent(prop) + "%5D"); - } - } - else - vars.push(stack + "=" + encodeURIComponent(o)); - }; - - if (multicall) { - vars.push("func=" + mcallname); - for (var i = 0; i < args[0].length; i++) - recur(args[0][i], "f%5B" + i + "%5D"); - } else { - for (prop in args) { - if (jpf.isSafariOld && (!args[prop] || typeof args[prop] == "function")) - continue; - - recur(args[prop], prop); - } - } - - return vars.join("&"); -} - -jpf.fromCgiString = function(args) { - if (!args) - return false; - - var obj = {}; - args = args.split("&"); - for (var data, i = 0; i < args.length; i++) { - data = args[i].split("="); - data[0] = decodeURIComponent(data[0]); - var path = data[0].replace(/\]/g, "").split("["); - - var spare = obj; - for (var j = 0; j < path.length; j++) { - if (spare[path[j]]) - spare = spare[path[j]]; - else if (path.length == j+1) { - if (path[j]) - spare[path[j]] = decodeURIComponent(data[1]); - else - spare.push(decodeURIComponent(data[1])); - break; //assuming last - } - else{ - spare[path[j]] = !path[j+1] ? [] : {}; - spare = spare[path[j]]; - } - } - } - - return obj; -} - - - -/** - * Extends a Function object with properties from other objects, specified as - * arguments. - * - * @param {mixed} obj1, obj2, obj3, etc. - * @type Function - * @see jpf.extend - */ -Function.prototype.extend = function() { - jpf.extend.apply(this, [this].concat(Array.prototype.slice.call(arguments))); - return this; -}; - -/** - * Attach a Function object to an event as handler method. If jpf.AbstractEvent - * is available, the active event is extended with convinience accessors as - * declared in jpf.AbstractEvent - * - * @param {Object} The context the execute the Function within - * @param {mixed} param1, param2, param3, etc. - * @type Function - * @see jpf.AbstractEvent - */ -Function.prototype.bindWithEvent = function() { - var __method = this, args = Array.prototype.slice.call(arguments), - o = args.shift(), - ev = args.shift(); - return function(event) { - if (!event) event = window.event; - if (ev !== false) - event = new jpf.AbstractEvent(event, window); - return __method.apply(o, [event].concat(args) - .concat(Array.prototype.slice.call(arguments))); - } -}; - -/** - * Copy an array, like this statement would: 'this.concat([])', but then do it - * recursively. - */ -Array.prototype.copy = function(){ - var ar = []; - for (var i = 0, j = this.length; i < j; i++) - ar[i] = this[i] && this[i].copy ? this[i].copy() : this[i]; - - return ar; -}; - -/** - * Concatenate the current Array instance with one (or more) other Arrays, like - * Array.concat(), but return the current Array instead of a new one that - * results from the merge. - * - * @param {Array} array1, array2, array3, etc. - * @type {Array} - */ -Array.prototype.merge = function(){ - for (var i = 0, k = arguments.length; i < k; i++) { - for (var j = 0, l = arguments[i].length; j < l; j++) { - this.push(arguments[i][j]); - } - } -}; - -/** - * Add the values of one or more arrays to the current instance by using the - * '+=' operand on each value. - * - * @param {Array} array1, array2, array3, etc. - * @type {Array} - * @see Array.copy - */ -Array.prototype.arrayAdd = function(){ - var s = this.copy(); - for (var i = 0, k = arguments.length; i < k; i++) { - for (var j = 0, l = s.length; j < l; j++) { - s[j] += arguments[i][j]; - } - } - - return s; -}; - -/** - * Check if an object is contained within the current Array instance. - * - * @param {mixed} obj The value to check for inside the Array - * @type {Boolean} - */ -Array.prototype.equals = function(obj){ - for (var i = 0, j = this.length; i < j; i++) - if (this[i] != obj[i]) - return false; - return true; -}; - -/** - * Make sure that an array instance contains only unique values (NO duplicates). - * - * @type {Array} - */ -Array.prototype.makeUnique = function(){ - var i, length, newArr = []; - for (i = 0, length = this.length; i < length; i++) - if (newArr.indexOf(this[i]) == -1) - newArr.push(this[i]); - - this.length = 0; - for (i = 0, length = newArr.length; i < length; i++) - this.push(newArr[i]); - - return this; -}; - -/** - * Check if this array instance contains a value 'obj'. - * - * @param {mixed} obj The value to check for inside the array - * @param {Number} [from] Left offset index to start the search from - * @type {Boolean} - * @see Array.indexOf - */ -Array.prototype.contains = function(obj, from){ - return this.indexOf(obj, from) != -1; -}; - -/** - * Search for the index of the first occurence of a value 'obj' inside an array - * instance. - * July 29, 2008: added 'from' argument support to indexOf() - * - * @param {mixed} obj The value to search for inside the array - * @param {Number} [from] Left offset index to start the search from - * @type {Number} - */ -Array.prototype.indexOf = Array.prototype.indexOf || function(obj, from){ - var len = this.length; - for (var i = (from < 0) ? Math.max(0, len + from) : from || 0; i < len; i++) { - if (this[i] === obj) - return i; - } - return -1; -}; - -/** - * Search for the index of the last occurence of a value 'obj' inside an array - * instance. - * - * @param {mixed} obj The value to search for inside the array - * @param {Number} [from] Left offset index to start the search from - * @type {Number} - */ -Array.prototype.lastIndexOf = Array.prototype.lastIndexOf || function(obj, from) { - //same as indexOf(), but in reverse loop, JS spec 1.6 - var len = this.length; - for (var i = (from >= len) ? len - 1 : (from < 0) ? from + len : len - 1; i >= 0; i--) { - if (this[i] === obj) - return i; - } - return -1; -}; - -/** - * Like Array.push, but only invoked when the value 'item' is already present - * inside the array instance. - * - * @param {mixed} item - * @type {Array} - */ -Array.prototype.pushUnique = function(item){ - if (this.indexOf(item) == -1) - this.push(item); - return this; -}; - -/** - * Ruben: could you please comment on this function? Seems to serve a very - * specific purpose... - * - * I also could not find an occurrence in our codebase. - */ -Array.prototype.search = function(){ - for (var i = 0, length = arguments.length; i < length; i++) { - if (typeof this[i] != "array") - continue; - for (var j = 0; j < length; j++) { - if (this[i][j] != arguments[j]) - break; - else if (j == (length - 1)) - return this[i]; - } - } -}; - -/** - * Iterate through each value of an array instance from left to right (front to - * back) and execute a callback Function for each value. - * - * @param {Function} fn - * @type {Array} - */ -Array.prototype.each = -Array.prototype.forEach = Array.prototype.forEach || function(fn) { - for (var i = 0, l = this.length; i < l; i++) - fn.call(this, this[i], i, this); - return this; -} - -/** - * Search for a value 'obj' inside an array instance and remove it when found. - * - * @type {mixed} obj - * @type {Array} - */ -Array.prototype.remove = function(obj){ - for (var i = this.length - 1; i >= 0; i--) { - if (this[i] != obj) - continue; - - this.splice(i, 1); - } - - return this; -}; - -/** - * Remove an item from an array instance which can be identified with key 'i' - * - * @param {Number} i - * @return {mixed} The removed item - */ -Array.prototype.removeIndex = function(i){ - if (!this.length) return; - return this.splice(i, 1); -}; - -/** - * Insert a new value at a specific object; alias for Array.splice. - * - * @param {mixed} obj Value to insert - * @param {Number} i Index to insert 'obj' at - * @type {Number} - */ -Array.prototype.insertIndex = function(obj, i){ - this.splice(i, 0, obj); -}; - -/** - * Reverses the order of the elements of an array; the first becomes the last, - * and the last becomes the first. - * - * @type {Array} - */ -Array.prototype.invert = -Array.prototype.reverse = Array.prototype.reverse || function(){ - var l = this.length - 1; - for (var temp, i = 0; i < Math.ceil(0.5 * l); i++) { - temp = this[i]; - this[i] = this[l - i] - this[l - i] = temp; - } - - return this; -}; - - -/** - * Transform a number to a string and pad it with a zero digit its length is one. - * - * @type {String} - */ -Number.prototype.toPrettyDigit = Number.prototype.toPrettyDigit || function() { - var n = this.toString(); - return (n.length == 1) ? "0" + n : n; -}; - -/** - * Attempt to fully comply (in terms of functionality) with the JS specification, - * up till version 1.7: - * @link http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array - */ - -/** - * Creates a new array with all of the elements of this array for which the - * provided filtering function returns true. - * - * @param {Function} fn Function to test each element of the array. - * @param {Object} bind Object to use as this when executing callback. - * @type {Array} - */ -Array.prototype.filter = Array.prototype.filter || function(fn, bind){ - var results = []; - for (var i = 0, l = this.length; i < l; i++) { - if (fn.call(bind, this[i], i, this)) - results.push(this[i]); - } - return results; -}; - -/** - * Returns true if every element in this array satisfies the provided testing - * function. - * - * @param {Function} fn Function to test for each element. - * @param {Object} bind Object to use as this when executing callback. - * @type {Boolean} - */ -Array.prototype.every = Array.prototype.every || function(fn, bind){ - for (var i = 0, l = this.length; i < l; i++) { - if (!fn.call(bind, this[i], i, this)) - return false; - } - return true; -}; - -/** - * Creates a new array with the results of calling a provided function on every - * element in this array. - * - * @param {Function} fn Function that produces an element of the new Array from an element of the current one. - * @param {Object} bind Object to use as this when executing callback. - * @type {Array} - */ -Array.prototype.map = Array.prototype.map || function(fn, bind){ - var results = []; - for (var i = 0, l = this.length; i < l; i++) - results[i] = fn.call(bind, this[i], i, this); - return results; -}; - -/** - * Tests whether some element in the array passes the test implemented by the - * provided function. - * - * @param {Function} fn Function to test for each element. - * @param {Object} bind Object to use as this when executing callback. - * @type {Boolean} - */ -Array.prototype.some = Array.prototype.some || function(fn, bind){ - for (var i = 0, l = this.length; i < l; i++) { - if (fn.call(bind, this[i], i, this)) - return true; - } - return false; -}; - -Math.hexlist = "0123456789ABCDEF"; -/** - * Convert a number (or float) from decimal to hexadecimal notation. - * - * @param {Number} value - * @type {String} - */ -Math.decToHex = function(value){ - var hex = this.floor(value / 16); - hex = (hex > 15 ? this.decToHex(hex) : this.hexlist.charAt(hex)); - - return hex + "" + this.hexlist.charAt(this.floor(value % 16)); -}; - -/** - * Convert a String from hexadecimal to decimal notation. - * - * @param {String} value - * @type {Number} - */ -Math.hexToDec = function(value){ - if (!/(.)(.)/.exec(value.toUpperCase())) - return false; - return this.hexlist.indexOf(RegExp.$1) * 16 + this.hexlist.indexOf(RegExp.$2); -}; - - -RegExp.prototype.getNativeFlags = function() { - return (this.global ? "g" : "") + - (this.ignoreCase ? "i" : "") + - (this.multiline ? "m" : "") + - (this.extended ? "x" : "") + - (this.sticky ? "y" : ""); -}; - -/** - * Accepts flags; returns a new XRegExp object generated by recompiling - * the regex with the additional flags (may include non-native flags). - * the original regex object is not altered. - */ -RegExp.prototype.addFlags = function(flags){ - return new RegExp(this.source, (flags || "") + this.getNativeFlags()); - // unused XRegExp stuff: - /*if (this._x) { - regex._x = { - source: this._x.source, - captureNames: this._x.captureNames ? this._x.captureNames.slice(0) : null - }; - } - return regex;*/ -}; - -/** - * Casts the first character in a string to uppercase. - * - * @type {String} - */ -String.prototype.uCaseFirst = function(){ - return this.substr(0, 1).toUpperCase() + this.substr(1) -}; - -/** - * Removes spaces and other space-like characters from the left and right ends - * of a string - * - * @type {String} - */ -String.prototype.trim = function(){ - return this.replace(/[\s\n\r]*$/, "").replace(/^[\s\n\r]*/, ""); -}; - -/** - * Concatenate a string with itself n-times. - * - * @param {Number} times Number of times to repeat the String concatenation - * @type {String} - */ -String.prototype.repeat = function(times){ - return Array(times + 1).join(this); -}; - -/** - * Count the number of occurences of substring 'str' inside a string - * - * @param {String} str - * @type {Number} - */ -String.prototype.count = function(str){ - return this.split(str).length - 1; -}; - -/** - * Remove HTML or any XML-like tags from a string - * - * @type {String} - */ -String.prototype.stripTags = function() { - return this.replace(/<\/?[^>]+>/gi, ''); -}; - -/** - * Wrapper for the global 'escape' function for strings - * - * @type {String} - */ -String.prototype.escape = function() { - return escape(this); -}; - -if (typeof window != "undefined" && typeof window.document != "undefined" - && typeof window.document.createElement == "function") { - /** - * Encode HTML entities to its HTML equivalents, like '&' to '&amp;' - * and '<' to '&lt;'. - * - * @type {String} - */ - String.prototype.escapeHTML = function() { - this.escapeHTML.text.data = this; - return this.escapeHTML.div.innerHTML; - }; - - /** - * Decode HTML equivalent entities to characters, like '&amp;' to '&' - * and '&lt;' to '<'. - * - * @type {String} - */ - String.prototype.unescapeHTML = function() { - var div = document.createElement('div'); - div.innerHTML = this.stripTags(); - if (div.childNodes[0]) { - if (div.childNodes.length > 1) { - var out = []; - for (var i = 0; i < div.childNodes.length; i++) - out.push(div.childNodes[i].nodeValue); - return out.join(''); - } - else - return div.childNodes[0].nodeValue; - } - return ""; - }; - - String.prototype.escapeHTML.div = document.createElement('div'); - String.prototype.escapeHTML.text = document.createTextNode(''); - String.prototype.escapeHTML.div.appendChild(String.prototype.escapeHTML.text); - - if ('<\n>'.escapeHTML() !== '<\n>') - String.prototype.escapeHTML = null; - - if ('<\n>'.unescapeHTML() !== '<\n>') - String.prototype.unescapeHTML = null; -} - -if (!String.prototype.escapeHTML) { - String.prototype.escapeHTML = function() { - return this.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>'); - }; -} - -if (!String.prototype.unescapeHTML) { - String.prototype.unescapeHTML = function() { - return this.stripTags().replace(/</g,'<').replace(/>/g,'>').replace(/&/g,'&'); - }; -} - -/** - * Trim a string down to a specific number of characters. Optionally, append an - * ellipsis ('...') as a suffix. - * - * @param {Number} nr - * @param {Boolean} [ellipsis] Append an ellipsis - * @type {String} - */ -String.prototype.truncate = function(nr, ellipsis){ - return this.length >= nr - ? this.substring(0, nr - (ellipsis ? 4 : 1)) + (ellipsis ? "..." : "") - : this; -}; - -/** - * Pad a string at the right or left end with a string 'pad' to a specific - * number of characters. - * - * @param {Number} len - * @param {String} pad - * @type {String} - */ -String.prototype.pad = function(len, pad, dir) { - return dir ? (this + Array(len).join(pad)).slice(0, len) - : (Array(len).join(pad) + this).slice(-len); -}; - -jpf.PAD_LEFT = false; -jpf.PAD_RIGHT = true; - -/** - * Special String.split; optionally lowercase a string and trim all results from - * the left and right. - * - * @param {String} separator - * @param {Number} limit Maximum number of items to return - * @param {Boolean} bLowerCase Flag to lowercase the string prior to split - * @type {String} - */ -String.prototype.splitSafe = function(separator, limit, bLowerCase) { - return (bLowerCase && this.toLowerCase() || this) - .replace(/(?:^\s+|\n|\s+$)/g, "") - .split(new RegExp("[\\s ]*" + separator + "[\\s ]*", "g"), limit || 999); -}; - -var _oldSplit = String.prototype.split; -/** - * A consistent cross-browser, ECMA-262 v3 compliant split method - * Fixes to native object: - * - Internet Explorer excludes almost all empty values from the resulting - * array (e.g. when two delimiters appear next to each other in the data, - * or when a delimiter appears at the start or end of the data). - * This behavior differs when using a string as the delimiter. - * - Internet Explorer and Safari do not splice the values of capturing groups - * into the returned array. - * - Firefox does not splice undefined values into the returned array as the - * result of non-participating capturing groups. - * - Internet Explorer, Safari, and Opera have various additional edge-case - * bugs where they do not follow the split specification. - * @link http://stevenlevithan.com/regex/xregexp/#split - * - * @param {mixed} s Seperator pattern can be either a String or RegExp - * @param {Number} [limit] Limit the result set of the split action to a specific number - * @type {Array} - -String.prototype.split = function(s, limit) { - // if separator is not a regex, use the native split method - if (!(s instanceof RegExp)) - return _oldSplit.apply(this, arguments); - - var output = [], - origLastIndex = s.lastIndex, - lastLastIndex = 0, - i = 0, match, lastLength; - - // behavior for limit: if it's... - // - undefined: no limit - // - NaN or zero: return an empty array - // - a positive number: use limit after dropping any decimal - // - a negative number: no limit - // - other: type-convert, then use the above rules - if (limit === undefined || +limit < 0) { - limit = false; - } - else { - limit = Math.floor(+limit); - if (!limit) - return []; - } - - if (s.global) - s.lastIndex = 0; - else - s = s.addFlags("g"); - - while ((!limit || i++ <= limit) && (match = s.exec(this))) { // run the altered exec! - if (s.lastIndex > lastLastIndex) { - output = output.concat(this.slice(lastLastIndex, match.index)); - if (1 < match.length && match.index < this.length) - output = output.concat(match.slice(1)); - lastLength = match[0].length; // only needed if s.lastIndex === this.length - lastLastIndex = s.lastIndex; - } - if (!match[0].length) - s.lastIndex++; // avoid an infinite loop - } - - // since this uses test(), output must be generated before restoring lastIndex - output = lastLastIndex === this.length ? - (s.test("") && !lastLength ? output : output.concat("")) : - (limit ? output : output.concat(this.slice(lastLastIndex))); - s.lastIndex = origLastIndex; // only needed if s.global, else we're working with a copy of the regex - return output; -};*/ - -/** - * Appends a random number with a specified length to this String instance. - * - * @see randomGenerator - * @param {Number} length - * @type {String} - */ -String.prototype.appendRandomNumber = function(length) { - // Create a new string from the old one, don't just create a copy - var source = this.toString(); - for (var i = 1; i <= length; i++) { - source += jpf.randomGenerator.generate(1, 9); - } - return source; -}; - -/** - * Prepends a random number with a specified length to this String instance. - * - * @see randomGenerator - * @param {Number} length - * @type {String} - */ -String.prototype.prependRandomNumber = function(length) { - // Create a new string from the old one, don't just create a copy - var source = this.toString(); - for (var i = 1; i <= length; i++) { - source = jpf.randomGenerator.generate(1, 9) + source; - } - return source; -}; - -/** - * Returns a string produced according to the formatting string. It replaces - * all <i>%s</i> occurrences with the arguments provided. - * - * @link http://www.php.net/sprintf - * @type {String} - */ -String.prototype.sprintf = function() { - // Create a new string from the old one, don't just create a copy - var str = this.toString(); - var i = 0, inx = str.indexOf('%s'); - while (inx >= 0) { - var replacement = arguments[i++] || ' '; - str = str.substr(0, inx) + replacement + str.substr(inx + 2); - inx = str.indexOf('%s'); - } - return str; -}; - -//})(); //end closure - - - -/*FILEHEAD(/var/lib/jpf/src/core/lib/util/dragmode.js)SIZE(-1077090856)TIME(1238933677)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - -/* ******** DRAGMODE *********** - Drag Mode - Handles Drag&Drop Methods on Body -*******************************/ -/** - * @private - */ -jpf.dragmode = { - modes : {}, - - removeMode : function(mode){ - this.modes[mode] = null; - }, - - defineMode : function(mode, struct){ - this.modes[mode] = struct; - }, - - setMode : function(mode){ - for (var prop in this.modes[mode]) - if (prop.match(/^on/)) - document[prop] = this.modes[mode][prop]; - - this.mode = mode; - }, - - clear : function(){ - for (var prop in this.modes[this.mode]) - if (prop.match(/^on/)) - document[prop] = null; - - this.mode = null; - } -}; - -jpf.Init.run('jpf.dragmode'); - - -/*FILEHEAD(/var/lib/jpf/src/core/lib/util/nameserver.js)SIZE(-1077090856)TIME(1225967668)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * @private
- */
-jpf.namespace("nameserver", {
- lookup : {},
-
- add : function(type, item){
- if (!this.lookup[type])
- this.lookup[type] = [];
-
- if(this.onchange)
- this.onchange(type, item);
-
- return this.lookup[type].push(item) - 1;
- },
-
- register : function(type, id, item){
- if (!this.lookup[type])
- this.lookup[type] = {};
-
- if (this.onchange)
- this.onchange(type, item, id);
-
- return (this.lookup[type][id] = item);
- },
-
- get : function(type, id){
- return this.lookup[type] ? this.lookup[type][id] : null;
- },
-
- getAll : function(type){
- var name, arr = [];
- for (name in this.lookup[type]) {
- if (jpf.isSafariOld
- && (!this.lookup[type][name]
- || typeof this.lookup[type][name] != "object"))
- continue;
- arr.push(this.lookup[type][name]);
- }
- return arr;
- },
-
- getAllNames : function(type){
- var name, arr = [];
- for (name in this.lookup[type]){
- if (parseInt(name) == name) continue;
- arr.push(name);
- }
- return arr;
- }
-});
-
-
-/**
- * Object which provides a means to store key values pairs in a named context.
- */
-jpf.registry = jpf.extend({
- /**
- * Stores a key value pair.
- * @param {String} key the identifier of the information.
- * @param {mixed} value the information to store.
- * @param {String} namespace the named context into which to store the key value pair.
- */
- put : function(key, value, namespace){
- this.register(namespace, key, value);
- },
-
- /**
- * @notimplemented
- */
- getNamespaces : function(){
-
- },
-
- /**
- * Retrieves all the keys of a namespace.
- * @param {String} namespace the named context of the keys to retrieve.
- * @return {Array} the list of keys in the namespace.
- */
- getKeys : function(namespace){
- return this.getAllNames(namespace);
- },
-
- /**
- * Removes a key in a namespace.
- * @param {String} key the identifier of the information.
- * @param {String} namespace the named context of the keys to remove.
- */
- remove : function(key, namespace){
- delete this.lookup[namespace][key];
- },
-
- /**
- * @notimplemented
- */
- clear : function(namespace){
- this.lookup = {}; //@todo
- },
-
- $export : function(storage){
- var namespace, key;
-
- for (namespace in this.lookup) {
- for (key in this.lookup[namespace]) {
- storage.put(key, this.lookup[key][namespace], namespace);
- }
- }
- }
-}, jpf.nameserver);
-
-jpf.registry.lookup = {};
-
-/**
- * Retrieves a keys in a namespace.
- * @param {String} key the identifier of the information.
- * @param {String} namespace the named context of the keys to retrieve.
- * @return {mixed} the value that correspond to the key in the namespace.
- */
-jpf.registry.get = function(key, namespace){
- return this.lookup[namespace] ? this.lookup[namespace][key] : null;
-};
-
- - -/*FILEHEAD(/var/lib/jpf/src/core/lib/util/silverlight.js)SIZE(-1077090856)TIME(1228078143)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - -/** - * Helper class that aids in creating and controlling Microsoft Silverlight - * elements (XAML stuff). - * - * @author Mike de Boer - * @version %I%, %G% - * @since 1.0 - * @namespace jpf - */ -jpf.silverlight = (function() { - /** - * {Number} silverlightCount: - * - * Counter of globalized event handlers - */ - var silverlightCount = 0; - - /** - * {Boolean} __onSilverlightInstalledCalled: - * - * Prevents onSilverlightInstalled from being called multiple times - */ - var __onSilverlightInstalledCalled = false; - - /** - * {String} fwlinkRoot: - * - * Prefix for fwlink URL's - */ - var fwlinkRoot = 'http://go2.microsoft.com/fwlink/?LinkID='; - - /** - * {Boolean} __installationEventFired: - * - * Ensures that only one Installation State event is fired. - */ - var __installationEventFired = false; - - /** - * {Function} onGetSilverlight - * - * Called by Silverlight.GetSilverlight to notify the page that a user - * has requested the Silverlight installer - */ - var onGetSilverlight = null; - - /** - * Called by jpf.silverlight.WaitForInstallCompletion when the page detects - * that Silverlight has been installed. The event handler is not called - * in upgrade scenarios. - * - * @type {void} - */ - function onSilverlightInstalled() { - window.location.reload(false); - } - - /** - * Checks to see if the correct version is installed - * - * @param {String} version - * @type {Boolean} - */ - function isInstalled(version){ - if (version == undefined) - version = null; - - var isVersionSupported = false; - var container = null; - - try { - var control = null; - var tryNS = false; - - if (window.ActiveXObject) { - try { - control = new ActiveXObject('AgControl.AgControl'); - if (version === null) { - isVersionSupported = true; - } - else if (control.IsVersionSupported(version)) { - isVersionSupported = true; - } - control = null; - } - catch (e) { - tryNS = true; - } - } - else { - tryNS = true; - } - if (tryNS) { - var plugin = navigator.plugins["Silverlight Plug-In"]; - if (plugin) { - if (version === null) { - isVersionSupported = true; - } - else { - var actualVer = plugin.description; - if (actualVer === "1.0.30226.2") - actualVer = "2.0.30226.2"; - var actualVerArray = actualVer.split("."); - while (actualVerArray.length > 3) { - actualVerArray.pop(); - } - while (actualVerArray.length < 4) { - actualVerArray.push(0); - } - var reqVerArray = version.split("."); - while (reqVerArray.length > 4) { - reqVerArray.pop(); - } - - var requiredVersionPart; - var actualVersionPart; - var index = 0; - do { - requiredVersionPart = parseInt(reqVerArray[index]); - actualVersionPart = parseInt(actualVerArray[index]); - index++; - } - while (index < reqVerArray.length && requiredVersionPart === actualVersionPart); - - if (requiredVersionPart <= actualVersionPart && !isNaN(requiredVersionPart)) { - isVersionSupported = true; - } - } - } - } - } - catch (e) { - isVersionSupported = false; - } - - return isVersionSupported; - } - - /** - * Occasionally checks for Silverlight installation status. If it - * detects that Silverlight has been installed then it calls - * jpf.silverlight.onSilverlightInstalled();. This is only supported - * if Silverlight was not previously installed on this computer. - * - * @type {void} - */ - function WaitForInstallCompletion(){ - if (!jpf.silverlight.isBrowserRestartRequired && onSilverlightInstalled) { - try { - navigator.plugins.refresh(); - } - catch(e) {} - if (isInstalled(null) && !__onSilverlightInstalledCalled) { - onSilverlightInstalled(); - __onSilverlightInstalledCalled = true; - } - else { - setTimeout(WaitForInstallCompletion, 3000); - } - } - } - - /** - * Performs startup tasks - * - * @type {void} - */ - function startup() { - navigator.plugins.refresh(); - jpf.silverlight.isBrowserRestartRequired = isInstalled(null); - if (!jpf.silverlight.isBrowserRestartRequired) { - WaitForInstallCompletion(); - if (!__installationEventFired) { - onInstallRequired(); - __installationEventFired = true; - } - } - else if (window.navigator.mimeTypes) { - var mimeSL2 = navigator.mimeTypes["application/x-silverlight-2"]; - var mimeSL2b2 = navigator.mimeTypes["application/x-silverlight-2-b2"]; - var mimeSL2b1 = navigator.mimeTypes["application/x-silverlight-2-b1"]; - var mimeHighestBeta = mimeSL2b1; - if (mimeSL2b2) - mimeHighestBeta = mimeSL2b2; - - if (!mimeSL2 && (mimeSL2b1 || mimeSL2b2)) { - if (!__installationEventFired) { - onUpgradeRequired(); - __installationEventFired = true; - } - } - else if (mimeSL2 && mimeHighestBeta) { - if (mimeSL2.enabledPlugin && - mimeHighestBeta.enabledPlugin) { - if (mimeSL2.enabledPlugin.description != - mimeHighestBeta.enabledPlugin.description) { - if (!__installationEventFired) { - onRestartRequired(); - __installationEventFired = true; - } - } - } - } - } - } - - /** - * Inserts a Silverlight <object> tag or installation experience into the HTML - * DOM based on the current installed state of Silverlight. - * - * @param {String} source - * @param {HTMLDomElement} parentElement - * @param {String} id - * @param {Object} properties - * @param {Object} events - * @param {Object} initParams - * @param {mixed} userContext - * @type {String} - */ - function createObject(source, parentElement, id, properties, events, initParams, userContext) { - var slPluginHelper = {}, - slProperties = properties, - slEvents = events; - - slPluginHelper.version = slProperties.version; - slProperties.source = source; - slPluginHelper.alt = slProperties.alt; - - //rename properties to their tag property names. For bacwards compatibility - //with Silverlight.js version 1.0 - if (initParams) - slProperties.initParams = initParams; - if (slProperties.isWindowless && !slProperties.windowless) - slProperties.windowless = slProperties.isWindowless; - if (slProperties.framerate && !slProperties.maxFramerate) - slProperties.maxFramerate = slProperties.framerate; - if (id && !slProperties.id) - slProperties.id = id; - - // remove elements which are not to be added to the instantiation tag - delete slProperties.ignoreBrowserVer; - delete slProperties.inplaceInstallPrompt; - delete slProperties.version; - delete slProperties.isWindowless; - delete slProperties.framerate; - delete slProperties.data; - delete slProperties.src; - delete slProperties.alt; - - // detect that the correct version of Silverlight is installed, else display install - if (isInstalled(slPluginHelper.version)) { - //move unknown events to the slProperties array - for (var name in slEvents) { - if (slEvents[name]) { - if (name == "onLoad" && typeof slEvents[name] == "function" - && slEvents[name].length != 1 ) { - var onLoadHandler = slEvents[name]; - slEvents[name] = function (sender) { - return onLoadHandler(document.getElementById(id), - userContext, sender) - }; - } - var handlerName = __getHandlerName(slEvents[name]); - if (handlerName != null) { - slProperties[name] = handlerName; - slEvents[name] = null; - } - else { - throw "typeof events."+name+" must be 'function' or 'string'"; - } - } - } - slPluginHTML = buildHTML(slProperties); - } - //The control could not be instantiated. Show the installation prompt - else { - slPluginHTML = buildPromptHTML(slPluginHelper); - } - - // insert or return the HTML - if (parentElement) - parentElement.innerHTML = slPluginHTML; - else - return slPluginHTML; - } - - /** - * create HTML that instantiates the control - * - * @param {Object} slProperties - * @type {String} - */ - function buildHTML(slProperties) { - var htmlBuilder = []; - htmlBuilder.push('<object type=\"application/x-silverlight\" data="data:application/x-silverlight,"'); - if (slProperties.id != null) - htmlBuilder.push(' id="' + HtmlAttributeEncode(slProperties.id) + '"'); - if (slProperties.width != null) - htmlBuilder.push(' width="' + slProperties.width+ '"'); - if (slProperties.height != null) - htmlBuilder.push(' height="' + slProperties.height + '"'); - htmlBuilder.push(' >'); - - delete slProperties.id; - delete slProperties.width; - delete slProperties.height; - - for (var name in slProperties) { - if (slProperties[name]) - htmlBuilder.push('<param name="' + HtmlAttributeEncode(name) - + '" value="' + HtmlAttributeEncode(slProperties[name]) + '" />'); - } - htmlBuilder.push('<\/object>'); - return htmlBuilder.join(''); - } - - /** - * takes a single parameter of all createObject - * parameters enclosed in {} - * - * @param {Object} params - * @type {String} - */ - function createObjectEx(params) { - var parameters = params; - var html = createObject(parameters.source, parameters.parentElement, - parameters.id, parameters.properties, parameters.events, - parameters.initParams, parameters.context); - if (parameters.parentElement == null) - return html; - } - - /** - * Builds the HTML to prompt the user to download and install Silverlight - * - * @param {Object} slPluginHelper - * @type {String} - */ - function buildPromptHTML(slPluginHelper) { - var slPluginHTML = ""; - var urlRoot = fwlinkRoot; - var version = slPluginHelper.version ; - if (slPluginHelper.alt) { - slPluginHTML = slPluginHelper.alt; - } - else { - if (!version) - version=""; - slPluginHTML = "<a href='javascript:Silverlight.getSilverlight(\"{1}\");' style='text-decoration: none;'><img src='{2}' alt='Get Microsoft Silverlight' style='border-style: none'/></a>"; - slPluginHTML = slPluginHTML.replace('{1}', version); - slPluginHTML = slPluginHTML.replace('{2}', urlRoot + '108181'); - } - - return slPluginHTML; - } - - /** - * Navigates the browser to the appropriate Silverlight installer - * - * @param {String} version - * @type {void} - */ - function getSilverlight(version) { - if (onGetSilverlight ) - onGetSilverlight(); - - var shortVer = ""; - var reqVerArray = String(version).split("."); - if (reqVerArray.length > 1) { - var majorNum = parseInt(reqVerArray[0]); - if (isNaN(majorNum) || majorNum < 2) - shortVer = "1.0"; - else - shortVer = reqVerArray[0]+'.'+reqVerArray[1]; - } - - var verArg = ""; - if (shortVer.match(/^\d+\056\d+$/) ) - verArg = "&v="+shortVer; - followFWLink("114576" + verArg); - } - - /** - * Navigates to a url based on fwlinkid - * - * @param {String} linkid - * @type {void} - */ - function followFWLink(linkid) { - top.location = fwlinkRoot + String(linkid); - } - - /** - * Encodes special characters in input strings as charcodes - * - * @param {String} strInput - * @type {String} - */ - function HtmlAttributeEncode(strInput) { - var c; - var retVal = ''; - - if (strInput == null) return null; - - for (var cnt = 0; cnt < strInput.length; cnt++) { - c = strInput.charCodeAt(cnt); - - if (((c > 96) && (c < 123)) || (( c > 64) && (c < 91)) - || ((c > 43) && (c < 58) && (c != 47)) || (c == 95)) - retVal = retVal + String.fromCharCode(c); - else - retVal = retVal + '&#' + c + ';'; - } - return retVal; - } - - /** - * Default error handling function - * - * @param {String} sender - * @param {Object} args - * @type {void} - */ - function default_error_handler(sender, args) { - var iErrorCode; - var errorType = args.ErrorType; - - iErrorCode = args.ErrorCode; - - var errMsg = ["\nSilverlight error message \n\ - ErrorCode: ", iErrorCode, "\n\ - ErrorType: ", errorType, " \n\ - Message: ", args.ErrorMessage, " \n"]; - - if (errorType == "ParserError") { - errMsg.push("XamlFile: ", args.xamlFile, " \n\ - Line: ", args.lineNumber, " \n\ - Position: ", args.charPosition, " \n"); - } - else if (errorType == "RuntimeError") { - if (args.lineNumber != 0) { - errMsg.push("Line: ", args.lineNumber, " \n\ - Position: ", args.charPosition, " \n"); - } - errMsg.push("MethodName: ", args.methodName, " \n"); - } - throw new Error(jpf.formatErrorString(0, this, errMsg.join(''))); - } - - /** - * Releases event handler resources when the page is unloaded - * - * @type {void} - */ - function __cleanup() { - for (var i = silverlightCount - 1; i >= 0; i--) - window['__slEvent' + i] = null; - - silverlightCount = 0; - if (window.removeEventListener) - window.removeEventListener('unload', __cleanup , false); - else - window.detachEvent('onunload', __cleanup ); - } - - /** - * Generates named event handlers for delegates. - * - * @param {Function} handler - * @type {String} - */ - function __getHandlerName(handler) { - var handlerName = ""; - if (typeof handler == "string") { - handlerName = handler; - } - else if (typeof handler == "function" ) { - if (silverlightCount == 0) { - if (window.addEventListener) - window.addEventListener('onunload', __cleanup , false); - else - window.attachEvent('onunload', __cleanup); - } - var count = silverlightCount++; - handlerName = "__slEvent"+count; - - window[handlerName]=handler; - } - else { - handlerName = null; - } - return handlerName; - } - - /** - * onRequiredVersionAvailable: - * - * Called by version verification control to notify the page that - * an appropriate build of Silverlight is available. The page - * should respond by injecting the appropriate Silverlight control - */ - function onRequiredVersionAvailable() {}; - - /** - * onRestartRequired: - * - * Called by version verification control to notify the page that - * an appropriate build of Silverlight is installed but not loaded. - * The page should respond by injecting a clear and visible - * "Thanks for installing. Please restart your browser and return - * to mysite.com" or equivalent into the browser DOM - */ - function onRestartRequired() {}; - - /** - * onUpgradeRequired: - * - * Called by version verification control to notify the page that - * Silverlight must be upgraded. The page should respond by - * injecting a clear, visible, and actionable upgrade message into - * the DOM. The message must inform the user that they need to - * upgrade Silverlight to use the page. They are already somewhat - * familiar with the Silverlight product when they encounter this. - * Silverlight should be mentioned so the user expects to see that - * string in the installer UI. However, the Silverlight-powered - * application should be the focus of the solicitation. The user - * wants the app. Silverlight is a means to the app. - * - * The upgrade solicitation will have a button that directs - * the user to the Silverlight installer. Upon click the button - * should both kick off a download of the installer URL and replace - * the Upgrade text with "Thanks for downloading. When the upgarde - * is complete please restart your browser and return to - * mysite.com" or equivalent. - * - * Note: For a more interesting upgrade UX we can use Silverlight - * 1.0-style XAML for this upgrade experience. Contact PiotrP for - * details. - */ - function onUpgradeRequired() {}; - - /** - * onInstallRequired: - * - * Called by Silverlight.checkInstallStatus to notify the page - * that Silverlight has not been installed by this user. - * The page should respond by - * injecting a clear, visible, and actionable upgrade message into - * the DOM. The message must inform the user that they need to - * download and install components needed to use the page. - * Silverlight should be mentioned so the user expects to see that - * string in the installer UI. However, the Silverlight-powered - * application should be the focus of the solicitation. The user - * wants the app. Silverlight is a means to the app. - * - * The installation solicitation will have a button that directs - * the user to the Silverlight installer. Upon click the button - * should both kick off a download of the installer URL and replace - * the Upgrade text with "Thanks for downloading. When installation - * is complete you may need to refresh the page to view this - * content" or equivalent. - */ - function onInstallRequired() {}; - - /** - * IsVersionAvailableOnError: - * - * This function should be called at the beginning of a web page's - * Silverlight error handler. It will determine if the required - * version of Silverlight is installed and available in the - * current process. - * - * During its execution the function will trigger one of the - * Silverlight installation state events, if appropriate. - * - * Sender and Args should be passed through from the calling - * onError handler's parameters. - * - * The associated Sivlerlight <object> tag must have - * minRuntimeVersion set and should have autoUpgrade set to false. - */ - function IsVersionAvailableOnError(sender, args) { - var retVal = false; - try { - if (args.ErrorCode == 8001 && !__installationEventFired) { - onUpgradeRequired(); - __installationEventFired = true; - } - else if (args.ErrorCode == 8002 && !__installationEventFired) { - onRestartRequired(); - __installationEventFired = true; - } - // this handles upgrades from 1.0. That control did not - // understand the minRuntimeVerison parameter. It also - // did not know how to parse XAP files, so would throw - // Parse Error (5014). A Beta 2 control may throw 2106 - else if (args.ErrorCode == 5014 || args.ErrorCode == 2106) { - if (__verifySilverlight2UpgradeSuccess(args.getHost())) - retVal = true; - } - else { - retVal = true; - } - } - catch (e) { } - return retVal; - }; - - /** - * IsVersionAvailableOnLoad: - * - * This function should be called at the beginning of a web page's - * Silverlight onLoad handler. It will determine if the required - * version of Silverlight is installed and available in the - * current process. - * - * During its execution the function will trigger one of the - * Silverlight installation state events, if appropriate. - * - * Sender should be passed through from the calling - * onError handler's parameters. - * - * The associated Sivlerlight <object> tag must have - * minRuntimeVersion set and should have autoUpgrade set to false. - */ - function IsVersionAvailableOnLoad(sender) { - var retVal = false; - try { - if (__verifySilverlight2UpgradeSuccess(sender.getHost())) - retVal = true; - } - catch (e) {} - return retVal; - }; - - /** - * __verifySilverlight2UpgradeSuccess: - * - * This internal function helps identify installation state by - * taking advantage of behavioral differences between the - * 1.0 and 2.0 releases of Silverlight. - * - */ - function __verifySilverlight2UpgradeSuccess(host) { - var retVal = false, - version = "2.0.31005", - installationEvent = null; - - try { - if (host.IsVersionSupported(version + ".99")) { - installationEvent = onRequiredVersionAvailable; - retVal = true; - } - else if (host.IsVersionSupported(version + ".0")) { - installationEvent = onRestartRequired; - } - else { - installationEvent = onUpgradeRequired; - } - - if (installationEvent && !__installationEventFired) { - installationEvent(); - __installationEventFired = true; - } - } - catch (e) {} - return retVal; - }; - - var aIsAvailable = {}; - /* - * Checks whether a valid version of Silverlight is available on the clients' - * system. Default version to check for is 1.0. - * - * @param {String} sVersion Optional. - * @type {Boolean} - */ - function isAvailable(sVersion) { - if (typeof sVersion == "undefined") - sVersion = "1.0"; - if (typeof aIsAvailable[sVersion] == "undefined") - aIsAvailable[sVersion] = isInstalled(sVersion); - return aIsAvailable[sVersion]; - } - - return { - /** - * onGetSilverlight: - * - * Called by jpf.silverlight.GetSilverlight to notify the page that a user - * has requested the Silverlight installer - */ - onGetSilverlight : null, - isBrowserRestartRequired: false, - startup : startup, - createObject : createObject, - createObjectEx : createObjectEx, - getSilverlight : getSilverlight, - default_error_handler : default_error_handler, - isAvailable : isAvailable - }; -})(); - - -/*FILEHEAD(/var/lib/jpf/src/core/lib/util/abstractevent.js)SIZE(-1077090856)TIME(1238933677)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -/** - * @constructor - */ -jpf.AbstractEvent = function(event, win) { - win = win || window; - var doc = win.document; - event = event || win.event; - if (event.$extended) return event; - this.$extended = true; - - this.event = event; - - this.type = event.type; - this.target = event.target || event.srcElement; - while (this.target && this.target.nodeType == 3) - this.target = this.target.parentNode; - - if (this.type.indexOf("key") != -1) { - this.code = event.which || event.keyCode; - /*this.key = jpf.AbstractEvent.KEYS.fromCode(this.code); - if (this.type == 'keydown') { - var fKey = this.code - 111; - if (fKey > 0 && fKey < 13) - this.key = 'f' + fKey; - } - this.key = this.key || String.fromCharCode(this.code).toLowerCase();*/ - } - else if (this.type.match(/(click|mouse|menu)/i)) { - doc = (!doc.compatMode || doc.compatMode == 'CSS1Compat') ? doc.html : doc.body; - this.page = { - x: event.pageX || event.clientX + (doc ? doc.scrollLeft : 0), - y: event.pageY || event.clientY + (doc ? doc.scrollTop : 0) - }; - this.client = { - x: (event.pageX) ? event.pageX - win.pageXOffset : event.clientX, - y: (event.pageY) ? event.pageY - win.pageYOffset : event.clientY - }; - if (this.type.match(/DOMMouseScroll|mousewheel/)){ - this.wheel = (event.wheelDelta) ? event.wheelDelta / 120 : -(event.detail || 0) / 3; - } - this.rightClick = (event.which == 3) || (event.button == 2); - this.relatedTarget = null; - if (this.type.match(/over|out/)) { - if (this.type == "mouseover") - this.relatedTarget = event.relatedTarget || event.fromElement; - else if (this.type == "mouseout") - this.relatedTarget = event.relatedTarget || event.toElement; - else { - try { - while (this.relatedTarget && this.relatedTarget.nodeType == 3) - this.relatedTarget = this.relatedTarget.parentNode; - } - catch(e) {} - } - } - } - - this.shift = Boolean(event.shiftKey); - this.control = Boolean(event.ctrlKey); - this.alt = Boolean(event.altKey); - this.meta = Boolean(event.metaKey) - - this.stop = function(){ - return this.stopPropagation().preventDefault(); - }; - - this.stopPropagation = function(){ - if (this.event.stopPropagation) - this.event.stopPropagation(); - else - this.event.cancelBubble = true; - return this; - }; - - this.preventDefault = function(){ - if (this.event.preventDefault) - this.event.preventDefault(); - else - this.event.returnValue = false; - return this; - }; -}; - -jpf.AbstractEvent.KEYS = { - 'enter' : 13, - 'up' : 38, - 'down' : 40, - 'left' : 37, - 'right' : 39, - 'esc' : 27, - 'space' : 32, - 'backspace': 8, - 'tab' : 9, - 'delete' : 46, - - fromCode: function(code) { - for (var i in this) { - if (this[i] == code) - return i; - return null; - } - } -}; - -jpf.AbstractEvent.stop = function(event) { - return (new jpf.AbstractEvent(event)).stop(); -}; - -jpf.AbstractEvent.addListener = function(el, type, fn){ - if (el.addEventListener) - el.addEventListener(type, fn, false); - else if (el.attachEvent) - el.attachEvent('on' + type, fn); - return this; -}; - -jpf.AbstractEvent.removeListener = function(el, type, fn){ - if (el.removeEventListener) - el.removeEventListener(type, fn, false); - else if (el.detachEvent) - el.detachEvent('on' + type, fn); - return this; -}; - - - -/*FILEHEAD(/var/lib/jpf/src/core/lib/util/css.js)SIZE(-1077090856)TIME(1238933677)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -/** - * This method sets a single css rule - * @param {String} name the css name of the rule (i.e. '.cls' or '#id'). - * @param {String} type the css property to change. - * @param {String} value the css value of the property. - * @param {String} [stylesheet] the name of the stylesheet to change. - */ -jpf.setStyleRule = function(name, type, value, stylesheet, win){ - var rules = (win || self).document.styleSheets[stylesheet || 0][jpf.styleSheetRules]; - for (var i = 0; i < rules.length; i++) { - if (rules.item(i).selectorText == name) { - rules.item(i).style[type] = value; - return true; - } - } - - return false; -}; - -jpf.getStyleRule = function(name, type, stylesheet, win){ - if (!stylesheet) { - var sheets = (win || self).document.styleSheets; - for (var j = sheets.length - 1; j >= 0; j--) { - try { - var rules = sheets[j][jpf.styleSheetRules]; - for (var i = 0; i < rules.length; i++) { - if (rules.item(i).selectorText == name) { - return rules.item(i).style[type]; - } - } - } - catch(e){} - } - } - else { - var rules = (win || self).document.styleSheets[stylesheet || 0][jpf.styleSheetRules]; - for (var i = 0; i < rules.length; i++) { - if (rules.item(i).selectorText == name) { - return rules.item(i).style[type]; - } - } - } - - return false; -} - -/** - * This method adds one class name to an HTMLElement and removes none or more. - * @param {HTMLElement} oHtml the HTMLElement to apply the css class to. - * @param {String} className the name of the css class to apply. - * @param {Array} [exclusion] a list of strings specifying names of css classes to remove. - * @returns {HTMLElement} - */ -jpf.setStyleClass = function(oHtml, className, exclusion, special){ - if (!oHtml || this.disabled) - return; - - if (!className) className = " "; - - if (exclusion) - exclusion.push(className); - else - exclusion = [className]; - - //Remove defined classes - var re = new RegExp("(?:(^| +)" + exclusion.join("|") + "($| +))", "gi"); - //var re = new RegExp("(?:(?:^| +)(?:" + exclusion.join("|") + ")(?:$| +))", "gi"); - - if (oHtml.nodeFunc) { - throw new Error(jpf.formatErrorString(0, this, - "Setting style class", - "Trying to set style class on jml node. Only xml or html nodes can \ - be passed to this function")); - } - - //Set new class - oHtml.className != null - ? (oHtml.className = oHtml.className.replace(re, " ") + " " + className) - : oHtml.setAttribute("class", (oHtml.getAttribute("class") || "") - .replace(re, " ") + " " + className); - - return oHtml; -}; - -/** - * This method imports a css stylesheet from a string - * @param {Object} doc the reference to the document where the css is applied on - * @param {String} cssString the css definition - * @param {String} media the media to which this css applies (i.e. 'print' or 'screen') - */ -jpf.importCssString = function(doc, cssString, media){ - var htmlNode = doc.getElementsByTagName("head")[0];//doc.documentElement.getElementsByTagName("head")[0]; - - if (!jpf.supportOpacity) { - cssString = cssString.replace(/opacity[ \s]*\:[ \s]*([\d\.]+)/g, - function(m, m1){ - return "filter:progid:DXImageTransform.Microsoft.Alpha(opacity=" + (m1*100) + ")"; - }); - } - - if (jpf.canCreateStyleNode) { - //var head = document.getElementsByTagName("head")[0]; - var style = document.createElement("style"); - style.appendChild(document.createTextNode(cssString)); - htmlNode.appendChild(style); - } - else { - htmlNode.insertAdjacentHTML("beforeend", ".<style media='" - + (media || "all") + "'>" + cssString + "</style>"); - - /*if(document.body){ - document.body.style.height = "100%"; - setTimeout('document.body.style.height = "auto"'); - }*/ - } -}; - -/** - * This method retrieves the current value of a property on a HTML element - * recursively. If the style isn't found on the element itself, it's parent is - * checked. - * @param {HTMLElement} el the element to read the property from - * @param {String} prop the property to read - * @returns {String} - */ -jpf.getStyleRecur = function(el, prop) { - var value = jpf.hasComputedStyle - ? document.defaultView.getComputedStyle(el,'').getPropertyValue( - prop.replace(/([A-Z])/g, function(m, m1){ - return "-" + m1.toLowerCase(); - })) - : el.currentStyle[prop] - - return ((!value || value == "transparent" || value == "inherit") - && el.parentNode && el.parentNode.nodeType == 1) - ? this.getStyleRecur(el.parentNode, prop) - : value; -}; - -/** - * This method determines if specified coordinates are within the HTMLElement. - * @param {HTMLElement} el the element to check - * @param {Number} x the x coordinate in pixels - * @param {Number} y the y coordinate in pixels - * @returns {Boolean} - */ -jpf.isInRect = function(oHtml, x, y){ - var pos = this.getAbsolutePosition(oHtml); - if (x < pos[0] || y < pos[1] || x > oHtml.offsetWidth + pos[0] - 10 - || y > oHtml.offsetHeight + pos[1] - 10) - return false; - return true; -}; - -/** - * Retrieves the parent which provides the rectangle to which the HTMLElement is - * bound and cannot escape. In css this is accomplished by having the overflow - * property set to hidden or auto. - * @param {HTMLElement} o the element to check - * @returns {HTMLElement} - */ -jpf.getOverflowParent = function(o){ - //not sure if this is the correct way. should be tested - - o = o.offsetParent; - while (o && (this.getStyle(o, "overflow") != "hidden" - || "absolute|relative".indexOf(this.getStyle(o, "position")) == -1)) { - o = o.offsetParent; - } - return o || document.documentElement; -}; - -/** - * Retrieves the first parent element which has a position absolute or - * relative set. - * @param {HTMLElement} o the element to check - * @returns {HTMLElement} - */ -jpf.getPositionedParent = function(o){ - o = o.offsetParent; - while (o && o.tagName.toLowerCase() != "body" - && "absolute|relative".indexOf(this.getStyle(o, "position")) == -1) { - o = o.offsetParent; - } - return o || document.documentElement; -}; - -/** - * Retrieves the absolute x and y coordinates, relative to the browsers - * drawing area or the specified refParent. - * @param {HTMLElement} oHtml the element to check - * @param {HTMLElement} [refParent] the reference parent - * @param {Boolean} [inclSelf] whether to include the position of the element to check in the return value. - * @returns {Array} the x and y coordinate of oHtml. - */ -jpf.getAbsolutePosition = function(o, refParent, inclSelf){ - var wt = inclSelf ? 0 : o.offsetLeft, ht = inclSelf ? 0 : o.offsetTop; - o = inclSelf ? o : o.offsetParent; - - var z, bw, bh, foundPosRel = 0; - while (o && o != refParent) {//&& o.tagName.toLowerCase() != "html" - //Border - Left - bw = jpf.isOpera ? 0 : this.getStyle(o, jpf.descPropJs - ? "borderLeftWidth" : "border-left-width"); - - wt += (jpf.isIE && o.currentStyle.borderLeftStyle != "none" && bw == "medium" - ? 2 - : parseInt(bw) || 0) + o.offsetLeft; - - //Border - Top - bh = jpf.isOpera ? 0 : this.getStyle(o, jpf.descPropJs - ? "borderTopWidth" : "border-top-width"); - ht += (jpf.isIE && o.currentStyle.borderTopStyle != "none" && bh == "medium" - ? 2 - : parseInt(bh) || 0) + o.offsetTop; - - //Scrolling - wt -= o.scrollLeft; - ht -= o.scrollTop; - - //Table support - if (o.tagName.toLowerCase() == "table") { - ht -= parseInt(o.border || 0) + parseInt(o.cellSpacing || 0); - wt -= parseInt(o.border || 0) + parseInt(o.cellSpacing || 0) * 2; - } - else if (o.tagName.toLowerCase() == "tr") { - ht -= (cp = parseInt(o.parentNode.parentNode.cellSpacing)); - while (o.previousSibling) - ht -= (o = o.previousSibling).offsetHeight + cp; - } - - if (!o.offsetParent && o.parentNode.nodeType == 1) { - wt -= o.parentNode.scrollLeft; - ht -= o.parentNode.scrollTop; - } - - o = o.offsetParent; - } - - return [wt, ht]; -}; - - - -/*FILEHEAD(/var/lib/jpf/src/core/lib/util/plane.js)SIZE(-1077090856)TIME(1238933677)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - -/** - * @private - */ -jpf.plane = { - init : function(){ - if (!this.plane) { - this.plane = document.createElement("DIV"); - document.body.appendChild(this.plane); - this.plane.style.background = "url(images/spacer.gif)"; - this.plane.style.position = "absolute"; - this.plane.style.zIndex = 100000000; - this.plane.style.left = 0; - this.plane.style.top = 0; - } - }, - - lastCursor : null, - show : function(o, dontAppend, copyCursor){ - this.init(); - - var plane = this.plane; - this.current = o; - //o.parentNode.appendChild(plane); - - if (!dontAppend) { - this.lastZ = this.current.style.zIndex; - this.current.style.zIndex = 100000; - } - else { - this.plane.appendChild(o); - } - - var pWidth = (plane.parentNode == document.body - ? (jpf.isIE - ? plane.offsetParent.offsetWidth - : window.innerWidth) - : plane.parentNode.offsetWidth); - - var pHeight = (plane.parentNode == document.body - ? (jpf.isIE - ? plane.offsetParent.offsetHeight - : window.innerHeight) - : plane.parentNode.offsetHeight); - - if (copyCursor) { - if (this.lastCursor === null) - this.lastCursor = document.body.style.cursor; - document.body.style.cursor = jpf.getStyle(o, "cursor"); - } - - this.plane.style.display = "block"; - //this.plane.style.left = p.scrollLeft; - //this.plane.style.top = p.scrollTop; - - var diff = jpf.getDiff(plane.parentNode); - this.plane.style.width = (pWidth - diff[0]) + "px"; - this.plane.style.height = (pHeight - diff[1]) + "px"; - - return plane; - }, - - hide : function(){ - var isChild = jpf.xmldb.isChildOf(this.plane, document.activeElement); - - if (this.lastZ) { - if (this.current.style.zIndex == 100000) - this.current.style.zIndex = this.lastZ; - this.lastZ = null; - } - - if (this.current.parentNode == this.plane) - this.plane.parentNode.appendChild(this.current); - - this.plane.style.display = "none"; - - if (isChild) { - if (!jpf.isIE) - document.activeElement.focus(); - jpf.window.focussed.$focus(); - } - - this.current = null; - - if (this.lastCursor !== null) { - document.body.style.cursor = this.lastCursor; - this.lastCursor = null; - } - - return this.plane; - } -}; - - -/*FILEHEAD(/var/lib/jpf/src/core/lib/util/cookie.js)SIZE(-1077090856)TIME(1224578766)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -/** - * Sets a name/value pair which is stored in the browser and sent to the server - * with every request. This is also known as a cookie. Be careful setting - * cookies, because they can take up a lot of bandwidth, especially for Ajax - * applications. - */ -jpf.setcookie = function(name, value, expire, path, domain, secure){ - var ck = name + "=" + escape(value) + ";"; - if (expire) ck += "expires=" + new Date(expire - + new Date().getTimezoneOffset() * 60).toGMTString() + ";"; - if (path) ck += "path=" + path + ";"; - if (domain) ck += "domain=" + domain; - if (secure) ck += "secure"; - - document.cookie = ck; - return value -}; - -/** - * Gets the value of a stored name/value pair called a cookie. - * @param {String} name the name of the stored cookie. - */ -jpf.getcookie = function (name){ - var aCookie = document.cookie.split("; "); - for (var i=0; i < aCookie.length; i++) { - var aCrumb = aCookie[i].split("="); - if (name == aCrumb[0]) - return unescape(aCrumb[1]); - } - - return ""; -}; - -/** - * Deletes a stored name/value pair called a cookie. - * @param {String} name the name of the stored cookie. - */ -jpf.delcookie = function (name, domain){ - document.cookie = name + "=blah; expires=Fri, 31 Dec 1999 23:59:59 GMT;" - + (domain ? 'domain='+domain : ''); -}; - - - -/*FILEHEAD(/var/lib/jpf/src/core/lib/storage/flash.js)SIZE(-1077090856)TIME(1238933676)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-// summary:
-// Storage provider that uses features in Flash to achieve permanent
-// storage
-// description:
-
-jpf.namespace("storage.modules.flash", {
- initialized : false,
- asyncInit : true,
-
- _available : null,
- _statusHandler: null,
- _flashReady : false,
- _pageReady : false,
-
- delayCalls : [],
-
- init: function(){
- this.name = "flashStorage";
- this.id = jpf.flash.addPlayer(this);
-
- // IE/Flash has an evil bug that shows up some time: if we load the
- // Flash and it isn't in the cache, ExternalInterface works fine --
- // however, the second time when its loaded from the cache a timing
- // bug can keep ExternalInterface from working. The trick below
- // simply invalidates the Flash object in the cache all the time to
- // keep it loading fresh. -- Brad Neuberg
- this.STORAGE_SWF = (jpf.appsettings.resourcePath || jpf.basePath)
- + "resources/jpfStorage.swf?cachebust="
- + new Date().getTime();
-
- var flash = jpf.flash.buildContent(
- "src", this.STORAGE_SWF,
- "width", "215",
- "height", "138",
- "align", "middle",
- "id", this.name,
- "quality", "high",
- "bgcolor", "#ffffff",
- "allowFullScreen", "true",
- "name", this.name,
- "flashvars", "playerID=" + this.id,
- "allowScriptAccess","always",
- "type", "application/x-shockwave-flash",
- "pluginspage", "http://www.adobe.com/go/getflashplayer",
- "menu", "true");
-
- this.container = document.createElement('div');
- this.container.id = this.name + "_Container";
- this.container.className = "jpfVideo";
- with (this.container.style) {
- width = height = "0px";
- overflow = "hidden";
- }
- document.body.appendChild(this.container);
- this.container.innerHTML = flash;
-
- //this.container = document.getElementById(this.name + "_Container");
- this.player = jpf.flash.getElement(this.name);
-
- // get available namespaces
- this._allNamespaces = this.getNamespaces();
-
- this._flashReady = this._pageReady = true;
- },
-
- /**
- * Sets the visibility of this Flash object.
- *
- * @param {Boolean} visible
- */
- setVisible: function(visible){
- if (visible == true) {
- this.container.style.position = "absolute"; // IE -- Brad Neuberg
- this.container.style.visibility = "visible";
- }
- else {
- with (this.container.style) {
- position = "absolute";
- x = "-1000px";
- y = "-1000px";
- visibility = "hidden";
- }
- }
- return this;
- },
-
- /**
- * All public methods use this proxy to make sure that methods called before
- * initialization are properly called after the player is ready.
- * Supply three arguments maximum, because function.apply does not work on
- * the flash object.
- *
- * @param {String} param1
- * @param {String} param2
- * @param {String} param3
- * @type {Object}
- */
- callMethod: function(param1, param2, param3, param4, param5) {
- if (this.initialized && typeof this.player.callMethod == "function") {
- try {
- return this.player.callMethod(
- jpf.flash.encode(param1),
- jpf.flash.encode(param2),
- jpf.flash.encode(param3),
- jpf.flash.encode(param4),
- jpf.flash.encode(param5)
- ); // function.apply does not work on the flash object
- }
- catch (ex) {}
- }
- else
- this.delayCalls.push(arguments);
- },
-
- /**
- * Call methods that were made before the player was initialized.
- *
- * @type {Object}
- */
- delayedCallTimer: null,
- makeDelayCalls : function() {
- clearTimeout(this.delayedCallTimer);
-
- if (!this.delayCalls.length) {
- if (typeof this['onready'] == "function")
- this.onready();
- return this;
- }
-
- this.callMethod.apply(this, this.delayCalls[0]);
- this.delayCalls.splice(0, 1);
-
- //run timeout, we're interfacing with Flash here :S
- var _self = this;
- this.delayedCallTimer = window.setTimeout(function() {
- _self.makeDelayCalls();
- }, 1);
-
- return this;
- },
-
- ready : function(callback){
- if (this.initialized)
- callback();
- else
- this.onready = callback;
- },
-
- event: function(sEventName, oData) {
- //jpf.console.info('Event called: ' + sEventName + ', ' + oData);
- if (sEventName == "status") {
- // Called if the storage system needs to tell us about the status
- // of a put() request.
- var ds = jpf.storage;
-
- if (statusResult == ds.PENDING) {
- //dfo.center();
- this.setVisible(true);
- }
- else
- this.setVisible(false);
-
- if (ds._statusHandler)
- ds._statusHandler.call(null, oData.status, oData.keyName, oData.namespace);
- }
- else if (sEventName == "loaded") {
- this.initialized = true;
- this.setVisible(false).makeDelayCalls();
- }
- },
-
- // Set a new value for the flush delay timer.
- // Possible values:
- // 0 : Perform the flush synchronously after each "put" request
- // > 0 : Wait until 'newDelay' ms have passed without any "put" request to flush
- // -1 : Do not automatically flush
- setFlushDelay: function(newDelay){
- if (newDelay === null || typeof newDelay === "undefined" || isNaN(newDelay))
- throw new Error("Invalid argunment: " + newDelay);
-
- this.callMethod('setFlushDelay', String(newDelay));
- },
-
- getFlushDelay: function(){
- return Number(this.callMethod('getFlushDelay'));
- },
-
- flush: function(namespace){
- //@fixme: is this test necessary? Just use !namespace
- if (namespace == null || typeof namespace == "undefined") {
- namespace = jpf.storage.namespace;
- }
- this.callMethod('flush', namespace);
- },
-
- /**
- * @todo replace this with mikes flash detection code
- */
- isAvailable: function(){
- return location.protocol != "file:" && jpf.flash.isEightAvailable();
- },
-
- put: function(key, value, namespace){
- if (this.isValidKey(key) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Setting name/value pair", "Invalid key given: " + key));
-
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Setting name/value pair", "Invalid namespace given: " + namespace));
-
- this.callMethod('put', key, jpf.serialize(value), namespace);
- },
-
- putMultiple: function(keys, values, namespace){
- if (this.isValidKeyArray(keys) === false
- || ! values instanceof Array
- || keys.length != values.length){
- throw new Error(jpf.formatErrorString(0, null,
- "Setting multiple name/value pairs", "Invalid arguments: keys = ["
- + keys + "], values = [" + values + "]"));
- }
-
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null, "Setting multiple name/value pairs", "Invalid namespace given: " + namespace));
-
- // Convert the arguments on strings we can pass along to Flash
- var metaKey = keys.join(",");
- var lengths = [];
- for (var i = 0; i < values.length; i++) {
- values[i] = jpf.unserialize(values[i]);
- lengths[i] = values[i].length;
- }
- var metaValue = values.join("");
- var metaLengths = lengths.join(",");
- this.callMethod('putMultiple', metaKey, metaValue, metaLengths, namespace);
- },
-
- get: function(key, namespace){
- if (this.isValidKey(key) == false)
- throw new Error(jpf.formatErrorString(0, null, "Getting name/value pair", "Invalid key given: " + key));
-
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Getting name/value pair", "Invalid namespace given: " + namespace));
-
- var results = this.callMethod('get', key, namespace);
- if (results == "")
- return null;
-
- return jpf.unserialize(jpf.flash.decode(results));
- },
-
- getMultiple: function(keys, namespace){
- if (this.isValidKeyArray(keys) === false)
- throw new Error(jpf.formatErrorString(0, null,
- "Getting name/value pair", "Invalid key array given: " + keys));
-
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Getting multiple name/value pairs", "Invalid namespace given: "
- + namespace));
-
- var metaKey = keys.join(",");
- var metaResults = this.callMethod('getMultiple', metaKey, namespace);
- if (!metaResults)
- return null;
- var results = eval("(" + metaResults.replace(/""([^",\]]+)/g, '"\\"$1')
- .replace(/([^",]+)""/g, '$1\\""') + ")");
-
- // destringify each entry back into a real JS object
- for (var i = 0; i < results.length; i++)
- results[i] = (results[i] == "") ? null : jpf.unserialize(jpf.flash.decode(results[i]));
-
- return results;
- },
-
- _destringify: function(results){
- // destringify the content back into a
- // real JavaScript object;
- // handle strings differently so they have better performance
- if (typeof results == "string" && (/^string:/.test(results)))
- results = results.substring("string:".length);
- else
- results = eval(results);
-
- return results;
- },
-
- getKeys: function(namespace){
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null, "Clearing storage",
- "Invalid namespace given: " + namespace));
-
- var results = this.callMethod('getKeys', namespace);
-
- // Flash incorrectly returns an empty string as "null"
- if (results == this || results == null || results == "null")
- results = "";
-
- results = results.split(",");
- results.sort();
-
- return results;
- },
-
- getNamespaces: function(){
- var results = this.callMethod('getNamespaces');
-
- // Flash incorrectly returns an empty string as "null"
- if (results == this || results == null || results == "null")
- results = jpf.storage.namespace || "default";
-
- results = results.split(",");
- results.sort();
-
- return results;
- },
-
- clear: function(namespace){
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null, "Clearing storage",
- "Invalid namespace given: " + namespace));
-
- this.callMethod('clear', namespace);
- },
-
- remove: function(key, namespace){
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null, "Removing key",
- "Invalid namespace given: " + namespace));
-
- this.callMethod('remove', key, namespace);
- },
-
- removeMultiple: function(/*array*/ keys, /*string?*/ namespace){ /*Object*/
- if (this.isValidKeyArray(keys) === false)
- throw new Error(jpf.formatErrorString(0, null,
- "Getting name/value pair", "Invalid key array given: " + keys));
-
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Getting multiple name/value pairs", "Invalid namespace given: "
- + namespace));
-
- var metaKey = keys.join(",");
- this.callMethod('removeMultiple', metaKey, namespace);
- },
-
- isPermanent: function(){
- return true;
- },
-
- getMaximumSize: function(){
- return this.SIZE_NO_LIMIT;
- },
-
- hasSettingsUI: function(){
- return false;
- },
-
- showSettingsUI: function(){
- throw new Error(jpf.formatErrorString(0, null, this.declaredClass
- + " does not support a storage settings user-interface"));
- },
-
- hideSettingsUI: function(){
- throw new Error(jpf.formatErrorString(0, null, this.declaredClass
- + " does not support a storage settings user-interface"));
- },
-
- getResourceList: function(){ /* Array[] */
- // @todo: implement offline support icw Flash storage
- return [];
- }
-});
- - -/*FILEHEAD(/var/lib/jpf/src/core/lib/storage/memory.js)SIZE(-1077090856)TIME(1225842281)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * Storage module using javascript objects to store the data. When the
- * application restarts or closes this data is be purged. This module is used
- * when no other storage mechanism is available to still allow for some of the
- * features that depend on a storage mechanism to be available.
- * @default_private
- */
-jpf.namespace("storage.modules.memory", {
- initialized: true,
- store : {},
-
- isAvailable: function(){
- return true;
- },
-
- /**
- * Stores a key value pair in a namespace.
- * @param {String} key the identifier of the information.
- * @param {mixed} value the information to store.
- * @param {String} namespace the named context into which to store the key value pair.
- */
- put: function(key, value, namespace){
- if (this.isValidKey(key) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Setting name/value pair",
- "Invalid key given: " + key));
-
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Setting name/value pair",
- "Invalid namespace given: " + namespace));
-
- // serialize the value;
- value = jpf.serialize(value);
-
- // store the value
- if (!this.store[namespace])
- this.store[namespace] = {};
-
- this.store[namespace][key] = value;
- },
-
- /**
- * Retrieves a keys in a namespace.
- * @param {String} key the identifier of the information.
- * @param {String} namespace the named context of the keys to retrieve.
- * @return {mixed} the value that correspond to the key in the namespace.
- */
- get: function(key, namespace){
- if (this.isValidKey(key) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Getting name/value pair",
- "Invalid key given: " + key));
-
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Getting name/value pair",
- "Invalid namespace given: " + namespace));
-
- if (!this.store[namespace] || !this.store[namespace][key])
- return null;
-
- return jpf.unserialize(this.store[namespace][key]);
- },
-
- /**
- * Retrieves all the namespaces in use.
- * @return {Array} list of namespaces.
- */
- getNamespaces: function(){
- var results = [ this.namespace ];
-
- for (var ns in this.store)
- results.push(ns);
-
- return results;
- },
-
- /**
- * Retrieves all the keys of a namespace.
- * @param {String} namespace the named context of the keys to retrieve.
- * @return {Array} the list of keys in the namespace.
- */
- getKeys: function(namespace){
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Clearing storage",
- "Invalid namespace given: " + namespace));
-
- var results = [];
- for (var prop in this.store[namespace])
- results.push(prop);
-
- return results;
- },
-
- /**
- * Removes all keys from a namespace
- */
- clear: function(namespace){
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Clearing storage",
- "Invalid namespace given: " + namespace));
-
- delete this.store[namespace]
- },
-
- /**
- * Removes a key in a namespace.
- * @param {String} key the identifier of the information.
- * @param {String} namespace the named context of the keys to remove.
- */
- remove: function(key, namespace){
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Removing key",
- "Invalid namespace given: " + namespace));
-
- if (this.store[namespace])
- delete this.store[namespace][key];
- },
-
- /**
- * Stores a key value pair in a namespace.
- * @param {Array} keys a list of keys that identify the information stored.
- * @param {Array} values a list of values to store.
- * @param {String} namespace the named context into which to store the key value pair.
- */
- putMultiple: function(keys, values, namespace) {
- if (this.isValidKeyArray(keys) === false
- || ! values instanceof Array
- || keys.length != values.length) {
- throw new Error(jpf.formatErrorString(0, null,
- "Setting multiple name/value pairs",
- "Invalid arguments: keys = [" + keys + "], \
- values = [" + values + "]"));
- }
-
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Setting multiple name/value pairs",
- "Invalid namespace given: " + namespace));
-
- // store the value
- if (!this.store[namespace])
- this.store[namespace] = {};
-
- // try to store the value
- for (var i = 0; i < keys.length; i++) {
- this.store[namespace][keys[i]] = jpf.serialize(values[i]);
- }
-
- return true;
- },
-
- /**
- * Retrieves all the values of several keys in a namespace.
- * @param {Array} keys a list of keys that identify the information retrieved.
- * @param {String} namespace the named context into which to store the key value pair.
- * @returns {Array} list of values that have been retrieved.
- */
- getMultiple: function(keys, namespace){
- if (this.isValidKeyArray(keys) === false)
- throw new Error(jpf.formatErrorString(0, null,
- "Getting name/value pair",
- "Invalid key array given: " + keys));
-
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Getting multiple name/value pairs",
- "Invalid namespace given: " + namespace));
-
- if (!this.store[namespace])
- return [];
-
- var results = [];
- for (var i = 0; i < keys.length; i++){
- if (this.store[namespace][keys[i]])
- results.push(jpf.unserialize(this.store[namespace][keys[i]]));
- }
-
- return results;
- },
-
- /**
- * Removes a key in a namespace.
- * @param {Array} keys a list of keys that identify the information to be removed.
- * @param {String} namespace the named context of the keys to remove.
- */
- removeMultiple: function(keys, namespace){
- if (this.isValidKeyArray(keys) === false)
- throw new Error(jpf.formatErrorString(0, null,
- "Removing name/value pair",
- "Invalid key array given: " + keys));
-
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Removing multiple name/value pairs",
- "Invalid namespace given: " + namespace));
-
- if (!this.store[namespace])
- return;
-
- for (var i = 0; i < keys.length; i++)
- delete this.store[namespace][keys[i]];
- },
-
- isPermanent: function(){
- return false;
- },
-
- getMaximumSize: function(){
- return this.SIZE_NO_LIMIT;
- },
-
- hasSettingsUI: function(){
- return false;
- },
-
- showSettingsUI: function(){
- throw new Error(this.declaredClass
- + " does not support a storage settings user-interface");
- },
-
- hideSettingsUI: function(){
- throw new Error(this.declaredClass
- + " does not support a storage settings user-interface");
- }
-});
- - -/*FILEHEAD(/var/lib/jpf/src/core/lib/storage/air.file.js)SIZE(-1077090856)TIME(1225628611)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-// summary:
-// Storage provider that uses features in the Adobe AIR runtime to achieve
-// permanent storage
-
-jpf.namespace("storage.modules['air.file']", {
- initialized: false,
-
- init: function(){
- this.File = window.runtime.flash.filesystem.File;
- this.FileStream = window.runtime.flash.filesystem.FileStream;
- this.FileMode = window.runtime.flash.filesystem.FileMode;
-
- this.storagePath = "__JPF_" + (jpf.appsettings.name
- ? jpf.appsettings.name.toUpperCase()
- : "STORAGE") + "/";
-
- // need to initialize our storage directory
- try {
- var dir = this.File.applicationStorageDirectory.resolvePath(this.storagePath);
- if (!dir.exists)
- dir.createDirectory();
- this.initialized = true;
- }
- catch(e) {
- jpf.console.warn(e.message);
- return false;
- }
- },
-
- isAvailable: function(){
- return jpf.isAIR;
- },
-
- put: function(key, value, namespace){
- if (this.isValidKey(key) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Setting name/value pair",
- "Invalid key given: " + key));
-
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Setting name/value pair",
- "Invalid namespace given: " + namespace));
-
- // try to store the value
- try {
- this.remove(key, namespace);
-
- var dir = this.File.applicationStorageDirectory.resolvePath(this.storagePath + namespace);
- if (!dir.exists)
- dir.createDirectory();
-
- var file = dir.resolvePath(key);
- var stream = new this.FileStream();
- stream.open(file, this.FileMode.WRITE);
- stream.writeObject(value);
- stream.close();
- }
- catch(e) {
- throw new Error(jpf.formatErrorString(0, null,
- "Setting name/value pair",
- "Error writing file: " + e.message));
-
- return false;
- }
-
- return true;
- },
-
- get: function(key, namespace){
- if (this.isValidKey(key) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Getting name/value pair",
- "Invalid key given: " + key));
-
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Getting name/value pair",
- "Invalid namespace given: " + namespace));
-
- var file = this.File.applicationStorageDirectory.resolvePath(this.storagePath + namespace + '/' + key);
- if (!file.exists || file.isDirectory)
- return false;
-
- var stream = new this.FileStream();
- stream.open(file, this.FileMode.READ);
- var results = stream.readObject();
- stream.close();
-
- return results;
- },
-
- getNamespaces: function(){
- var results = [ this.namespace ];
- var dir = this.File.applicationStorageDirectory.resolvePath(this.storagePath);
- var files = dir.getDirectoryListing();
- for (var i = 0; i < files.length; i++) {
- if (files[i].isDirectory && files[i].name != this.namespace)
- results.push(files[i].name);
- }
-
- return results;
- },
-
- getKeys: function(namespace){
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Clearing storage",
- "Invalid namespace given: " + namespace));
-
- var results = [];
- var dir = this.File.applicationStorageDirectory.resolvePath(this.storagePath + namespace);
- if (dir.exists && dir.isDirectory){
- var files = dir.getDirectoryListing();
- for (var i = 0; i < files.length; i++)
- results.push(files[i].name);
- }
- return results;
- },
-
- clear: function(namespace){
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Clearing storage",
- "Invalid namespace given: " + namespace));
-
- var dir = this.File.applicationStorageDirectory.resolvePath(this.storagePath + namespace);
- if (dir.exists && dir.isDirectory)
- dir.deleteDirectory(true);
- },
-
- remove: function(key, namespace){
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Removing key",
- "Invalid namespace given: " + namespace));
-
- var file = this.File.applicationStorageDirectory.resolvePath(this.storagePath + namespace + '/' + key);
- if (file.exists && !file.isDirectory)
- file.deleteFile();
- },
-
- putMultiple: function(keys, values, namespace) {
- if (this.isValidKeyArray(keys) === false
- || ! values instanceof Array
- || keys.length != values.length){
- throw new Error(jpf.formatErrorString(0, null,
- "Setting multiple name/value pairs",
- "Invalid arguments: keys = [" + keys + "], values = [" + values + "]"));
- }
-
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Setting multiple name/value pairs",
- "Invalid namespace given: " + namespace));
-
- // try to store the value
- try {
- for (var i = 0; i < keys.length; i++)
- this.put(keys[i], values[i], null, namespace);
- }
- catch(e) {
- throw new Error(jpf.formatErrorString(0, null,
- "Writing multiple name/value pair",
- "Error writing file: " + e.message));
- return false;
- }
-
- return true;
- },
-
- getMultiple: function(keys, namespace){
- if (this.isValidKeyArray(keys) === false)
- throw new Error(jpf.formatErrorString(0, null,
- "Getting name/value pair",
- "Invalid key array given: " + keys));
-
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Getting multiple name/value pairs",
- "Invalid namespace given: " + namespace));
-
- var results = [];
- for (var i = 0; i < keys.length; i++)
- results[i] = this.get(keys[i], namespace);
-
- return results;
- },
-
- removeMultiple: function(keys, namespace){
- if (this.isValidKeyArray(keys) === false)
- throw new Error(jpf.formatErrorString(0, null,
- "Removing name/value pair",
- "Invalid key array given: " + keys));
-
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Removing multiple name/value pairs",
- "Invalid namespace given: " + namespace));
-
- for (var i = 0; i < keys.length; i++)
- this.remove(keys[i], namespace);
- },
-
- isPermanent: function(){
- return true;
- },
-
- getMaximumSize: function(){
- return this.SIZE_NO_LIMIT;
- },
-
- hasSettingsUI: function(){
- return false;
- },
-
- showSettingsUI: function(){
- throw new Error(this.declaredClass
- + " does not support a storage settings user-interface");
- },
-
- hideSettingsUI: function(){
- throw new Error(this.declaredClass
- + " does not support a storage settings user-interface");
- }
-});
-
- -/*FILEHEAD(/var/lib/jpf/src/core/lib/storage/air.sql.js)SIZE(-1077090856)TIME(1225628611)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-// summary:
-// Storage provider that uses features in the Adobe AIR runtime to achieve
-// permanent storage
-
-jpf.namespace("storage.modules['air.sql']", {
- database_file: "jpf.db",
-
- initialized: false,
- _db: null,
-
- init: function(){
- this.File = window.runtime.flash.filesystem.File;
- this.SQLConnection = window.runtime.flash.data.SQLConnection;
- this.SQLStatement = window.runtime.flash.data.SQLStatement;
-
- this.table_name = "__JPF_" + (jpf.appsettings.name
- ? jpf.appsettings.name.toUpperCase()
- : "STORAGE");
-
- // need to initialize our storage database
- try {
- this._db = new this.SQLConnection();
- this._db.open(this.File.applicationStorageDirectory.resolvePath(this.database_file));
-
- this._sql("CREATE TABLE IF NOT EXISTS " + this.table_name
- + "(namespace TEXT, key TEXT, value TEXT)");
- this._sql("CREATE UNIQUE INDEX IF NOT EXISTS namespace_key_index ON "
- + this.table_name + " (namespace, key)");
-
- this.initialized = true;
- }
- catch(e) {
- jpf.console.warn(e.message);
- return false;
- }
- },
-
- _sql: function(query, params){
- var stmt = new this.SQLStatement();
- stmt.sqlConnection = this._db;
- stmt.text = query;
- if (params)
- jpf.extend(stmt.parameters, params);
-
- stmt.execute();
- return stmt.getResult();
- },
-
- isAvailable: function(){
- return jpf.isAIR;
- },
-
- put: function(key, value, namespace){
- if (this.isValidKey(key) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Setting name/value pair",
- "Invalid key given: " + key));
-
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Setting name/value pair",
- "Invalid namespace given: " + namespace));
-
- // try to store the value
- try {
- this._sql("DELETE FROM " + this.table_name
- + " WHERE namespace = :namespace AND key = :key",
- {
- ":namespace": namespace,
- ":key" : key
- });
- this._sql("INSERT INTO " + this.table_name
- + " VALUES (:namespace, :key, :value)",
- {
- ":namespace": namespace,
- ":key" : key,
- ":value" : value
- });
- }
- catch(e) {
- throw new Error(jpf.formatErrorString(0, null,
- "Setting name/value pair",
- "Error writing file: " + e.message));
-
- return false;
- }
-
- return true;
- },
-
- get: function(key, namespace){
- if (this.isValidKey(key) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Getting name/value pair",
- "Invalid key given: " + key));
-
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Getting name/value pair",
- "Invalid namespace given: " + namespace));
-
- var results = this._sql("SELECT * FROM " + this.table_name
- + " WHERE namespace = :namespace AND key = :key",
- {
- ":namespace": namespace,
- ":key" : key
- });
-
- if (results.data && results.data.length)
- return results.data[0].value;
-
- return null;
- },
-
- getNamespaces: function(){
- var results = [ this.namespace ];
- var rs = this._sql("SELECT namespace FROM " + this.table_name + " DESC GROUP BY namespace");
- if (rs.data) {
- for (var i = 0; i < rs.data.length; i++) {
- if (rs.data[i].namespace != this.namespace)
- results.push(rs.data[i].namespace);
- }
- }
- return results;
- },
-
- getKeys: function(namespace){
- if(!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Clearing storage",
- "Invalid namespace given: " + namespace));
-
- var results = [];
- var rs = this._sql("SELECT key FROM " + this.table_name
- + " WHERE namespace = :namespace", {
- ":namespace": namespace
- });
- if (rs.data) {
- for (var i = 0; i < rs.data.length; i++)
- results.push(rs.data[i].key);
- }
- return results;
- },
-
- clear: function(namespace){
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Clearing storage",
- "Invalid namespace given: " + namespace));
-
- this._sql("DELETE FROM " + this.table_name
- + " WHERE namespace = :namespace", {
- ":namespace":namespace
- });
- },
-
- remove: function(key, namespace){
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Removing key",
- "Invalid namespace given: " + namespace));
-
- this._sql("DELETE FROM " + this.table_name
- + " WHERE namespace = :namespace AND key = :key",
- {
- ":namespace": namespace,
- ":key" : key
- });
- },
-
- putMultiple: function(keys, values, namespace) {
- if (this.isValidKeyArray(keys) === false
- || ! values instanceof Array
- || keys.length != values.length){
- throw new Error(jpf.formatErrorString(0, null,
- "Setting multiple name/value pairs",
- "Invalid arguments: keys = [" + keys + "], values = [" + values + "]"));
- }
-
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Setting multiple name/value pairs",
- "Invalid namespace given: " + namespace));
-
- // try to store the value
- try {
- this._db.begin();
- for (var i = 0; i < keys.length; i++) {
- this._sql("DELETE FROM " + this.table_name
- + " WHERE namespace = :namespace AND key = :key",
- {
- ":namespace": namespace,
- ":key" : key[i]
- });
- this._sql("INSERT INTO " + this.table_name
- + " VALUES (:namespace, :key, :value)",
- {
- ":namespace": namespace,
- ":key" : key[i],
- ":value" : value
- });
- }
- this._db.commit();
- }
- catch(e) {
- throw new Error(jpf.formatErrorString(0, null,
- "Writing multiple name/value pair",
- "Error writing file: " + e.message));
- return false;
- }
-
- return true;
- },
-
- getMultiple: function(keys, namespace){
- if (this.isValidKeyArray(keys) === false)
- throw new Error(jpf.formatErrorString(0, null,
- "Getting name/value pair",
- "Invalid key array given: " + keys));
-
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Getting multiple name/value pairs",
- "Invalid namespace given: " + namespace));
-
- var results = [];
- for (var i = 0; i < keys.length; i++) {
- var result = this._sql("SELECT * FROM " + this.table_name
- + " WHERE namespace = :namespace AND key = :key",
- {
- ":namespace": namespace,
- ":key" : keys[i]
- });
- results[i] = result.data && result.data.length
- ? result.data[0].value
- : null;
- }
-
- return results;
- },
-
- removeMultiple: function(keys, namespace){
- if (this.isValidKeyArray(keys) === false)
- throw new Error(jpf.formatErrorString(0, null,
- "Removing name/value pair",
- "Invalid key array given: " + keys));
-
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Removing multiple name/value pairs",
- "Invalid namespace given: " + namespace));
-
- this._db.begin();
- for (var i = 0; i < keys.length;i++) {
- this._sql("DELETE FROM " + this.table_name
- + " WHERE namespace = namespace = :namespace AND key = :key",
- {
- ":namespace": namespace,
- ":key" : keys[i]
- });
- }
- this._db.commit();
- },
-
- isPermanent: function(){
- return true;
- },
-
- getMaximumSize: function(){
- return this.SIZE_NO_LIMIT;
- },
-
- hasSettingsUI: function(){
- return false;
- },
-
- showSettingsUI: function(){
- throw new Error(this.declaredClass + " does not support a storage settings user-interface");
- },
-
- hideSettingsUI: function(){
- throw new Error(this.declaredClass + " does not support a storage settings user-interface");
- }
-});
-
- -/*FILEHEAD(/var/lib/jpf/src/core/lib/storage/gears.js)SIZE(-1077090856)TIME(1225842322)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * Storage provider that uses Google Gears to store data.
- */
-jpf.storage.modules.gears =
-jpf.storage.modules["gears.sql"] = {
- // instance methods and properties
- table_name : "STORAGE",
- initialized : false,
-
- $available : null,
- $db : null,
-
- init: function(){
- this.factory = jpf.nameserver.get("google", "gears");
- this.database_name = jpf.appsettings.name + ".jpf.offline.gears";
-
- this.$db = this.factory.create('beta.database', '1.0');
- this.$db.open(this.database_name);
-
- // create the table that holds our data
- try {
- this.$sql("CREATE TABLE IF NOT EXISTS " + this.table_name + "( "
- + " namespace TEXT, "
- + " key TEXT, "
- + " value TEXT "
- + ")"
- );
- this.$sql("CREATE UNIQUE INDEX IF NOT EXISTS namespace_key_index"
- + " ON " + this.table_name
- + " (namespace, key)");
-
- this.initialized = true;
- }
- catch(e) {
- jpf.console.warn(e.message);
- return false;
- }
- },
-
- $sql: function(query, params){
- var rs = this.$db.execute(query, params);
-
- return this.$normalizeResults(rs); //can I do this after I close db?
- },
-
- destroy : function(){
- //if (!jpf.isIE)
- this.$db.close();
- },
-
- $normalizeResults: function(rs){
- var results = [];
- if (!rs) return [];
-
- while (rs.isValidRow()) {
- var row = {};
-
- for (var i = 0; i < rs.fieldCount(); i++) {
- var fieldName = rs.fieldName(i);
- var fieldValue = rs.field(i);
- row[fieldName] = fieldValue;
- }
-
- results.push(row);
-
- rs.next();
- }
-
- rs.close();
-
- return results;
- },
-
- isAvailable: function(){
- // is Google Gears available and defined?
- return jpf.isGears;
- },
-
- put: function(key, value, namespace){
- if (this.isValidKey(key) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Setting name/value pair",
- "Invalid key given: " + key));
-
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Setting name/value pair",
- "Invalid namespace given: " + namespace));
-
- value = jpf.serialize(value);
-
- // try to store the value
- try {
- this.$sql("DELETE FROM " + this.table_name
- + " WHERE namespace = ? AND key = ?",
- [namespace, key]);
- this.$sql("INSERT INTO " + this.table_name
- + " VALUES (?, ?, ?)",
- [namespace, key, value]);
- }
- catch(e) {
- throw new Error(jpf.formatErrorString(0, null,
- "Setting name/value pair",
- "Error setting name/value pair: " + e.message));
- return false;
- }
-
- return true;
- },
-
- get: function(key, namespace){
- if (this.isValidKey(key) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Getting name/value pair",
- "Invalid key given: " + key));
-
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Getting name/value pair",
- "Invalid namespace given: " + namespace));
-
- // try to find this key in the database
- var results = this.$sql("SELECT * FROM " + this.table_name
- + " WHERE namespace = ? AND "
- + " key = ?",
- [namespace, key]);
-
- if (!results.length)
- return null;
-
- return jpf.unserialize(results[0].value);
- },
-
- getNamespaces: function(){
- var results = [ this.namespace ];
-
- var rs = this.$sql("SELECT namespace FROM " + this.table_name
- + " DESC GROUP BY namespace");
- for (var i = 0; i < rs.length; i++) {
- if (rs[i].namespace != this.namespace)
- results.push(rs[i].namespace);
- }
-
- return results;
- },
-
- getKeys: function(namespace){
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Retrieving keys",
- "Invalid namespace given: " + namespace));
-
- var rs = this.$sql("SELECT key FROM " + this.table_name
- + " WHERE namespace = ?",
- [namespace]);
-
- var results = [];
- for (var i = 0; i < rs.length; i++)
- results.push(rs[i].key);
-
- return results;
- },
-
- clear: function(namespace){
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Clearing storage",
- "Invalid namespace given: " + namespace));
-
- this.$sql("DELETE FROM " + this.table_name
- + " WHERE namespace = ?",
- [namespace]);
- },
-
- remove: function(key, namespace){
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Removing key",
- "Invalid namespace given: " + namespace));
-
- this.$sql("DELETE FROM " + this.table_name
- + " WHERE namespace = ? AND"
- + " key = ?",
- [namespace, key]);
- },
-
- putMultiple: function(keys, values, namespace) {
- if(this.isValidKeyArray(keys) === false
- || ! values instanceof Array
- || keys.length != values.length){
- throw new Error(jpf.formatErrorString(0, null,
- "Setting multiple name/value pairs",
- "Invalid arguments: keys = [" + keys + "], \
- values = [" + values + "]"));
- }
-
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Setting multiple name/value pairs",
- "Invalid namespace given: " + namespace));
-
- // try to store the value
- try {
- this.$sql.open();
- this.$sql.db.execute("BEGIN TRANSACTION");
- var stmt = "REPLACE INTO " + this.table_name + " VALUES (?, ?, ?)";
- for(var i=0;i<keys.length;i++) {
- // serialize the value;
- // handle strings differently so they have better performance
- var value = jpf.serialize(values[i]);
-
- this.$sql.db.execute(stmt, [namespace, keys[i], value]);
- }
- this.$sql.db.execute("COMMIT TRANSACTION");
- this.$sql.close();
- }
- catch(e) {
- throw new Error(jpf.formatErrorString(0, null,
- "Writing multiple name/value pair",
- "Error writing file: " + e.message));
- return false;
- }
-
- return true;
- },
-
- getMultiple: function(keys, namespace){
- if (this.isValidKeyArray(keys) === false)
- throw new Error(jpf.formatErrorString(0, null,
- "Getting name/value pair",
- "Invalid key array given: " + keys));
-
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Getting multiple name/value pairs",
- "Invalid namespace given: " + namespace));
-
- var stmt = "SELECT * FROM " + this.table_name +
- " WHERE namespace = ? AND " + " key = ?";
-
- var results = [];
- for (var i = 0; i < keys.length; i++) {
- var result = this.$sql(stmt, [namespace, keys[i]]);
- results[i] = result.length
- ? jpf.unserialize(result[0].value)
- : null;
- }
-
- return results;
- },
-
- removeMultiple: function(keys, namespace){
- if (this.isValidKeyArray(keys) === false)
- throw new Error(jpf.formatErrorString(0, null,
- "Removing name/value pair",
- "Invalid key array given: " + keys));
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Removing multiple name/value pairs",
- "Invalid namespace given: " + namespace));
-
- this.$sql.open();
- this.$sql.db.execute("BEGIN TRANSACTION");
- var stmt = "DELETE FROM " + this.table_name + " WHERE namespace = ? AND key = ?";
-
- for (var i = 0; i < keys.length; i++)
- this.$sql.db.execute(stmt, [namespace, keys[i]]);
-
- this.$sql.db.execute("COMMIT TRANSACTION");
- this.$sql.close();
- },
-
- isPermanent: function(){
- return true;
- },
-
- getMaximumSize: function(){
- return this.SIZE_NO_LIMIT;
- },
-
- hasSettingsUI: function(){
- return false;
- },
-
- showSettingsUI: function(){
- throw new Error(this.declaredClass
- + " does not support a storage settings user-interface");
- },
-
- hideSettingsUI: function(){
- throw new Error(this.declaredClass
- + " does not support a storage settings user-interface");
- }
-};
- - -/*FILEHEAD(/var/lib/jpf/src/core/lib/storage/air.js)SIZE(-1077090856)TIME(1224578766)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-// summary:
-// Storage provider that uses features in the Adobe AIR runtime to achieve
-// permanent storage
-
-jpf.namespace("storage.modules.air", {
- init: function(){
- this.ByteArray = window.runtime.flash.utils.ByteArray;
- this.EncryptedLocalStore = window.runtime.flash.data.EncryptedLocalStore;
- },
-
- isAvailable: function(){
- return jpf.isAIR;
- },
-
- _getItem: function(key){
- var storedValue = this.EncryptedLocalStore.getItem("__jpf_" + key);
- return storedValue ? storedValue.readUTFBytes(storedValue.length) : "";
- },
-
- _setItem: function(key, value){
- var bytes = new this.ByteArray();
- bytes.writeUTFBytes(value);
- this.EncryptedLocalStore.setItem("__jpf_" + key, bytes);
- },
-
- _removeItem: function(key){
- this.EncryptedLocalStore.removeItem("__jpf_" + key);
- },
-
- put: function(key, value, namespace){
- if (this.isValidKey(key) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Setting name/value pair", "Invalid key given: " + key));
-
- if(!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Setting name/value pair", "Invalid namespace given: " + namespace));
-
- // try to store the value
- try {
- var namespaces = this._getItem("namespaces") || '';
- if(namespaces.indexOf('|' + namespace + '|') == -1)
- this._setItem("namespaces", namespaces + namespace + '|');
-
- var keys = this._getItem(namespace + "_keys") || '';
- if(keys.indexOf('|' + key + '|') == -1)
- this._setItem(namespace + "_keys", keys + key + '|');
-
- this._setItem('_' + namespace + '_' + key, value);
- }
- catch(e) {
- throw new Error(jpf.formatErrorString(0, null,
- "Setting name/value pair", "Error writing: " + e.message));
-
- return false;
- }
-
- return true;
- },
-
- get: function(key, namespace){
- if (this.isValidKey(key) == false)
- throw new Error(jpf.formatErrorString(0, null, "Getting name/value pair", "Invalid key given: " + key));
-
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Getting name/value pair", "Invalid namespace given: " + namespace));
-
- return this._getItem('_' + namespace + '_' + key);
- },
-
- getNamespaces: function(){
- var results = [ this.namespace ];
- var namespaces = (this._getItem("namespaces") || '').split('|');
- for (var i=0;i<namespaces.length;i++){
- if (namespaces[i] && namespaces[i] != this.namespace)
- results.push(namespaces[i]);
- }
- return results;
- },
-
- getKeys: function(namespace){
- if (!namespace)
- namespace = this.namespace;
-
- if(this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null, "Getting keys",
- "Invalid namespace given: " + namespace));
-
- var results = [];
- var keys = (this._getItem(namespace + "_keys") || '').split('|');
- for (var i = 0; i < keys.length; i++) {
- if (keys[i])
- results.push(keys[i]);
- }
-
- return results;
- },
-
- clear: function(namespace){
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null, "Clearing storage",
- "Invalid namespace given: " + namespace));
-
- var namespaces = this._getItem("namespaces") || '';
- if (namespaces.indexOf('|' + namespace + '|') != -1)
- this._setItem("namespaces", namespaces.replace('|' + namespace + '|', '|'));
-
- var keys = (this._getItem(namespace + "_keys") || '').split('|');
- for (var i = 0; i < keys.length; i++)
- if (keys[i].length)
- this._removeItem(namespace + "_" + keys[i]);
-
- this._removeItem(namespace + "_keys");
- },
-
- remove: function(key, namespace){
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null, "Removing key",
- "Invalid namespace given: " + namespace));
-
- var keys = this._getItem(namespace + "_keys") || '';
- if (keys.indexOf('|' + key + '|') != -1)
- this._setItem(namespace + "_keys", keys.replace('|' + key + '|', '|'));
-
- this._removeItem('_' + namespace + '_' + key);
- },
-
- putMultiple: function(keys, values, namespace) {
- if (this.isValidKeyArray(keys) === false
- || ! values instanceof Array
- || keys.length != values.length){
- throw new Error(jpf.formatErrorString(0, null,
- "Setting multiple name/value pairs", "Invalid arguments: keys = ["
- + keys + "], values = [" + values + "]"));
- }
-
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Setting multiple name/value pairs", "Invalid namespace given: "
- + namespace));
-
- // try to store the value
- try {
- for (var i = 0; i < keys.length; i++)
- this.put(keys[i], value[i], null, namespace);
- }
- catch(e) {
- throw new Error(jpf.formatErrorString(0, null,
- "Writing multiple name/value pair", "Error writing file: "
- + e.message));
- return false;
- }
-
- return true;
- },
-
- getMultiple: function(keys, namespace){
- if (this.isValidKeyArray(keys) === false)
- throw new Error(jpf.formatErrorString(0, null,
- "Getting name/value pair", "Invalid key array given: " + keys));
-
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Getting multiple name/value pairs", "Invalid namespace given: "
- + namespace));
-
- var results = [];
- for (var i = 0; i < keys.length; i++)
- results[i] = this.get(keys[i], namespace);
-
- return results;
- },
-
- removeMultiple: function(keys, namespace){
- if (this.isValidKeyArray(keys) === false)
- throw new Error(jpf.formatErrorString(0, null,
- "Removing name/value pair", "Invalid key array given: " + keys));
-
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Removing multiple name/value pairs", "Invalid namespace given: "
- + namespace));
-
- for (var i = 0; i < keys.length; i++)
- this.remove(keys[i], namespace);
- },
-
- isPermanent: function(){
- return true;
- },
-
- getMaximumSize: function(){
- return this.SIZE_NO_LIMIT;
- },
-
- hasSettingsUI: function(){
- return false;
- },
-
- showSettingsUI: function(){
- throw new Error(this.declaredClass
- + " does not support a storage settings user-interface");
- },
-
- hideSettingsUI: function(){
- throw new Error(this.declaredClass
- + " does not support a storage settings user-interface");
- }
-});
-
- -/*FILEHEAD(/var/lib/jpf/src/core/lib/storage/html5.js)SIZE(-1077090856)TIME(1225842396)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * Storage provider that uses WHAT Working Group features in Firefox 2
- * to achieve permanent storage.
- * The WHAT WG storage API is documented at
- * http://www.whatwg.org/specs/web-apps/current-work/#scs-client-side
- */
-jpf.namespace("storage.modules.html5", {
- domain : (location.hostname == "localhost")
- ? "localhost.localdomain"
- : location.hostname,
- initialized: true,
-
- isAvailable: function(){
- try {
- // see: https://bugzilla.mozilla.org/show_bug.cgi?id=357323
- var myStorage = globalStorage[this.domain];
- }
- catch(e){
- return false;
- }
-
- return true;
- },
-
- put: function(key, value, namespace){
- if(this.isValidKey(key) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Setting name/value pair", "Invalid key given: " + key));
-
- // get our full key name, which is namespace + key
- key = this.getFullKey(key, namespace);
-
- // serialize the value;
- value = jpf.serialize(value);
-
- // try to store the value
- try {
- var myStorage = globalStorage[this.domain];
- myStorage.setItem(key, value);
- }
- catch(e) {
- // indicate we failed
- throw new Error(jpf.formatErrorString(0, null, "Setting name/value pair",
- "Could not set name/value pair"));
- }
- },
-
- get: function(key, namespace){
- if (this.isValidKey(key) == false)
- throw new Error(jpf.formatErrorString(0, null,
- "Setting name/value pair", "Invalid key given: " + key));
-
- // get our full key name, which is namespace + key
- key = this.getFullKey(key, namespace);
-
- // sometimes, even if a key doesn't exist, Firefox
- // will return a blank string instead of a null --
- // this _might_ be due to having underscores in the
- // keyname, but I am not sure.
-
- // @fixme: Simplify this bug into a testcase and
- // submit it to Firefox
- var myStorage = globalStorage[this.domain];
- var results = myStorage.getItem(key);
-
- if (results == null || results == "")
- return null;
-
- return jpf.unserialize(results);
- },
-
- getNamespaces: function(){
- var results = [ this.namespace ];
-
- // simply enumerate through our array and save any string
- // that starts with __
- var found = {};
- var myStorage = globalStorage[this.domain];
- var tester = /^__([^_]*)_/;
- for (var i = 0; i < myStorage.length; i++) {
- var currentKey = myStorage.key(i);
- if (tester.test(currentKey) == true){
- var currentNS = currentKey.match(tester)[1];
- // have we seen this namespace before?
- if (typeof found[currentNS] == "undefined") {
- found[currentNS] = true;
- results.push(currentNS);
- }
- }
- }
-
- return results;
- },
-
- getKeys: function(namespace){
- if(!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null, "Getting keys",
- "Invalid namespace given: " + namespace));
-
- // create a regular expression to test the beginning
- // of our key names to see if they match our namespace;
- // if it is the default namespace then test for the presence
- // of no namespace for compatibility with older versions
- // of dojox.storage
- var namespaceTester = new RegExp(namespace == this.namespace
- ? "^([^_]{2}.*)$"
- : "^__" + namespace + "_(.*)$");
-
- var myStorage = globalStorage[this.domain];
- var keysArray = [];
- for (var i = 0; i < myStorage.length; i++) {
- var currentKey = myStorage.key(i);
- if (namespaceTester.test(currentKey) == true) {
- // strip off the namespace portion
- currentKey = currentKey.match(namespaceTester)[1];
- keysArray.push(currentKey);
- }
- }
-
- return keysArray;
- },
-
- clear: function(namespace){
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null, "Clearing storage", "Invalid namespace given: " + namespace));
-
- // create a regular expression to test the beginning
- // of our key names to see if they match our namespace;
- // if it is the default namespace then test for the presence
- // of no namespace for compatibility with older versions
- // of dojox.storage
- var namespaceTester = new RegExp(namespace == this.namespace
- ? "^[^_]{2}"
- : "^__" + namespace + "_");
-
- var myStorage = globalStorage[this.domain];
- for (var i = myStorage.length-1; i >= 0; i--) {
- if (namespaceTester.test(myStorage.key(i)) == true)
- myStorage.removeItem(myStorage.key(i));
- }
- },
-
- remove: function(key, namespace){
- // get our full key name, which is namespace + key
- key = this.getFullKey(key, namespace);
-
- var myStorage = globalStorage[this.domain];
- myStorage.removeItem(key);
- },
-
- isPermanent: function(){
- return true;
- },
-
- getMaximumSize: function(){
- return 0;
- },
-
- hasSettingsUI: function(){
- return false;
- },
-
- showSettingsUI: function(){
- throw new Error(jpf.formatErrorString(0, null, this.declaredClass
- + " does not support a storage settings user-interface"));
- },
-
- hideSettingsUI: function(){
- throw new Error(jpf.formatErrorString(0, null, this.declaredClass
- + " does not support a storage settings user-interface"));
- },
-
- getFullKey: function(key, namespace){
- if (!namespace)
- namespace = this.namespace;
-
- if (this.isValidKey(namespace) == false)
- throw new Error(jpf.formatErrorString(0, null, "Clearing storage",
- "Invalid namespace given: " + namespace));
-
- // don't append a namespace string for the default namespace,
- // for compatibility with older versions of dojox.storage
- return namespace == this.namespace
- ? key
- : "__" + namespace + "_" + key;
- }
-});
- - -/*FILEHEAD(/var/lib/jpf/src/core/browsers/is_opera.js)SIZE(-1077090856)TIME(1238933673)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-/**
- * Compatibility layer for Opera browsers.
- * @private
- */
-jpf.runOpera = function (){
- /*var setTimeoutOpera = window.setTimeout;
- var lookupOperaCall = [];
- window.setTimeout = function(call, time){
- if (typeof call == "string")
- return setTimeoutOpera(call, time);
- return setTimeoutOpera("lookupOperaCall["
- + (lookupOperaCall.push(call) - 1) + "]()", time);
- }*/
-
- //HTMLHtmlElement = document.createElement("html").constructor;
- //HTMLElement = {};
- //HTMLElement.prototype = HTMLHtmlElement.__proto__.__proto__;
- //HTMLDocument = Document = document.constructor;
- var x = new DOMParser();
- XMLDocument = DOMParser.constructor;
- //Element = x.parseFromString("<Single />", "text/xml").documentElement.constructor;
- x = null;
-
- /* ***************************************************************************
- XML Serialization
- ****************************************************************************/
- //XMLDocument.xml
-
- //Node.xml
- /*Node.prototype.serialize = function(){
- return (new XMLSerializer()).serializeToString(this);
- }*/
- //Node.xml
-
- Node.prototype.serialize =
- XMLDocument.prototype.serialize =
- Element.prototype.serialize = function(){
- return (new XMLSerializer()).serializeToString(this);
- };
-
-
- //XMLDocument.selectNodes
- Document.prototype.selectNodes =
- XMLDocument.prototype.selectNodes =
- HTMLDocument.prototype.selectNodes = function(sExpr, contextNode){
- var oResult = this.evaluate(sExpr, (contextNode ? contextNode : this),
- this.createNSResolver(this.documentElement),
- XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
- var nodeList = new Array(oResult.snapshotLength);
- nodeList.expr = sExpr;
- for (var i = 0; i < nodeList.length; i++)
- nodeList[i] = oResult.snapshotItem(i);
- return nodeList;
- };
-
- //Element.selectNodes
- Element.prototype.selectNodes = function(sExpr){
- var doc = this.ownerDocument;
- if (!doc.selectSingleNode) {
- doc.selectSingleNode = HTMLDocument.prototype.selectSingleNode;
- doc.selectNodes = HTMLDocument.prototype.selectNodes;
- }
-
- if (doc.selectNodes)
- return doc.selectNodes(sExpr, this);
- else
- throw new Error(jpf.formatErrorString(1047, null, "XPath Selection", "Method selectNodes is only supported by XML Nodes"));
- };
-
- //XMLDocument.selectSingleNode
- Document.prototype.selectSingleNode =
- XMLDocument.prototype.selectSingleNode =
- HTMLDocument.prototype.selectSingleNode = function(sExpr, contextNode){
- var nodeList = this.selectNodes(sExpr + "[1]", contextNode ? contextNode : null);
- return nodeList.length > 0 ? nodeList[0] : null;
- };
-
- //Element.selectSingleNode
- Element.prototype.selectSingleNode = function(sExpr){
- var doc = this.ownerDocument;
- if (!doc.selectSingleNode) {
- doc.selectSingleNode = HTMLDocument.prototype.selectSingleNode;
- doc.selectNodes = HTMLDocument.prototype.selectNodes;
- }
-
- if (doc.selectSingleNode)
- return doc.selectSingleNode(sExpr, this);
- else
- throw new Error(jpf.formatErrorString(1048, null, "XPath Selection", "Method selectSingleNode is only supported by XML Nodes. \nInfo : " + e));
- };
-
-
- if (jpf.runNonIe)
- jpf.runNonIe();
- //jpf.importClass(jpf.runNonIe, true, self);
-}
-
- - -/*FILEHEAD(/var/lib/jpf/src/core/browsers/is_jaw.js)SIZE(-1077090856)TIME(1238933673)*/ - - - -/*FILEHEAD(/var/lib/jpf/src/core/browsers/is_gears.js)SIZE(-1077090856)TIME(1225628611)*/ - -/**
- * @private
- */
-jpf.initGears = function(){
- // summary:
- // factory method to get a Google Gears plugin instance to
- // expose in the browser runtime environment, if present
- var factory, results;
-
- var gearsObj = jpf.nameserver.get("google", "gears");
- if(gearsObj)
- return gearsObj; // already defined elsewhere
-
- if (typeof GearsFactory != "undefined") { // Firefox
- factory = new GearsFactory();
- }
- else {
- if(jpf.isIE){
- // IE
- try {
- factory = new ActiveXObject("Gears.Factory");
- }
- catch(e) {
- // ok to squelch; there's no gears factory. move on.
- }
- }
- else if(navigator.mimeTypes["application/x-googlegears"]) {
- // Safari?
- factory = document.createElement("object");
- factory.setAttribute("type", "application/x-googlegears");
- factory.setAttribute("width", 0);
- factory.setAttribute("height", 0);
- factory.style.display = "none";
- document.documentElement.appendChild(factory);
- }
- }
-
- // still nothing?
- if (!factory)
- return null;
-
- return jpf.nameserver.register("google", "gears", factory);
-};
- -/*FILEHEAD(/var/lib/jpf/src/core/browsers/is_ie.js)SIZE(-1077090856)TIME(1238933673)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - -/** - * Compatibility layer for Internet Explorer browsers. - * @private - */ -jpf.runIE = function(){ - - /* ******** XML Compatibility ************************************************ - Extensions to the xmldb - ****************************************************************************/ - var hasIE7Security = hasIESecurity = false; - if (self.XLMHttpRequest) - try { - new XLMHttpRequest() - } - catch (e) { - hasIE7Security = true - } - try { - new ActiveXObject("microsoft.XMLHTTP") - } - catch (e) { - hasIESecurity = true - } - - if(hasIESecurity) jpf.importClass(function(){ - __CONTENT_IFRAME - }, true, self); - - jpf.getHttpReq = hasIESecurity - ? function(){ - if (jpf.teleport.availHTTP.length) - return jpf.teleport.availHTTP.pop(); - - //if(jpf.isDeskrun && !self.useNativeHttp) - // return jdshell.CreateComponent("XMLHTTP"); - - return new XMLHttpRequest(); - } - : function(){ - if (jpf.teleport.availHTTP.length) - return jpf.teleport.availHTTP.pop(); - - //if(jpf.isDeskrun && !jpf.useNativeHttp) - // return jdshell.CreateComponent("XMLHTTP"); - - return new ActiveXObject("microsoft.XMLHTTP"); - }; - - jpf.getXmlDom = hasIESecurity - ? function(message, noError){ - var xmlParser = getDOMParser(message, noError); - return xmlParser; - } - : function(message, noError, preserveWhiteSpaces){ - var xmlParser = new ActiveXObject("microsoft.XMLDOM"); - xmlParser.setProperty("SelectionLanguage", "XPath"); - if (preserveWhiteSpaces) - xmlParser.preserveWhiteSpace = true; - - if (message) { - if (jpf.cantParseXmlDefinition) - message = message.replace(/\] \]/g, "] ]").replace(/^<\?[^>]*\?>/, "");//replace xml definition <?xml .* ?> for IE5.0 - - xmlParser.loadXML(message); - - if (!noError) - this.xmlParseError(xmlParser); - } - - return xmlParser; - }; - - jpf.xmlParseError = function(xml){ - var xmlParseError = xml.parseError; - if (xmlParseError != 0) { - /* - http://msdn.microsoft.com/library/en-us/xmlsdk30/htm/xmobjpmexmldomparseerror.asp?frame=true - - errorCode Contains the error code of the last parse error. Read-only. - filepos Contains the absolute file position where the error occurred. Read-only. - line Specifies the line number that contains the error. Read-only. - linepos Contains the character position within the line where the error occurred. Read-only. - reason Explains the reason for the error. Read-only. - srcText Returns the full text of the line containing the error. Read-only. - url Contains the URL of the XML document containing the last error. Read-only. - */ - throw new Error(jpf.formatErrorString(1050, null, "XML Parse error on line " + xmlParseError.line, xmlParseError.reason + "Source Text:\n" + xmlParseError.srcText.replace(/\t/gi, " "))); - } - - return xml; - }; - - /** - * This method retrieves the current value of a property on a HTML element - * @param {HTMLElement} el the element to read the property from - * @param {String} prop the property to read - * @returns {String} - */ - jpf.getStyle = function(el, prop) { - return el.currentStyle[prop]; - }; - - //function extendXmlDb(){ - if (jpf.XmlDatabase) { - jpf.XmlDatabase.prototype.htmlImport = function(xmlNode, htmlNode, beforeNode, pre, post){ - var id; - if (xmlNode.length != null && !xmlNode.nodeType) { - var str, i, l; - for (str = [], i = 0, l = xmlNode.length; i < l; i++) - str.push(xmlNode[i].xml); - str = str.join(""); - - str = jpf.html_entity_decode(str) - .replace(/style="background-image:([^"]*)"/g, "find='$1' style='background-image:$1'"); - - if (pre) { - (beforeNode || htmlNode).insertAdjacentHTML(beforeNode - ? "beforebegin" - : "beforeend", pre + str + post); - } - - try { - (beforeNode || htmlNode).insertAdjacentHTML(beforeNode - ? "beforebegin" - : "beforeend", str); - } - catch (e) { - //IE table hack - document.body.insertAdjacentHTML("beforeend", "<table><tr>" - + str + "</tr></table>"); - var x = document.body.lastChild.firstChild.firstChild; - for (i = x.childNodes.length - 1; i >= 0; i--) - htmlNode.appendChild(x.childNodes[jpf.hasDynamicItemList ? 0 : i]); - } - - //Fix IE image loading bug - if (!this.nodes) - this.nodes = []; - - id = this.nodes.push(htmlNode.getElementsByTagName("*")) - 1; - setTimeout('jpf.xmldb.doNodes(' + id + ')'); - - return null; - } - - //== ??? OR != - if (htmlNode.ownerDocument && htmlNode.ownerDocument != document - && xmlNode.ownerDocument == htmlNode.ownerDocument) - return htmlNode.insertBefore(xmlNode, beforeNode); - //if(htmlNode.ownerDocument && htmlNode.ownerDocument != document) return htmlNode.insertBefore(xmlNode, beforeNode); - - var strHTML = jpf.html_entity_decode(xmlNode.outerHTML || xmlNode.xml || xmlNode.nodeValue); - var pNode = (beforeNode || htmlNode); - if (pNode.nodeType == 11) { - id = xmlNode.getAttribute("id"); - if (!id) - throw new Error(jpf.formatErrorString(1049, null, "xmldb", "Inserting Cache Item in Document Fragment without an ID")); - - document.body.insertAdjacentHTML(beforeNode ? "beforebegin" : "beforeend", strHTML); - pNode.appendChild(document.getElementById(id)); - } - else - pNode.insertAdjacentHTML(beforeNode ? "beforebegin" : "beforeend", strHTML); - - return beforeNode ? beforeNode.previousSibling : htmlNode.lastChild; - }; - - jpf.XmlDatabase.prototype.doNodes = function(id){ - var nodes = this.nodes[id]; - for (var i = 0; i < nodes.length; i++) { - if (nodes[i].getAttribute("find")) - nodes[i].style.backgroundImage = nodes[i].getAttribute("find"); - } - this.nodes[id] = null; - }; - - //Initialize xmldb - jpf.xmldb = new jpf.XmlDatabase(); - - } - - //jpf.Init.addConditional(extendXmlDb, self, 'XmlDatabase'); - if (!hasIESecurity) - jpf.Init.run('xmldb'); - - jpf.getHorBorders = function(oHtml){ - return Math.max(0, - (parseInt(jpf.getStyle(oHtml, "borderLeftWidth")) || 0) - + (parseInt(jpf.getStyle(oHtml, "borderRightWidth")) || 0)) - }; - - jpf.getVerBorders = function(oHtml){ - return Math.max(0, - (parseInt(jpf.getStyle(oHtml, "borderTopWidth")) || 0) - + (parseInt(jpf.getStyle(oHtml, "borderBottomWidth")) || 0)) - }; - - jpf.getWidthDiff = function(oHtml){ - return Math.max(0, (parseInt(jpf.getStyle(oHtml, "paddingLeft")) || 0) - + (parseInt(jpf.getStyle(oHtml, "paddingRight")) || 0) - + (parseInt(jpf.getStyle(oHtml, "borderLeftWidth")) || 0) - + (parseInt(jpf.getStyle(oHtml, "borderRightWidth")) || 0)) - }; - - jpf.getHeightDiff = function(oHtml){ - return Math.max(0, (parseInt(jpf.getStyle(oHtml, "paddingTop")) || 0) - + (parseInt(jpf.getStyle(oHtml, "paddingBottom")) || 0) - + (parseInt(jpf.getStyle(oHtml, "borderTopWidth")) || 0) - + (parseInt(jpf.getStyle(oHtml, "borderBottomWidth")) || 0)) - }; - - jpf.getDiff = function(oHtml){ - return [Math.max(0, (parseInt(jpf.getStyle(oHtml, "paddingLeft")) || 0) - + (parseInt(jpf.getStyle(oHtml, "paddingRight")) || 0) - + (parseInt(jpf.getStyle(oHtml, "borderLeftWidth")) || 0) - + (parseInt(jpf.getStyle(oHtml, "borderRightWidth")) || 0)), - Math.max(0, (parseInt(jpf.getStyle(oHtml, "paddingTop")) || 0) - + (parseInt(jpf.getStyle(oHtml, "paddingBottom")) || 0) - + (parseInt(jpf.getStyle(oHtml, "borderTopWidth")) || 0) - + (parseInt(jpf.getStyle(oHtml, "borderBottomWidth")) || 0))] - }; - - jpf.popup2 = { - cache: {}, - setContent: function(cacheId, content, style, width, height){ - if (!this.popup) - this.init(); - - this.cache[cacheId] = { - content: content, - style : style, - width : width, - height : height - }; - if (content.parentNode) - content.parentNode.removeChild(content); - if (style) - jpf.importCssString(this.popup.document, style); - - return this.popup.document; - }, - - removeContent: function(cacheId){ - this.cache[cacheId] = null; - delete this.cache[cacheId]; - }, - - init: function(){ - this.popup = window.createPopup(); - - this.popup.document.write('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\ - <html xmlns="http://www.w3.org/1999/xhtml" xmlns:j=' + jpf.ns.jml + ' xmlns:xsl="http://www.w3.org/1999/XSL/Transform">\ - <head>\ - <script>\ - var jpf = {\ - all: [],\ - lookup:function(uniqueId){\ - return this.all[uniqueId] || {\ - $setStyleClass:function(){}\ - };\ - }\ - };\ - function destroy(){\ - jpf.all=null;\ - }\ - </script>\ - <style>\ - HTML{border:0;overflow:hidden;margin:0}\ - BODY{margin:0}\ - </style>\ - </head>\ - <body onmouseover="if(!self.jpf) return;if(this.c){jpf.all = this.c.all;this.c.Popup.parentDoc=self;}"></body>\ - </html>'); - - var c = jpf; - this.popup.document.body.onmousemove = function(){ - this.c = c - } - }, - - show: function(cacheId, x, y, animate, ref, width, height, callback){ - if (!this.popup) - this.init(); - var o = this.cache[cacheId]; - //if(this.last != cacheId) - this.popup.document.body.innerHTML = o.content.outerHTML; - - if (animate) { - var iVal, steps = 7, i = 0, popup = this.popup; - iVal = setInterval(function(){ - var value = ++i * ((height || o.height) / steps); - popup.show(x, y, width || o.width, value, ref); - popup.document.body.firstChild.style.marginTop - = (i - steps - 1) * ((height || o.height) / steps); - if (i > steps) { - clearInterval(iVal) - callback(popup.document.body.firstChild); - } - }, 10); - } - else { - this.popup.show(x, y, width || o.width, height || o.height, ref); - } - - this.last = cacheId; - }, - - hide: function(){ - if (this.popup) - this.popup.hide(); - }, - - forceHide: function(){ - if (this.last) - jpf.lookup(this.last).dispatchEvent("popuphide"); - }, - - destroy: function(){ - if (!this.popup) - return; - this.popup.document.body.c = null; - this.popup.document.body.onmouseover = null; - } - }; - - jpf.importClass(jpf.runXpath, true, self); -} - - - -/*FILEHEAD(/var/lib/jpf/src/core/browsers/is_gecko.js)SIZE(-1077090856)TIME(1238933673)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-/**
- * Compatibility layer for Gecko based browsers.
- * @private
- */
-jpf.runGecko = function(){
- if (jpf.runNonIe)
- jpf.runNonIe();
-
- /* ***************************************************************************
- XSLT
- ****************************************************************************/
-
- //XMLDocument.selectNodes
- HTMLDocument.prototype.selectNodes = XMLDocument.prototype.selectNodes = function(sExpr, contextNode){
- var oResult = this.evaluate(sExpr, (contextNode || this),
- this.createNSResolver(this.documentElement),
- 7, null);//XPathResult.ORDERED_NODE_SNAPSHOT_TYPE
-
- var nodeList = new Array(oResult.snapshotLength);
- nodeList.expr = sExpr;
- for (var i = nodeList.length - 1; i >= 0; i--)
- nodeList[i] = oResult.snapshotItem(i);
- return nodeList;
- };
-
- //Element.selectNodes
- Element.prototype.selectNodes = function(sExpr){
- return this.ownerDocument.selectNodes(sExpr, this);
- };
-
- //XMLDocument.selectSingleNode
- HTMLDocument.prototype.selectSingleNode = XMLDocument.prototype.selectSingleNode = function(sExpr, contextNode){
- var nodeList = this.selectNodes(sExpr + "[1]", contextNode || null);
- return nodeList[0] || null;
- };
-
- //Element.selectSingleNode
- Element.prototype.selectSingleNode = function(sExpr){
- return this.ownerDocument.selectSingleNode(sExpr, this);
- };
-
-
- /* ******** Error Compatibility **********************************************
- Error Object like IE
- ****************************************************************************/
- function Error(nr, msg){
- if (!jpf.debugwin.useDebugger)
- jpf.debugwin.errorHandler(msg, "", 0);
-
- this.message = msg;
- this.nr = nr;
- }
-}
-
- - -/*FILEHEAD(/var/lib/jpf/src/core/browsers/non_ie.js)SIZE(-1077090856)TIME(1238933673)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-jpf.runNonIe = function (){
-
- DocumentFragment.prototype.getElementById = function(id){
- return this.childNodes.length ? this.childNodes[0].ownerDocument.getElementById(id) : null;
- };
-
- /**** XML Serialization ****/
- if (XMLDocument.prototype.__defineGetter__) {
- //XMLDocument.xml
- XMLDocument.prototype.__defineGetter__("xml", function(){
- return (new XMLSerializer()).serializeToString(this);
- });
- XMLDocument.prototype.__defineSetter__("xml", function(){
- throw new Error(jpf.formatErrorString(1042, null, "XML serializer", "Invalid assignment on read-only property 'xml'."));
- });
-
- //Node.xml
- Node.prototype.__defineGetter__("xml", function(){
- if (this.nodeType == 3 || this.nodeType == 4 || this.nodeType == 2)
- return this.nodeValue;
- return (new XMLSerializer()).serializeToString(this);
- });
-
- //Node.xml
- Element.prototype.__defineGetter__("xml", function(){
- return (new XMLSerializer()).serializeToString(this);
- });
- }
-
- /* ******** HTML Interfaces **************************************************
- insertAdjacentHTML(), insertAdjacentText() and insertAdjacentElement()
- ****************************************************************************/
- if (typeof HTMLElement!="undefined") {
- if (!HTMLElement.prototype.insertAdjacentElement) {
- HTMLElement.prototype.insertAdjacentElement = function(where,parsedNode){
- switch (where.toLowerCase()) {
- case "beforebegin":
- this.parentNode.insertBefore(parsedNode,this);
- break;
- case "afterbegin":
- this.insertBefore(parsedNode,this.firstChild);
- break;
- case "beforeend":
- this.appendChild(parsedNode);
- break;
- case "afterend":
- if (this.nextSibling)
- this.parentNode.insertBefore(parsedNode,this.nextSibling);
- else
- this.parentNode.appendChild(parsedNode);
- break;
- }
- };
- }
-
- if (!HTMLElement.prototype.insertAdjacentHTML) {
- HTMLElement.prototype.insertAdjacentHTML = function(where,htmlStr){
- var r = this.ownerDocument.createRange();
- r.setStartBefore(jpf.isSafari ? document.body : (self.document ? document.body : this));
- var parsedHTML = r.createContextualFragment(htmlStr);
- this.insertAdjacentElement(where, parsedHTML);
- };
- }
-
- if (jpf.isSafari || jpf.isChrome)
- HTMLBodyElement.prototype.insertAdjacentHTML = HTMLElement.prototype.insertAdjacentHTML;
-
- if (!HTMLElement.prototype.insertAdjacentText) {
- HTMLElement.prototype.insertAdjacentText = function(where,txtStr){
- var parsedText = document.createTextNode(txtStr);
- this.insertAdjacentElement(where,parsedText);
- };
- }
-
- //HTMLElement.removeNode
- HTMLElement.prototype.removeNode = function(){
- if (!this.parentNode) return;
-
- this.parentNode.removeChild(this);
- };
-
- //Currently only supported by Gecko
- if (HTMLElement.prototype.__defineSetter__) {
- //HTMLElement.innerText
- HTMLElement.prototype.__defineSetter__("innerText", function(sText){
- var s = "" + sText;
- this.innerHTML = s.replace(/\&/g, "&")
- .replace(/</g, "<").replace(/>/g, ">");
- });
-
- HTMLElement.prototype.__defineGetter__("innerText", function(){
- return this.innerHTML.replace(/<[^>]+>/g,"")
- .replace(/\s\s+/g, " ").replace(/^\s*|\s*$/g, " ")
- });
-
- HTMLElement.prototype.__defineGetter__("outerHTML", function(){
- return (new XMLSerializer()).serializeToString(this);
- });
- }
- }
-
- /* ******** XML Compatibility ************************************************
- Giving the Mozilla XML Parser the same interface as IE's Parser
- ****************************************************************************/
- var ASYNCNOTSUPPORTED = false;
-
- //Test if Async is supported
- try {
- XMLDocument.prototype.async = true;
- ASYNCNOTSUPPORTED = true;
- } catch(e) {/*trap*/}
-
- Document.prototype.onreadystatechange = null;
- Document.prototype.parseError = 0;
-
- Array.prototype.item = function(i){return this[i];};
- Array.prototype.expr = "";
-
- XMLDocument.prototype.readyState = 0;
-
- XMLDocument.prototype.$clearDOM = function(){
- while (this.hasChildNodes())
- this.removeChild(this.firstChild);
- };
-
- XMLDocument.prototype.$copyDOM = function(oDoc){
- this.$clearDOM();
-
- if (oDoc.nodeType == 9 || oDoc.nodeType == 11) {
- var oNodes = oDoc.childNodes;
-
- for (var i = 0; i < oNodes.length; i++)
- this.appendChild(this.importNode(oNodes[i], true));
- } else if(oDoc.nodeType == 1)
- this.appendChild(this.importNode(oDoc, true));
- };
-
- //XMLDocument.loadXML();
- XMLDocument.prototype.loadXML = function(strXML){
- jpf.xmldb.setReadyState(this, 1);
- var sOldXML = this.xml || this.serialize();
- var oDoc = (new DOMParser()).parseFromString(strXML, "text/xml");
- jpf.xmldb.setReadyState(this, 2);
- this.$copyDOM(oDoc);
- jpf.xmldb.setReadyState(this, 3);
- jpf.xmldb.loadHandler(this);
- return sOldXML;
- };
-
- Node.prototype.getElementById = function(id){};
-
- HTMLElement.prototype.replaceNode =
- Element.prototype.replaceNode = function(xmlNode){
- if (!this.parentNode) return;
-
- this.parentNode.insertBefore(xmlNode, this);
- this.parentNode.removeChild(this);
- };
-
- //XMLDocument.load
- XMLDocument.prototype.$load = XMLDocument.prototype.load;
- XMLDocument.prototype.load = function(sURI){
- var oDoc = document.implementation.createDocument("", "", null);
- oDoc.$copyDOM(this);
- this.parseError = 0;
- jpf.xmldb.setReadyState(this, 1);
-
- try {
- if (this.async == false && ASYNCNOTSUPPORTED) {
- var tmp = new XMLHttpRequest();
- tmp.open("GET", sURI, false);
- tmp.overrideMimeType("text/xml");
- tmp.send(null);
- jpf.xmldb.setReadyState(this, 2);
- this.$copyDOM(tmp.responseXML);
- jpf.xmldb.setReadyState(this, 3);
- } else
- this.$load(sURI);
- }
- catch (objException) {
- this.parseError = -1;
- }
- finally {
- jpf.xmldb.loadHandler(this);
- }
-
- return oDoc;
- };
-
-
-
- //Element.transformNodeToObject
- Element.prototype.transformNodeToObject = function(xslDoc, oResult){
- var oDoc = document.implementation.createDocument("", "", null);
- oDoc.$copyDOM(this);
- oDoc.transformNodeToObject(xslDoc, oResult);
- };
-
- //Document.transformNodeToObject
- Document.prototype.transformNodeToObject = function(xslDoc, oResult){
- var xsltProcessor = null;
- try {
- xsltProcessor = new XSLTProcessor();
-
- if (xsltProcessor.reset) {
- // new nsIXSLTProcessor is available
- xslDoc = jpf.getXmlDom(xslDoc.xml || xslDoc.serialize());
- xsltProcessor.importStylesheet(xslDoc);
- var newFragment = xsltProcessor.transformToFragment(this, oResult);
- oResult.$copyDOM(newFragment);
- }
- else {
- // only nsIXSLTProcessorObsolete is available
- xsltProcessor.transformDocument(this, xslDoc, oResult, null);
- }
- }
- catch(e) {
- if (xslDoc && oResult)
- throw new Error(jpf.formatErrorString(1043, null, "XSLT Transformation", "Failed to transform document. \nInfo : " + e));
- else if (!xslDoc)
- throw new Error(jpf.formatErrorString(1044, null, "XSLT Transformation", "No Stylesheet Document was provided. \nInfo : " + e));
- else if (!oResult)
- throw new Error(jpf.formatErrorString(1045, null, "XSLT Transformation", "No Result Document was provided. \nInfo : " + e));
- else if (xsltProcessor == null)
- throw new Error(jpf.formatErrorString(1046, null, "XSLT Transformation", "Could not instantiate an XSLTProcessor object. \nInfo : " + e));
- else
- throw e;
- }
- };
-
- //Element.transformNode
- Element.prototype.transformNode = function(xslDoc){
- return jpf.getXmlDom(this.xml || this.serialize())
- .transformNode(xslDoc);
- };
-
- //Document.transformNode
- Document.prototype.transformNode = function(xslDoc){
- var xsltProcessor = new XSLTProcessor();
- xslDoc = jpf.getXmlDom(xslDoc.xml || xslDoc.serialize());
- xsltProcessor.importStylesheet(xslDoc);
- var newFragment = xsltProcessor.transformToFragment(this,
- document.implementation.createDocument("", "", null));
-
- return newFragment.xml || newFragment.serialize()
-
- /*try{
- var serializer = new XMLSerializer();
- str = serializer.serializeToString(out);
- }
- catch(e){
- throw new Error("---- Javeline Error ----\nProcess : XSLT Transformation\nMessage : Failed to serialize result document. \nInfo : " + e);
- }
-
- return str;*/
- };
-
-
- /**
- * This method retrieves the current value of a property on a HTML element
- * @param {HTMLElement} el the element to read the property from
- * @param {String} prop the property to read
- * @returns {String}
- */
- jpf.getStyle = function(el, prop) {
- return window.getComputedStyle(el, '').getPropertyValue(prop);
- };
-
- //XMLDocument.setProperty
- HTMLDocument.prototype.setProperty =
- XMLDocument.prototype.setProperty = function(x,y){};
-
- /* ******** XML Compatibility ************************************************
- Extensions to the xmldb
- ****************************************************************************/
- jpf.getHttpReq = function(){
- if (jpf.teleport.availHTTP.length)
- return jpf.teleport.availHTTP.pop();
- return new XMLHttpRequest();
- };
-
- jpf.getXmlDom = function(message, noError){
- var xmlParser;
- if (message) {
- xmlParser = new DOMParser();
- xmlParser = xmlParser.parseFromString(message, "text/xml");
-
- if (!noError)
- this.xmlParseError(xmlParser);
- }
- else {
- xmlParser = document.implementation.createDocument("", "", null);
- }
-
- return xmlParser;
- };
-
- jpf.xmlParseError = function(xml){
- if (xml.documentElement.tagName == "parsererror") {
- var str = xml.documentElement.firstChild.nodeValue.split("\n");
- var linenr = str[2].match(/\w+ (\d+)/)[1];
- var message = str[0].replace(/\w+ \w+ \w+: (.*)/, "$1");
-
- var srcText = xml.documentElement.lastChild.firstChild.nodeValue.split("\n")[0];
-
- throw new Error(jpf.formatErrorString(1050, null,
- "XML Parse Error on line " + linenr, message +
- "\nSource Text : " + srcText.replace(/\t/gi, " ")));
- }
-
- return xml;
- };
-
- if (jpf.XmlDatabase) {
- jpf.XmlDatabase.prototype.htmlImport = function(xmlNode, htmlNode, beforeNode, test){
- if (!htmlNode)
- alert("No HTML node given in htmlImport:" + this.htmlImport.caller);
-
- if (xmlNode.length != null && !xmlNode.nodeType) {
- for (var str = [], i = 0, l = xmlNode.length; i < l; i++)
- str.push(xmlNode[i].xml || xmlNode[i].serialize());
-
- str = str.join("").replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&")
- .replace(/<([^>]+)\/>/g, "<$1></$1>");
-
- (beforeNode || htmlNode).insertAdjacentHTML(beforeNode
- ? "beforebegin"
- : "beforeend", str);
-
- return null;
- }
-
- if (htmlNode.ownerDocument && htmlNode.ownerDocument != document
- && xmlNode.ownerDocument == htmlNode.ownerDocument)
- return htmlNode.insertBefore(xmlNode, beforeNode);
-
- //var strHTML = (xmlNode.outerHTML
- //|| (xmlNode.nodeType == 1 ? xmlNode.xml || xmlNode.serialize() : xmlNode.nodeValue)).replace(/&/g, "&")
- //.replace(/</g, "<").replace(/>/g, ">");
-
- var strHTML = jpf.html_entity_decode(xmlNode.outerHTML || xmlNode.xml || xmlNode.nodeValue);
- var pNode = (beforeNode || htmlNode);
- if (pNode.nodeType == 11){
- var id = xmlNode.getAttribute("id");
- if (!id)
- throw new Error(jpf.formatErrorString(1049, null, "xmldb", "Inserting Cache Item in Document Fragment without an ID"));
-
- document.body.insertAdjacentHTML(beforeNode ? "beforebegin" : "beforeend", strHTML);
- pNode.appendChild(document.getElementById(id));
- }
- else {
- //firefox bug??
- if (xmlNode.tagName.match(/tbody|td|tr/))
- pNode.insertBefore(pNode.ownerDocument
- .createElement(xmlNode.tagName.toLowerCase()), beforeNode || null);
- else {
- pNode.insertAdjacentHTML(beforeNode ? "beforebegin" : "beforeend", strHTML);
- }
- }
-
- //var retNode = beforeNode ? beforeNode.previousSibling : htmlNode.lastChild;
- //if(!retNode.tagName || retNode.tagName.toLowerCase() != xmlNode.tagName.toLowerCase()) debugger;
-
- return beforeNode ? beforeNode.previousSibling : htmlNode.lastChild;
- };
-
- jpf.XmlDatabase.prototype.setReadyState = function(oDoc, iReadyState) {
- oDoc.readyState = iReadyState;
- if (oDoc.onreadystatechange != null && typeof oDoc.onreadystatechange == "function")
- oDoc.onreadystatechange();
- };
-
- jpf.XmlDatabase.prototype.loadHandler = function(oDoc){
- if (!oDoc.documentElement || oDoc.documentElement.tagName == "parsererror")
- oDoc.parseError = -1;
-
- jpf.xmldb.setReadyState(oDoc, 4);
- };
-
- //Initialize xmldb
- jpf.xmldb = new jpf.XmlDatabase();
- }
-
- //Fix XML Data-Island Support Problem with Form Tag
- jpf.Init.add(function(){
- var i, nodes = document.getElementsByTagName("form");
- for (i = 0; i < nodes.length; i++)
- nodes[i].removeNode();
- nodes = document.getElementsByTagName("xml");
- for(i = 0; i < nodes.length; i++)
- nodes[i].removeNode();
- nodes = null;
- });
-
- //IE Like Error Handling
- var MAXMSG = 3;
- var ERROR_COUNT = 0;
-
- /*window.onerror = function(message, filename, linenr){
- if(++ERROR_COUNT > MAXMSG) return;
- filename = filename ? filename.match(/\/([^\/]*)$/)[1] : "[Mozilla Library]";
- new Error("---- Javeline Error ----\nProcess : Javascript code in '" + filename + "'\nLine : " + linenr + "\nMessage : " + message);
- return false;
- }*/
-
- if (document.body)
- document.body.focus = function(){};
-
-
- if (!document.elementFromPoint) {
- Document.prototype.elementFromPointRemove = function(el){
- if (!this.RegElements) return;
-
- this.RegElements.remove(el);
- };
-
- Document.prototype.elementFromPointAdd = function(el){
- if (!this.RegElements)
- this.RegElements = [];
- this.RegElements.push(el);
- };
-
- Document.prototype.elementFromPointReset = function(RegElements){
- //define globals
- FoundValue = [];
- FoundNode = null;
- LastFoundAbs = document.documentElement;
- };
-
- Document.prototype.elementFromPoint = function(x, y){
- // Optimization, Keeping last found node makes it ignore all lower levels
- // when there is no possibility of changing positions and zIndexes
- /*if(self.FoundNode){
- var sx = getElementPosX(FoundNode);
- var sy = getElementPosY(FoundNode);
- var ex = sx + FoundNode.offsetWidth; var ey = sy + FoundNode.offsetHeight;
- }
- if(!self.FoundNode || !(x > sx && x < ex && y > sy && y < ey))*/
- document.elementFromPointReset();
-
- // Optimization only looking at registered nodes
- if (this.RegElements) {
- for (var calc_z = -1, calc, i = 0; i < this.RegElements.length; i++) {
- var n = this.RegElements[i];
- if (getStyle(n, "display") == "none") continue;
-
- var sx = getElementPosX(n);
- var sy = getElementPosY(n);
- var ex = sx + n.offsetWidth;
- var ey = sy + n.offsetHeight;
-
- if (x > sx && x < ex && y > sy && y < ey) {
- var z = getElementZindex(n);
- if (z > calc_z) { //equal z-indexes not supported
- calc = [n, x, y, sx, sy];
- calc_z = z;
- }
- }
- }
-
- if (calc) {
- efpi(calc[0], calc[1], calc[2], 0, FoundValue, calc[3], calc[4]);
- if (!FoundNode) {
- FoundNode = calc[0];
- LastFoundAbs = calc[0];
- FoundValue = [calc_z];
- }
- }
- }
-
- if (!this.RegElements || !this.RegElements.length)
- efpi(document.body, x, y, 0, [], getElementPosX(document.body),
- getElementPosY(document.body));
-
- return FoundNode;
- };
-
- function getStyle(el, prop) {
- return document.defaultView.getComputedStyle(el,'').getPropertyValue(prop);
- }
-
- function efpi(from, x, y, CurIndex, CurValue, px, py){
- var StartValue = CurValue;
- var StartIndex = CurIndex;
-
- //Loop through childNodes
- var nodes = from.childNodes;
- for(var n, i = 0; i < from.childNodes.length; i++) {
- n = from.childNodes[i];
- if (n.nodeType == 1 && getStyle(n, 'display') != 'none' && n.offsetParent) {
- var sx = px + n.offsetLeft - n.offsetParent.scrollLeft;//getElementPosX(n);
- var sy = py + n.offsetTop - n.offsetParent.scrollTop;//getElementPosY(n);
- var ex = sx + n.offsetWidth;
- var ey = sy + n.offsetHeight;
-
- //if(Child is position absolute/relative and overflow == "hidden" && !inSpace) continue;
- var isAbs = getStyle(n, "position");
- isAbs = (isAbs == "absolute") || (isAbs == "relative");
- var isHidden = getStyle(n, "overflow") == "hidden";
- var inSpace = (x > sx && x < ex && y > sy && y < ey);
-
- if (isAbs && isHidden && !inSpace) continue;
-
- CurIndex = StartIndex;
- CurValue = StartValue.copy();
-
- //if (Child is position absolute/relative and has zIndex) or overflow == "hidden"
- var z = parseInt(getStyle(n, "z-index")) || 0;
- if (isAbs && (z || z == 0) || isHidden) {
- //if(!is position absolute/relative) zIndex = 0
- if (!isAbs) z = 0;
-
- //if zIndex >= FoundValue[CurIndex]
- if (z >= (FoundValue[CurIndex] || 0)) {
- //if zIndex > CurValue[CurIndex];
- if (z > (CurValue[CurIndex] || 0)) {
- //CurValue = StartValue.copy();
-
- //set CurValue[CurIndex] = zIndex
- CurValue[CurIndex] = z;
- }
-
- CurIndex++;
-
- //if(inSpace && CurIndex >= FoundValue.length)
- if (inSpace && CurIndex >= FoundValue.length) {
- //Set FoundNode is currentNode
- FoundNode = n;
- //Set FoundValue is CurValue
- FoundValue = CurValue;//.copy();
-
- LastFoundAbs = n;
- }
- }
- else
- continue; //Ignore this treedepth
- }
- else if(inSpace && CurIndex >= FoundValue.length){
- //else if CurValue[CurIndex] continue; //Ignore this treedepth
- //else if(CurValue[CurIndex]) continue;
-
- //Set FoundNode is currentNode
- FoundNode = n;
- //Set FoundValue is CurValue
- FoundValue = CurValue;//.copy();
- }
-
- //loop through childnodes recursively
- efpi(n, x, y, CurIndex, CurValue, isAbs ? sx : px, isAbs ? sy : py)
- }
- }
- }
-
- function getElementPosY(myObj){
- return myObj.offsetTop + parseInt(jpf.getStyle(myObj, "border-top-width"))
- + (myObj.offsetParent ? getElementPosY(myObj.offsetParent) : 0);
- }
-
- function getElementPosX(myObj){
- return myObj.offsetLeft + parseInt(jpf.getStyle(myObj, "border-left-width"))
- + (myObj.offsetParent ? getElementPosX(myObj.offsetParent) : 0);
- }
-
- function getElementZindex(myObj){
- //This is not quite sufficient and should be changed
- var z = 0, n, p = myObj;
- while(p && p.nodeType == 1){
- z = Math.max(z, parseInt(getStyle(p, "z-index")) || -1);
- p = p.parentNode;
- }
- return z;
- }
- }
-
-
- jpf.getHorBorders = function(oHtml){
- return Math.max(0,
- (parseInt(jpf.getStyle(oHtml, "border-left-width")) || 0)
- + (parseInt(jpf.getStyle(oHtml, "border-right-width")) || 0));
- };
-
- jpf.getVerBorders = function(oHtml){
- return Math.max(0,
- (parseInt(jpf.getStyle(oHtml, "border-top-width")) || 0)
- + (parseInt(jpf.getStyle(oHtml, "border-bottom-width")) || 0));
- };
-
- jpf.getWidthDiff = function(oHtml){
- return Math.max(0, (parseInt(jpf.getStyle(oHtml, "padding-left")) || 0)
- + (parseInt(jpf.getStyle(oHtml, "padding-right")) || 0)
- + (parseInt(jpf.getStyle(oHtml, "border-left-width")) || 0)
- + (parseInt(jpf.getStyle(oHtml, "border-right-width")) || 0));
- };
-
- jpf.getHeightDiff = function(oHtml){
- return Math.max(0, (parseInt(jpf.getStyle(oHtml, "padding-top")) || 0)
- + (parseInt(jpf.getStyle(oHtml, "padding-bottom")) || 0)
- + (parseInt(jpf.getStyle(oHtml, "border-top-width")) || 0)
- + (parseInt(jpf.getStyle(oHtml, "border-bottom-width")) || 0));
- };
-
- jpf.getDiff = function(oHtml){
- return [Math.max(0, parseInt(jpf.getStyle(oHtml, "padding-left"))
- + parseInt(jpf.getStyle(oHtml, "padding-right"))
- + parseInt(jpf.getStyle(oHtml, "border-left-width"))
- + parseInt(jpf.getStyle(oHtml, "border-right-width")) || 0),
- Math.max(0, parseInt(jpf.getStyle(oHtml, "padding-top"))
- + parseInt(jpf.getStyle(oHtml, "padding-bottom"))
- + parseInt(jpf.getStyle(oHtml, "border-top-width"))
- + parseInt(jpf.getStyle(oHtml, "border-bottom-width")) || 0)];
- };
-
- jpf.Init.run('xmldb');
-}
- - -/*FILEHEAD(/var/lib/jpf/src/core/browsers/is_safari.js)SIZE(-1077090856)TIME(1238933673)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-/**
- * Compatibility layer for Webkit based browsers.
- * @private
- */
-jpf.runSafari = function(){
- if (!jpf.isChrome) {
- var setTimeoutSafari = window.setTimeout;
- lookupSafariCall = [];
- window.setTimeout = function(call, time){
- if (typeof call == "string")
- return setTimeoutSafari(call, time);
- return setTimeoutSafari("lookupSafariCall["
- + (lookupSafariCall.push(call) - 1) + "]()", time);
- }
-
- if (jpf.isSafariOld) {
- HTMLHtmlElement = document.createElement("html").constructor;
- Node = HTMLElement = {};
- HTMLElement.prototype = HTMLHtmlElement.__proto__.__proto__;
- HTMLDocument = Document = document.constructor;
- var x = new DOMParser();
- XMLDocument = x.constructor;
- Element = x.parseFromString("<Single />", "text/xml").documentElement.constructor;
- x = null;
- }
-
- if (!XMLDocument.__defineGetter__) {
- Document.prototype.serialize =
- Node.prototype.serialize =
- XMLDocument.prototype.serialize = function(){
- return (new XMLSerializer()).serializeToString(this);
- };
- }
- }
-
-
- if (jpf.isSafariOld || jpf.isSafari || jpf.isChrome) {
- //XMLDocument.selectNodes
- HTMLDocument.prototype.selectNodes =
- XMLDocument.prototype.selectNodes = function(sExpr, contextNode){
- return jpf.XPath.selectNodes(sExpr, contextNode || this);
- };
-
- //Element.selectNodes
- Element.prototype.selectNodes = function(sExpr, contextNode){
- return jpf.XPath.selectNodes(sExpr, contextNode || this);
- };
-
- //XMLDocument.selectSingleNode
- HTMLDocument.prototype.selectSingleNode =
- XMLDocument.prototype.selectSingleNode = function(sExpr, contextNode){
- return jpf.XPath.selectNodes(sExpr, contextNode || this)[0];
- };
-
- //Element.selectSingleNode
- Element.prototype.selectSingleNode = function(sExpr, contextNode){
- return jpf.XPath.selectNodes(sExpr, contextNode || this)[0];
- };
-
- jpf.importClass(jpf.runXpath, true, self);
- jpf.importClass(jpf.runXslt, true, self);
- }
-
-
- if (jpf.runNonIe)
- jpf.runNonIe();
- //jpf.importClass(jpf.runNonIe, true, self);
-}
-
- - -/*FILEHEAD(/var/lib/jpf/src/core/parsers/jml.js)SIZE(-1077090856)TIME(1238950355)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - -/** - * The parser of the Javeline Markup Language. Besides jml this parser takes care - * of distributing parsing tasks to other parsers like the native html parser and - * the xsd parser. - * @parser - * @private - */ -jpf.JmlParser = { - sbInit : {}, - - stateStack : [], - modelInit : [], - - parse : function(x){ - jpf.console.info("Start parsing main application"); - jpf.Latometer.start(); - this.$jml = x; - - jpf.isParsing = true; - - //Check for children in Jml node - if (!x.childNodes.length) - throw new Error(jpf.formatErrorString(1014, null, - "jpf.JmlParser", - "JML Parser got Markup without any children")); - - //Create window and document - jpf.window = new jpf.WindowImplementation(); - jpf.document = new jpf.DocumentImplementation(); - jpf.window.document = jpf.document; - jpf.window.$at = new jpf.actiontracker(); - jpf.window.$at.name = "default"; - jpf.nameserver.register("actiontracker", "default", jpf.window.$at); - - //First pass parsing of all JML documents - for (var docs = [x], i = 0; i < jpf.includeStack.length; i++) { - if (jpf.includeStack[i].nodeType) - docs.push(jpf.includeStack[i]); - } - - this.docs = docs; - this.parseSettings(docs); - - if (!this.shouldWait) - this.continueStartup(); - }, - - //Allow for Async processes set in appsettings to load before parsing... - continueStartup : function(){ - this.parseFirstPass(this.docs); - - //Main parsing pass - jpf.JmlParser.parseChildren(this.$jml, document.body, jpf.document.documentElement);//, this); - - //Activate Layout Rules [Maybe change idef to something more specific] - if (jpf.appsettings.layout) - jpf.layout.loadFrom(jpf.appsettings.layout); - - //Last pass parsing - setTimeout('jpf.JmlParser.parseLastPass();', 1); - - //Set init flag for subparsers - this.inited = true; - - jpf.Latometer.end(); - jpf.Latometer.addPoint("Total load time"); - jpf.Latometer.start(true); - }, - - parseSettings : function(xmlDocs) { - for (var i = 0; i < xmlDocs.length; i++) - this.preLoadRef(xmlDocs[i], ["appsettings"]); - }, - - parseFirstPass: function(xmlDocs){ - jpf.console.info("Parse First Pass"); - - //@todo fix inline skin parsing collision - //"presentation", - for (var i = 0; i < xmlDocs.length; i++) - this.preLoadRef(xmlDocs[i], ["teleport", "settings", - "skin[not(@j_preparsed=9999)]", "bindings[@id]", "actions[@id]", "dragdrop[@id]", "remote"]); - //"style", - for (var i = 0; i < xmlDocs.length; i++) - this.preLoadRef(xmlDocs[i], ["model[@id]", - "smartbinding[@id]", "iconmap"], true); - }, - - preparsed : [], - preLoadRef : function(xmlNode, sel, parseLocalModel){ - /*BUG: IE document handling bugs - - removed to see what this does - if (jpf.isIE) { - if (xmlNode.style) return; - }*/ - - var prefix = jpf.findPrefix(xmlNode, jpf.ns.jml); - if (prefix) prefix += ":"; - var nodes = jpf.xmldb.selectNodes(".//" + prefix + sel.join("|.//" - + prefix) + (parseLocalModel ? "|" + prefix + "model" : ""), xmlNode); - - var i, o, name, tagName, x, l; - for (i = 0, l = nodes.length; i < l; i++) { - x = nodes[i]; - - //Check if node should be rendered - if (jpf.xmldb.getInheritedAttribute(x, "render") == "runtime") - continue; - - var tagName = x[jpf.TAGNAME]; - - //Process Node - if (this.handler[tagName]) { - jpf.console.info("Processing [preload] " + tagName + " node"); - - o = this.handler[tagName](x); - name = x.getAttribute("id"); //or u could use o.name - - //Add this component to the nameserver - if (o && name) - jpf.nameserver.register(tagName, name, o); - - if (!o || !o.nodeType) - o = new jpf.JmlDom(tagName, null, jpf.NODE_HIDDEN, x, o); - { - o.$jmlLoaded = true; - - if (name) - jpf.setReference(name, o); - } - - x.setAttribute("j_preparsed", this.preparsed.push(o) - 1); - } - else if (x.parentNode) { - x.parentNode.removeChild(x); - } - } - }, - - parseMoreJml : function(x, pHtmlNode, jmlParent, noImpliedParent, parseSelf, beforeNode){ - var parsing = jpf.isParsing; - jpf.isParsing = true; - - if (!jpf.window) { - jpf.window = new jpf.WindowImplementation(); - jpf.document = new jpf.DocumentImplementation(); - jpf.window.document = jpf.document; - jpf.window.$at = new jpf.actiontracker(); - jpf.nameserver.register("actiontracker", "default", jpf.window.$at); - } - - if (!jmlParent) - jmlParent = jpf.document.documentElement; - - this.parseFirstPass([x]); - - if (parseSelf) { - if (jmlParent.loadJml) - jmlParent.loadJml(x, jmlParent.parentNode); - jmlParent.$jmlLoaded = true; - - if (jmlParent && jmlParent.pData) - jpf.layout.compileAlignment(jmlParent.pData); - - if (jmlParent.pData || jmlParent.tagName == "grid") - jpf.layout.activateRules(pNode.oInt || document.body); - } - else { - var lastChild = pHtmlNode.lastChild; - this.parseChildren(x, pHtmlNode, jmlParent, false, noImpliedParent); - - if (beforeNode) { - var loop = pHtmlNode.lastChild; - while (lastChild != loop) { - pHtmlNode.insertBefore(loop, beforeNode); - loop = pHtmlNode.lastChild; - } - } - } - - jpf.layout.activateRules();//@todo maybe use processQueue - - this.parseLastPass(); - jpf.isParsing = parsing; - }, - - reWhitespaces : /[\t\n\r]+/g, - parseChildren : function(x, pHtmlNode, jmlParent, checkRender, noImpliedParent){ - //Let's not parse our children when they're already rendered - if (pHtmlNode == jmlParent.oInt && jmlParent.childNodes.length - && jmlParent != jpf.document.documentElement) - return pHtmlNode; - - if (!jpf.Latometer.isStarted) jpf.Latometer.start(); - - // Check for delayed rendering flag - if (checkRender && jmlParent && jmlParent.hasFeature(__DELAYEDRENDER__) - && jmlParent.$checkDelay(x)) { - jpf.console.info("Delaying rendering of children"); - - return pHtmlNode; - } - if (jmlParent) - jmlParent.isRendered = true; - - if (x.namespaceURI == jpf.ns.jml || x.tagUrn == jpf.ns.jml) - this.lastNsPrefix = x.prefix || x.scopeName; - - //Loop through Nodes - for (var oCount = 0,i = 0; i < x.childNodes.length; i++) { - var q = x.childNodes[i]; - if (q.nodeType == 8) continue; - - // Text nodes and comments - if (q.nodeType != 1) { - if (!pHtmlNode) continue; - - if (jpf.isIE && !q.nodeValue.trim()) - continue; - - if (q.nodeType == 3 || pHtmlNode.style && q.nodeType == 4) { - //if(jmlParent.name == "barTest") debugger; - pHtmlNode.appendChild(pHtmlNode.ownerDocument - .createTextNode(!jpf.hasTextNodeWhiteSpaceBug - ? q.nodeValue - : q.nodeValue.replace(this.reWhitespaces, " "))); - - } - else if (q.nodeType == 4) { - pHtmlNode.appendChild(pHtmlNode.ownerDocument - .createCDataSection(q.nodeValue)); - } - - jpf.language.addElement(q.nodeValue.replace(/^\$(.*)\$$/, - "$1"), {htmlNode : pHtmlNode}); - continue; - } - - //Parse node using namespace handler - if (!this.nsHandler[q.namespaceURI || q.tagUrn || jpf.ns.xhtml]) - continue; //ignore tag - - this.nsHandler[q.namespaceURI || q.tagUrn || jpf.ns.xhtml].call( - this, q, pHtmlNode, jmlParent, noImpliedParent); - } - - if (pHtmlNode) { - //Calculate Alignment and Anchoring - if (jmlParent && jmlParent.pData) - jpf.layout.compileAlignment(jmlParent.pData); - //jpf.layout.compile(pHtmlNode); - - if (!jpf.hasSingleRszEvent) - jpf.layout.activateRules(pHtmlNode); - } - - return pHtmlNode; - }, - - addNamespaceHandler : function(xmlns, func){ - this.nsHandler[xmlns] = func; - }, - - /** - * @define include element that loads another jml files. - * Example: - * <code> - * <j:include src="bindings.jml" /> - * </code> - * @attribute {String} src the location of the jml file to include in this application. - * @addnode global, anyjml - */ - /** - * @private - */ - nsHandler : { - //Javeline PlatForm - "http://www.javeline.com/2005/jml" : function(x, pHtmlNode, jmlParent, noImpliedParent){ - var tagName = x[jpf.TAGNAME]; - - // Includes - if (tagName == "include") { - jpf.console.info("Switching to include context"); - - var xmlNode = jpf.includeStack[x.getAttribute("iid")]; - if (!xmlNode) - return jpf.console.warn("No include file found"); - - this.parseChildren(xmlNode, pHtmlNode, jmlParent, null, true); - } - else - - // Handler - if (this.handler[tagName]) { - var o, id, name; - - //Deal with preparsed nodes - if (id = x.getAttribute("j_preparsed")) { - x.removeAttribute("j_preparsed"); - - o = this.preparsed[id]; - delete this.preparsed[id]; - - if (o && !o.parentNode) { - if (jmlParent.hasFeature && jmlParent.hasFeature(__WITH_JMLDOM__)) - o.$setParent(jmlParent); - else - { - o.parentNode = jmlParent; - jmlParent.childNodes.push(o); - } - } - - return o; - } - - jpf.console.info("Processing '" + tagName + "' node"); - - o = this.handler[tagName](x, (noImpliedParent - ? null - : jmlParent), pHtmlNode); - - name = x.getAttribute("id"); //or u could use o.name - - //Add this component to the nameserver - if (o && name) - jpf.nameserver.register(tagName, name, o); - - if (!o || !o.nodeType) - o = new jpf.JmlDom(tagName, jmlParent, jpf.NODE_HIDDEN, x, o); - else if(noImpliedParent) - o.$setParent(jmlParent); - { - o.$jmlLoaded = true; - - if (name) - jpf.setReference(name, o); - } - } - - //XForms - //JML Components - else if (pHtmlNode) { - if (!jpf[tagName] || typeof jpf[tagName] != "function") - throw new Error(jpf.formatErrorString(1017, null, - "Initialization", - "Could not find Class Definition '" + tagName + "'.", x)); - - if (!jpf[tagName]) - throw new Error("Could not find class " + tagName); - - var objName = tagName; - - //Check if Class is loaded in current Window - //if(!self[tagName]) main.window.jpf.importClass(main.window[tagName], false, window); - - if (tagName == "input") { - objName = jpf.HTML5INPUT[objName = x.getAttribute("type")] - || objName || "textbox"; - } - - //Create Object en Reference - var o = new jpf[objName](pHtmlNode, tagName, x); - if (x.getAttribute("id")) - jpf.setReference(x.getAttribute("id"), o); - - //Process JML - if (o.loadJml) - o.loadJml(x, jmlParent); - - o.$jmlLoaded = true; - } - - return o; - } - - //XML Schema Definition - ,"http://www.w3.org/2001/XMLSchema" : function(x, pHtmlNode, jmlParent, noImpliedParent){ - var type = jpf.XSDParser.parse(x); - if (type && jmlParent) - jmlParent.setProperty("datatype", type); - } - - //XHTML - ,"http://www.w3.org/1999/xhtml" : function(x, pHtmlNode, jmlParent, noImpliedParent){ - var parseWhole = x.tagName.match(/table|object|embed/i) ? true : false; - - if (!pHtmlNode) { - throw new Error(jpf.formatErrorString(0, jmlParent, - "Parsing html elements", - "Unexpected HTML found", x)); - } - - // Move all this to the respective browser libs in a wrapper function - if (x.tagName == "script") { - return; - } - else if (x.tagName == "option") { - var o = pHtmlNode.appendChild(pHtmlNode.ownerDocument.createElement("option")); - if (x.getAttribute("value")) - o.setAttribute("value", x.getAttribute("value")); - } - else if (jpf.isIE) { - var o = (x.ownerDocument == pHtmlNode.ownerDocument) - ? pHtmlNode.appendChild(x.cloneNode(false)) - : jpf.xmldb.htmlImport(x.cloneNode(parseWhole), pHtmlNode); - } - else if (jpf.isSafari) { //SAFARI importing cloned node kills safari.. temp workaround in place - //o = pHtmlNode.appendChild(pHtmlNode.ownerDocument.importNode(x));//.cloneNode(false) - var o = (x.ownerDocument == pHtmlNode.ownerDocument) - ? pHtmlNode.appendChild(x) - : jpf.xmldb.htmlImport(x.cloneNode(parseWhole), pHtmlNode); - } - else { - var o = (x.ownerDocument == pHtmlNode.ownerDocument) - ? pHtmlNode.appendChild(x.cloneNode(false)) - : jpf.xmldb.htmlImport(x.cloneNode(false), pHtmlNode); - //o = pHtmlNode.appendChild(pHtmlNode.ownerDocument.importNode(x.cloneNode(false), false)); - } - - //Check attributes for j:left etc and j:repeat-nodeset - var tagName; - var prefix = this.lastNsPrefix || jpf.findPrefix(x.parentNode, jpf.ns.jml) || ""; - if (prefix && !x.style) { - if (!jpf.supportNamespaces) - x.ownerDocument.setProperty("SelectionNamespaces", "xmlns:" - + prefix + "='" + jpf.ns.jml + "'"); - prefix += ":"; - } - - var done = {}, aNodes = !x.style && x.selectNodes("@" + prefix + "*") || []; - for (var i = 0; i < aNodes.length; i++) { - tagName = aNodes[i][jpf.TAGNAME]; - - //@todo rewrite this, and optimize html loading - if (tagName.match(/^(left|top|right|bottom|width|height|align)$/)) { - if (done["position"]) continue; - done["position"] = true; - //Create positioning object - remove attributes when done - var html = new jpf.HtmlWrapper(pHtmlNode, o, prefix); - - if (x.getAttribute(prefix + "align") - || x.getAttribute(prefix + "align-position")) { - html.enableAlignment() - } - else if (x.getAttribute(prefix + "width") - || x.getAttribute(prefix + "height") - || x.getAttribute(prefix + "left") - || x.getAttribute(prefix + "top") - || x.getAttribute(prefix + "right") - || x.getAttribute(prefix + "bottom") - || x.getAttribute(prefix + "anchoring") == "true") { - html.getDiff(); - html.setHorizontal(x.getAttribute(prefix + "left"), - x.getAttribute(prefix + "right"), - x.getAttribute(prefix + "width")); - html.setVertical(x.getAttribute(prefix + "top"), - x.getAttribute(prefix + "bottom"), - x.getAttribute(prefix + "height")); - } - - //return o; - } - - } - - if ((jpf.canUseInnerHtmlWithTables || !parseWhole) && x.tagName.toUpperCase() != "IFRAME") - this.parseChildren(x, o, jmlParent); - else { - jpf.console.warn("Not parsing children of table, \ - ignoring all Javeline Platform Elements."); - } - - if (jpf.xmldb.getTextNode(x)) { - var data = { - jmlNode : x, - htmlNode : o - } - - jpf.language.addElement(jpf.xmldb.getTextNode(x) - .nodeValue.replace(/^\$(.*)\$$/, "$1"), data); - } - - return o; - } - }, - - - invalidJml : function(jml, message){ - jpf.console.warn((message || "Invalid JML syntax. The j:" - + jml[jpf.TAGNAME] + " node should not be placed under \ - it's current parent:") + "\n" - + (jml.xml || jml.serialize)); - }, - - handler : { - /** - * @define script element that loads javascript into the application - * either from it's first child or from a file. - * Example: - * <code> - * <j:script src="code.js" /> - * </code> - * Example: - * <code> - * <j:script><![CDATA[ - * for (var i = 0; i < 10; i++) { - * alert(i); - * } - * ]]></j:script> - * </code> - * @attribute {String} src the location of the script file. - * @addnode global, anyjml - */ - "script" : function(q){ - if (q.getAttribute("src")) { - if (jpf.isOpera) { - setTimeout(function(){ - jpf.window.loadCodeFile(jpf.hostPath - + q.getAttribute("src")); - }, 1000); - } - else { - jpf.window.loadCodeFile(jpf.hostPath - + q.getAttribute("src")); - } - } - else if (q.firstChild) { - var scode = q.firstChild.nodeValue; - jpf.exec(scode); - } - }, - - /** - * @define state-group Element that groups state elements together and - * provides a way to set a default state. - * Example: - * <code> - * <j:state-group - * loginMsg.visible = "false" - * winLogin.disabled = "false"> - * <j:state id="stFail" - * loginMsg.value = "Username or password incorrect" - * loginMsg.visible = "true" /> - * <j:state id="stError" - * loginMsg.value = "An error has occurred. Please check your network." - * loginMsg.visible = "true" /> - * <j:state id="stLoggingIn" - * loginMsg.value = "Please wait while logging in..." - * loginMsg.visible = "true" - * winLogin.disabled = "true" /> - * <j:state id="stIdle" /> - * </j:state-group> - * </code> - * @addnode elements - * @see element.state - */ - "state-group" : function(q, jmlParent){ - var name = q.getAttribute("name") || "stategroup" + jpf.all.length; - var pState = jpf.StateServer.addGroup(name, null, jmlParent); - - var nodes = q.childNodes, attr = q.attributes, al = attr.length; - for (var j, i = 0, l = nodes.length; i < l; i++){ - var node = nodes[i]; - - if (node.nodeType != 1 || node[jpf.TAGNAME] != "state") - continue; - - for (j = 0; j < al; j++) { - if (!node.getAttribute(attr[j].nodeName)) - node.setAttribute(attr[j].nodeName, attr[j].nodeValue); - } - - node.setAttribute("group", name); - - //Create Object en Reference and load JML - new jpf.state(jmlParent ? jmlParent.pHtmlNode : document.body, "state", node) - .loadJml(node, pState); - } - - return pState; - }, - - /** - * @define iconmap element that provides a means to get icons from a - * single image containing many icons. - * Example: - * <code> - * <j:iconmap id="tbicons" src="toolbar.icons.gif" - * type="horizontal" size="20" offset="2,2" /> - * - * <j:menu id="mmain" skin="menu2005"> - * <j:item icon="tbicons:1">Copy</j:item> - * <j:item icon="tbicons:2">Cut</j:item> - * </j:menu> - * </code> - * @attribute {String} src the location of the image. - * @attribute {String} type the spatial distribution of the icons within the image. - * Possible values: - * horizontal the icons are horizontally tiled. - * vertically the icons are vertically tiled. - * @attribute {String} size the width and height in pixels of an icon. Use this for square icons. - * @attribute {String} width the width of an icon in pixels. - * @attribute {String} height the height of an icon in pixels. - * @attribute {String} offset the distance from the calculated grid point that has to be added. This value consists of two numbers seperated by a comma. Defaults to 0,0. - * @addnode elements - */ - "iconmap" : function(q, jmlParent){ - var name = q.getAttribute("id"); - - if (!name) { - throw new Error(jpf.formatErrorString(0, null, - "Creating icon map", - "Could not create iconmap. Missing id attribute", q)); - } - - return jpf.skins.addIconMap({ - name : name, - src : q.getAttribute("src"), - type : q.getAttribute("type"), - size : parseInt(q.getAttribute("size")), - width : parseInt(q.getAttribute("width")), - height : parseInt(q.getAttribute("height")), - offset : (q.getAttribute("offset") || "0,0").splitSafe(",") - }); - }, - - /** - * @define window Alias for {@link element.modalwindow}. - * @addnode element - */ - "window" : function(q, jmlParent, pHtmlNode){ - //Create Object en Reference - var o = new jpf.modalwindow(pHtmlNode, "window", q); - - //Process JML - o.loadJml(q, jmlParent); - - //jpf.windowManager.addForm(q); //@todo rearchitect this - - return o; - }, - - /** - * @define style element containing css - * @addnode global, anyjml - */ - "style" : function(q){ - jpf.importCssString(document, q.firstChild.nodeValue); - }, - - /** - * @define comment all elements within the comment tag are ignored by the parser. - * @addnode anyjml - */ - "comment" : function (q){ - //do nothing - }, - - /** - * @define presentation element containing a skin definition - * @addnode global, anyjml - */ - "presentation" : function(q){ - var name = "skin" + Math.round(Math.random() * 100000); - q.parentNode.setAttribute("skin", name); - jpf.skins.skins[name] = {name:name,templates:{}} - var t = q.parentNode[jpf.TAGNAME]; - var skin = q.ownerDocument.createElement("skin"); skin.appendChild(q); - jpf.skins.skins[name].templates[t] = skin; - }, - - /** - * @define skin element specifying the skin of an application. - * Example: - * <code> - * <j:skin src="perspex.xml" - * name = "perspex" - * media-path = "http://example.com/images" - * icon-path = "http://icons.example.com" /> - * </code> - * @attribute {String} name the name of the skinset. - * @attribute {String} src the location of the skin definition. - * @attribute {String} media-path the basepath for the images of the skin. - * @attribute {String} icon-path the basepath for the icons used in the elements using this skinset. - * @addnode global, anyjml - */ - "skin" : function(q, jmlParent){ - if (jmlParent) { - var name = "skin" + Math.round(Math.random() * 100000); - q.parentNode.setAttribute("skin", name); - jpf.skins.skins[name] = {name: name, templates: {}}; - jpf.skins.skins[name].templates[q.parentNode[jpf.TAGNAME]] = q; - } - else if (q.childNodes.length) { - jpf.skins.Init(q); - } - else { - var path = q.getAttribute("src") - ? jpf.getAbsolutePath(jpf.hostPath, q.getAttribute("src")) - : jpf.getAbsolutePath(jpf.hostPath, q.getAttribute("name")) + "/index.xml"; - - jpf.loadJmlInclude(q, true, path); - } - }, - - - "model" : function(q, jmlParent){ - var model = new jpf.model().loadJml(q, jmlParent); - - if (jmlParent && jmlParent.hasFeature(__DATABINDING__)) { - modelId = "model" + jmlParent.uniqueId; - jmlParent.$jml.setAttribute("model", modelId); - model.register(jmlParent); - jpf.nameserver.register("model", modelId, model); - } - - return model; - }, - - "smartbinding" : function(q, jmlParent){ - var bc = new jpf.smartbinding(q.getAttribute("id"), q, jmlParent); - - if (jmlParent && jmlParent.hasFeature(__DATABINDING__)) - jpf.JmlParser.addToSbStack(jmlParent.uniqueId, bc); - - return bc; - }, - - "ref" : function(q, jmlParent){ - if (!jmlParent || !jmlParent.hasFeature(__DATABINDING__)) - return jpf.JmlParser.invalidJml(q); - - jpf.JmlParser.getFromSbStack(jmlParent.uniqueId) - .addBindRule(q, jmlParent); - }, //not referencable - - "bindings" : function(q, jmlParent){ - var rules = jpf.getRules(q); - - if (jmlParent && jmlParent.hasFeature(__DATABINDING__)) - jpf.JmlParser.getFromSbStack(jmlParent.uniqueId) - .addBindings(rules, q); - - return rules; - }, - - "action" : function(q, jmlParent){ - if (!jmlParent || !jmlParent.hasFeature(__DATABINDING__)) - return jpf.JmlParser.invalidJml(q); - - jpf.JmlParser.getFromSbStack(jmlParent.uniqueId) - .addActionRule(q, jmlParent); - }, //not referencable - - "actions" : function(q, jmlParent){ - var rules = jpf.getRules(q); - - if (jmlParent && jmlParent.hasFeature(__DATABINDING__)) { - jpf.JmlParser.getFromSbStack(jmlParent.uniqueId) - .addActions(rules, q); - } - - return rules; - }, - - - "actiontracker" : function(q, jmlParent){ - var at = new jpf.actiontracker(jmlParent); - at.loadJml(q); - - if (jmlParent) - jmlParent.$at = at; - - return at; - }, - - - /** - * @for JmlNode - * @define contextmenu element specifying which menu is shown when a - * contextmenu is requested by a user for a jml node. - * Example: - * This example shows a list that shows the mnuRoot menu when the user - * right clicks on the root data element. Otherwise the mnuItem menu is - * shown. - * <code> - * <j:list> - * <j:contextmenu menu="mnuRoot" select="root" /> - * <j:contextmenu menu="mnuItem" /> - * </j:list> - * </code> - * @attribute {String} menu the id of the menu element. - * @attribute {String} select the xpath executed on the selected element of the databound element which determines whether this contextmenu is shown. - */ - "contextmenu" : function(q, jmlParent){ - if (!jmlParent) - return jpf.JmlParser.invalidJml(q); //not supported - - if (!jmlParent.contextmenus) - jmlParent.contextmenus = []; - jmlParent.contextmenus.push(q); - }, - - - "allow-drag" : function(q, jmlParent){ - if (!jmlParent || !jmlParent.hasFeature(__DATABINDING__)) - return jpf.JmlParser.invalidJml(q); - - jpf.JmlParser.getFromSbStack(jmlParent.uniqueId) - .addDragRule(q, jmlParent); - }, //not referencable - - "allow-drop" : function(q, jmlParent){ - if (!jmlParent || !jmlParent.hasFeature(__DATABINDING__)) - return jpf.JmlParser.invalidJml(q); - - jpf.JmlParser.getFromSbStack(jmlParent.uniqueId) - .addDropRule(q, jmlParent); - }, //not referencable - - "dragdrop" : function(q, jmlParent){ - var rules = jpf.getRules(q); - - if (jmlParent && jmlParent.hasFeature(__DATABINDING__)) { - jpf.JmlParser.getFromSbStack(jmlParent.uniqueId) - .addDragDrop(rules, q); - } - - return rules; - }, - - "teleport" : function(q, jmlParent){ - //Initialize Communication Component - return jpf.teleport.loadJml(q, jmlParent); - }, - - "remote" : function(q, jmlParent){ - //Remote Smart Bindings - return new jpf.remote(q.getAttribute("id"), q, jmlParent); - }, - - "appsettings" : function(q, jmlParent){ - return jpf.appsettings.loadJml(q, jmlParent); - } - - , "deskrun" : function(q){ - if (!jpf.isDeskrun) return; - jpf.window.loadJml(q); //@todo rearchitect this - } - - /** - * @define loader Element defining the html that is shown while the - * application is loading. - * Example: - * <code> - * <j:loader> - * <div class="loader"> - * Loading... - * </div> - * </j:loader> - * </code> - * @addnode global - */ - , "loader" : function(q){ - //ignore, handled elsewhere - } - }, - - getSmartBinding : function(id){ - return jpf.nameserver.get("smartbinding", id); - }, - - getActionTracker : function(id){ - var at = jpf.nameserver.get("actiontracker", id); - if (at) - return at; - if (self[id]) - return self[id].getActionTracker(); - }, - - replaceNode : function(newNode, oldNode){ - var nodes = oldNode.childNodes; - for (var i = nodes.length - 1; i >= 0; i--) { - if (nodes[i].host) { - nodes[i].host.pHtmlNode = newNode; - } - newNode.insertBefore(nodes[i], newNode.firstChild); - } - - newNode.onresize = oldNode.onresize; - - return newNode; - }, - - parseLastPass : function(){ - - jpf.console.info("Parse final pass"); - - //if (!jpf.appsettings.offline) - // jpf.offline.init(); - - jpf.parsingFinalPass = true; - - /* - All these component dependant things might - be suited better to be in a component generation - called event - */ - - while (this.hasNewSbStackItems) { - var sbInit = this.sbInit; - this.sbInit = {}; - this.hasNewSbStackItems = false; - - //Initialize Databinding for all GUI Elements in Form - for (var uniqueId in sbInit) { - if (parseInt(uniqueId) != uniqueId) - continue; - - //Retrieve Jml Node - var jNode = jpf.lookup(uniqueId); - - //Set Main smartbinding - if (sbInit[uniqueId][0]) { - jNode.$propHandlers["smartbinding"] - .call(jNode, sbInit[uniqueId][0], true); - } - - //Set selection smartbinding if any - if (sbInit[uniqueId][1]) - jNode.$setMultiBind(sbInit[uniqueId][1]); - } - } - this.sbInit = {}; - - //Initialize property bindings - var s = this.stateStack; - for (var i = 0; i < s.length; i++) { - //if (s[i].name == "visible" && !/^\{.*\}$/.test(s[i].value)) //!jpf.dynPropMatch.test(pValue) - //continue; //@todo check that this code can be removed... - s[i].node.setDynamicProperty(s[i].name, s[i].value); - } - this.stateStack = []; - - //Initialize Models - while (this.hasNewModelStackItems) { - var jmlNode, modelInit = this.modelInit; - this.modelInit = {}; - this.hasNewModelStackItems = false; - - for (var data,i = 0; i < modelInit.length; i++) { - data = modelInit[i][1]; - data[0] = data[0].substr(1); - - jmlNode = eval(data[0]); - if (jmlNode.connect) - jmlNode.connect(modelInit[i][0], null, data[2], data[1] || "select"); - else - jmlNode.setModel(new jpf.model().loadFrom(data.join(":"))); - } - } - this.modelInit = []; - - //Call the onload event - if (!jpf.loaded) - jpf.dispatchEvent("load"); - jpf.loaded = true; - - - jpf.layout.activateRules();// processQueue(); - - if (!this.loaded) { - if (jpf.isDeskrun) - jpf.window.deskrun.Show(); - - //Set the default selected element - if (!jpf.window.focussed) - jpf.window.focusDefault(); - - this.loaded = true; - } - - //END OF ENTIRE APPLICATION STARTUP - - jpf.console.info("Initialization finished"); - - jpf.Latometer.end(); - jpf.Latometer.addPoint("Total time for final pass"); - - jpf.isParsing = false; - jpf.parsingFinalPass = false; - } - - , - addToSbStack : function(uniqueId, sNode, nr){ - this.hasNewSbStackItems = true; - - return ((this.sbInit[uniqueId] - || (this.sbInit[uniqueId] = []))[nr||0] = sNode); - }, - - getFromSbStack : function(uniqueId, nr, create){ - this.hasNewSbStackItems = true; - if (nr) { - if (!create) - return (this.sbInit[uniqueId] || {})[nr]; - - return this.sbInit[uniqueId] - && (this.sbInit[uniqueId][nr] - || (this.sbInit[uniqueId][nr] = new jpf.smartbinding())) - || ((this.sbInit[uniqueId] = [])[nr] = new jpf.smartbinding()); - } - - return !this.sbInit[uniqueId] - && (this.sbInit[uniqueId] = [new jpf.smartbinding()])[0] - || this.sbInit[uniqueId][0] - || (this.sbInit[uniqueId][0] = new jpf.smartbinding()); - }, - - stackHasBindings : function(uniqueId){ - return (this.sbInit[uniqueId] && this.sbInit[uniqueId][0] - && this.sbInit[uniqueId][0].bindings); - } - - , - - addToModelStack : function(o, data){ - this.hasNewModelStackItems = true; - this.modelInit.push([o, data]); - } -}; - - -/** - * @define input - * Remarks: - * Javeline PlatForm supports the input types specified by the WHATWG html5 spec. - * @attribute {String} type the type of input element. - * Possible values: - * email provides a way to enter an email address. - * url provides a way to enter a url. - * password provides a way to enter a password. - * datetime provides a way to pick a date and time. - * date provides a way to pick a date. - * month provides a way to pick a month. - * week provides a way to pick a week. - * time provides a way to pick a time. - * number provides a way to pick a number. - * range provides a way to select a point in a range. - * checkbox provides a way to set a boolean value. - * radio used in a set, it provides a way to select a single value from multiple options. - * file provides a way to upload a file. - * submit provides a way to submit data. - * image provides a way to submit data displaying an image instead of a button. - * reset provides a way to reset entered data. - * @addnode elements - */ -/** - * @private - */ -jpf.HTML5INPUT = { - "email" : "textbox", - "url" : "textbox", - "password" : "textbox", - "datetime" : "spinner", //@todo - "date" : "calendar", - "month" : "spinner", //@todo - "week" : "spinner", //@todo - "time" : "spinner", //@todo - "number" : "spinner", - "range" : "slider", - "checkbox" : "checkbox", - "radio" : "radiobutton", - "file" : "fileuploadbox", - "submit" : "submit", - "image" : "submit", - "reset" : "button" -}; - - -jpf.Init.run('jpf.JmlParser'); - - -/*FILEHEAD(/var/lib/jpf/src/core/parsers/xslt.js)SIZE(-1077090856)TIME(1238933672)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-jpf.runXslt = function(){
- /**
- * @constructor
- * @parser
- */
- jpf.XSLTProcessor = function(){
- this.templates = {};
- this.p = {
- "value-of": function(context, xslNode, childStack, result){
- var xmlNode = jpf.XPath.selectNodes(xslNode.getAttribute("select"), context)[0];// + "[0]"
- if (!xmlNode)
- value = "";
- else {
- if (xmlNode.nodeType == 1)
- value = xmlNode.firstChild ? xmlNode.firstChild.nodeValue : "";
- else
- value = typeof xmlNode == "object" ? xmlNode.nodeValue : xmlNode;
- }
-
- result.appendChild(this.xmlDoc.createTextNode(value));
- },
-
- "copy-of": function(context, xslNode, childStack, result){
- var xmlNode = jpf.XPath.selectNodes(xslNode.getAttribute("select"), context)[0];// + "[0]"
- if (xmlNode)
- result.appendChild(jpf.canImportNode
- ? result.ownerDocument.importNode(xmlNode, true)
- : xmlNode.cloneNode(true));
- },
-
- "if": function(context, xslNode, childStack, result){
- if (jpf.XPath.selectNodes(xslNode.getAttribute("test"), context)[0]) {// + "[0]"
- this.parseChildren(context, xslNode, childStack, result);
- }
- },
-
- "for-each": function(context, xslNode, childStack, result){
- var nodes = jpf.XPath.selectNodes(xslNode.getAttribute("select"), context);
- for (var i = 0; i < nodes.length; i++) {
- this.parseChildren(nodes[i], xslNode, childStack, result);
- }
- },
-
- "choose": function(context, xslNode, childStack, result){
- var nodes = xslNode.childNodes;
- for (var i = 0; i < nodes.length; i++) {
- if (!nodes[i].tagName)
- continue;
-
- if (nodes[i][jpf.TAGNAME] == "otherwise"
- || nodes[i][jpf.TAGNAME] == "when"
- && jpf.XPath.selectNodes(nodes[i].getAttribute("test"), context)[0])
- return this.parseChildren(context, nodes[i], childStack[i][2], result);
- }
- },
-
- "output": function(context, xslNode, childStack, result){},
-
- "param": function(context, xslNode, childStack, result){},
-
- "attribute": function(context, xslNode, childStack, result){
- var nres = this.xmlDoc.createDocumentFragment();
- this.parseChildren(context, xslNode, childStack, nres);
-
- result.setAttribute(xslNode.getAttribute("name"), nres.xml);
- },
-
- "apply-templates": function(context, xslNode, childStack, result){
- if (!xslNode) {
- var t = this.templates["/"] || this.templates[context.tagName];
- if (t)
- this.parseChildren(t == this.templates["/"]
- ? context.ownerDocument : context, t[0], t[1], result);
- }
- else {
- if (xslNode.getAttribute("select")) {
- var t = this.templates[xslNode.getAttribute("select")];
- if (t) {
- if (xslNode.getAttribute("select") == "/")
- return alert("Something went wrong. The / template was executed as a normal template");
-
- var nodes = context.selectNodes(xslNode.getAttribute("select"));
- for (var i = 0; i < nodes.length; i++)
- this.parseChildren(nodes[i], t[0], t[1], result);
- }
- }
- //Named templates should be in a different hash
- else {
- if (xslNode.getAttribute("name")) {
- var t = this.templates[xslNode.getAttribute("name")];
- if (t)
- this.parseChildren(context, t[0], t[1], result);
- }
- else {
- //Copy context
- var ncontext = context.cloneNode(true); //importnode here??
- var nres = this.xmlDoc.createDocumentFragment();
-
- var nodes = ncontext.childNodes;
- for (var tName, i = nodes.length - 1; i >= 0; i--) {
- if (nodes[i].nodeType == 3 || nodes[i].nodeType == 4) {
- //result.appendChild(this.xmlDoc.createTextNode(nodes[i].nodeValue));
- continue;
- }
- if (!nodes[i].nodeType == 1)
- continue;
- var n = nodes[i];
-
- //Loop through all templates
- for (tName in this.templates) {
- if (tName == "/")
- continue;
- var t = this.templates[tName];
-
- var snodes = n.selectNodes("self::" + tName);
- for (var j = snodes.length - 1; j >= 0; j--) {
- var s = snodes[j], p = s.parentNode;
- this.parseChildren(s, t[0], t[1], nres);
- if (nres.childNodes) {
- for (var k = nres.childNodes.length - 1; k >= 0; k--)
- p.insertBefore(nres.childNodes[k], s);
- }
- p.removeChild(s);
- }
- }
-
- if (n.parentNode) {
- var p = n.parentNode;
- this.p["apply-templates"].call(this, n, xslNode, childStack, nres);
- if (nres.childNodes) {
- for (var k = nres.childNodes.length - 1; k >= 0; k--)
- p.insertBefore(nres.childNodes[k], n);
- }
- p.removeChild(n);
- }
- }
-
- for (var i = ncontext.childNodes.length - 1; i >= 0; i--)
- result.insertBefore(ncontext.childNodes[i], result.firstChild);
- }
- }
- }
- },
-
- cache : {},
- "import": function(context, xslNode, childStack, result){
- var file = xslNode.getAttribute("href");
- if (!this.cache[file]) {
- var data = new jpf.http().get(file);
- this.cache[file] = data;
- }
-
- //compile
- //parseChildren
- },
-
- "include" : function(context, xslNode, childStack, result){},
-
- "when" : function(){},
- "otherwise": function(){},
-
- "copy-clone": function(context, xslNode, childStack, result){
- result = result.appendChild(jpf.canImportNode ? result.ownerDocument.importNode(xslNode, false) : xslNode.cloneNode(false));
- if (result.nodeType == 1) {
- for (var i = 0; i < result.attributes.length; i++) {
- var blah = result.attributes[i].nodeValue; //stupid Safari shit
- if (!jpf.isSafariOld && result.attributes[i].nodeName.match(/^xmlns/))
- continue;
- result.attributes[i].nodeValue = result.attributes[i].nodeValue.replace(/\{([^\}]+)\}/g, function(m, xpath){
- var xmlNode = jpf.XPath.selectNodes(xpath, context)[0];
-
- if (!xmlNode) {
- value = "";
- }
- else {
- if (xmlNode.nodeType == 1)
- value = xmlNode.firstChild ? xmlNode.firstChild.nodeValue : "";
- else
- value = typeof xmlNode == "object" ? xmlNode.nodeValue : xmlNode;
- }
-
- return value;
- });
-
- result.attributes[i].nodeValue; //stupid Safari shit
- }
- }
-
- this.parseChildren(context, xslNode, childStack, result);
- }
- }
-
- this.parseChildren = function(context, xslNode, childStack, result){
- if (!childStack)
- return;
- for (var i = 0; i < childStack.length; i++) {
- childStack[i][0].call(this, context, childStack[i][1], childStack[i][2], result);
- }
- };
-
- this.compile = function(xslNode){
- var nodes = xslNode.childNodes;
- for (var stack = [], i = 0; i < nodes.length; i++) {
- if (nodes[i].nodeType != 1 && nodes[i].nodeType != 3 && nodes[i].nodeType != 4)
- continue;
-
- if (nodes[i][jpf.TAGNAME] == "template") {
- this.templates[nodes[i].getAttribute("match") || nodes[i].getAttribute("name")] = [nodes[i], this.compile(nodes[i])];
- }
- else {
- if (nodes[i][jpf.TAGNAME] == "stylesheet") {
- this.compile(nodes[i])
- }
- else {
- if (nodes[i].prefix == "xsl") {
- var func = this.p[nodes[i][jpf.TAGNAME]];
- if (!func)
- alert("xsl:" + nodes[i][jpf.TAGNAME] + " is not supported at this time on this platform");
- else
- stack.push([func, nodes[i], this.compile(nodes[i])]);
- }
- else {
- stack.push([this.p["copy-clone"], nodes[i], this.compile(nodes[i])]);
- }
- }
- }
- }
- return stack;
- };
-
- this.importStylesheet = function(xslDoc){
- this.xslDoc = xslDoc.nodeType == 9 ? xslDoc.documentElement : xslDoc;
- xslStack = this.compile(xslDoc);
-
- //var t = this.templates["/"] ? "/" : false;
- //if(!t) for(t in this.templates) if(typeof this.templates[t] == "array") break;
- this.xslStack = [[this.p["apply-templates"], null]];//{getAttribute : function(n){if(n=="name") return t}
- };
-
- //return nodes
- this.transformToFragment = function(doc, newDoc){
- this.xmlDoc = newDoc.nodeType != 9 ? newDoc.ownerDocument : newDoc;//new DOMParser().parseFromString("<xsltresult></xsltresult>", "text/xml");//
- var docfrag = this.xmlDoc.createDocumentFragment();
-
- if (!jpf.isSafariOld && doc.nodeType == 9)
- doc = doc.documentElement;
- var result = this.parseChildren(doc, this.xslDoc, this.xslStack, docfrag);
- return docfrag;
- };
- };
-
- self.XSLTProcessor = jpf.XSLTProcessor;
-
-}
-
- - -/*FILEHEAD(/var/lib/jpf/src/core/parsers/url.js)SIZE(-1077090856)TIME(1238944816)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * Object that represents a URI, broken down to its parts, according to RFC3986.
- * All parts are publicly accessible after parsing like 'url.port' or 'url.host'.
- * Example:
- * <code>
- * var url = new jpf.url('http://usr:pwd@www.test.com:81/dir/dir.2/index.htm?q1=0&&test1&test2=value#top');
- * alert(url.port); //will show '81'
- * alert(url.host); //will show 'www.test.com'
- * alert(url.isSameLocation()) // will show 'true' when the browser is surfing on the www.test.com domain
- * </code>
- *
- * @link http://tools.ietf.org/html/rfc3986
- * @classDescription This class creates a new URL object, divided into chunks
- * @return {jpf.url} Returns a new jpf.uri instance
- * @type {jpf.url}
- * @constructor
- * @parser
- *
- * @author Mike de Boer
- * @version %I%, %G%
- * @since 1.0
- */
-jpf.url = function(str) {
- var base;
- if (str.indexOf(":") == -1 && (base = window.location.toString()).indexOf(":") != -1) {
- base = new jpf.url(base);
- str = jpf.getAbsolutePath("http://" + base.host + "/"
- + (base.directory.charAt(base.directory.length - 1) == "/"
- ? base.directory
- : base.directory + '/'), str);
- }
- var o = jpf.url.options,
- m = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
- i = 14;
- this.uri = str.toString(); //copy string
-
- while (i--)
- this[o.key[i]] = m[i] || "";
-
- this[o.q.name] = {};
- var _self = this;
- this[o.key[12]].replace(o.q.parser, function($0, $1, $2){
- if ($1)
- _self[o.q.name][$1] = $2;
- });
-};
-
-jpf.url.prototype = {
- /**
- * Checks if the same origin policy is in effect for this URI.
- * @link http://developer.mozilla.org/index.php?title=En/Same_origin_policy_for_JavaScript
- *
- * @type {Boolean}
- */
- isSameLocation: function(){
- // filter out anchors
- if (this.uri.length && this.uri.charAt(0) == "#")
- return false;
- // totally relative -- ../../someFile.html
- if (!this.protocol && !this.port && !this.host)
- return true;
-
- // scheme relative with port specified -- foo.com:8080
- if (!this.protocol && this.host && this.port
- && window.location.hostname == this.host
- && window.location.port == this.port) {
- return true;
- }
- // scheme relative with no-port specified -- foo.com
- if (!this.protocol && this.host && !this.port
- && window.location.hostname == this.host
- && window.location.port == 80) {
- return true;
- }
- return window.location.protocol == (this.protocol + ":")
- && window.location.hostname == this.host
- && (window.location.port == this.port || !window.location.port && !this.port);
- }
-};
-
-jpf.url.options = {
- strictMode: false,
- key: ["source", "protocol", "authority", "userInfo", "user", "password",
- "host", "port", "relative", "path", "directory", "file", "query",
- "anchor"],
- q : {
- name : "queryKey",
- parser: /(?:^|&)([^&=]*)=?([^&]*)/g
- },
- parser: {
- strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
- loose : /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
- }
-};
-
- - -/*FILEHEAD(/var/lib/jpf/src/core/parsers/xsd.js)SIZE(-1077090856)TIME(1238933672)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-//Non validating parser
-
-/**
- * Object returning an implementation of an XSD parser.
- *
- * @classDescription This class creates a new XSD parser
- * @return {XSDImplementation} Returns a new XSD parser
- * @type {XSDImplementation}
- * @constructor
- * @parser
- *
- * @allownode simpleType, complexType
- *
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.8
- */
-jpf.XSDImplementation = function(){
- var typeHandlers = {
- //XSD datetypes [L10n potential]
- "xsd:dateTime": function(value){
- value = value.replace(/-/g, "/");
-
- value.match(/^(\d{2})\/(\d{2})\/(\d{4}) (\d{2}):(\d{2}):(\d{2})$/);
- if (!RegExp.$3 || RegExp.$3.length < 4)
- return false;
-
- var dt = new Date(value);
- if (dt.getFullYear() != parseFloat(RegExp.$3))
- return false;
- if (dt.getMonth() != parseFloat(RegExp.$2) - 1)
- return false;
- if (dt.getDate() != parseFloat(RegExp.$1))
- return false;
- if (dt.getHours() != parseFloat(RegExp.$4))
- return false;
- if (dt.getMinutes() != parseFloat(RegExp.$5))
- return false;
- if (dt.getSeconds() != parseFloat(RegExp.$5))
- return false;
-
- return true;
- },
- "xsd:time": function(value){
- value.match(/^(\d{2}):(\d{2}):(\d{2})$/);
-
- var dt = new Date("21/06/1980 " + value);
- if (dt.getHours() != parseFloat(RegExp.$1))
- return false;
- if (dt.getMinutes() != parseFloat(RegExp.$2))
- return false;
- if (dt.getSeconds() != parseFloat(RegExp.$3))
- return false;
-
- return true;
- },
- "xsd:date": function(value){
- value = value.replace(/-/g, "/");
- value.match(/^(\d{2})\/(\d{2})\/(\d{4})$/);
- if (!RegExp.$3 || RegExp.$3.length < 4)
- return false;
-
- var dt = new Date(RegExp.$2 + "/" + RegExp.$1 + "/" + RegExp.$3); //@todo this is a dutch date, localization...
- if (dt.getFullYear() != parseFloat(RegExp.$3))
- return false;
- if (dt.getMonth() != parseFloat(RegExp.$2) - 1)
- return false;
- if (dt.getDate() != parseFloat(RegExp.$1))
- return false;
-
- return true;
- },
- "xsd:gYearMonth": function(value){
- value = value.replace(/-/g, "/");
- value.match(/^\/?(\d{4})(?:\d\d)?\/(\d{2})(?:\w|[\+\-]\d{2}:\d{2})?$/);
- if (!RegExp.$1 || RegExp.$1.length < 4)
- return false;
-
- var dt = new Date(value);
- if (dt.getFullYear() != parseFloat(RegExp.$))
- return false;
- if (dt.getMonth() != parseFloat(RegExp.$2) - 1)
- return false;
-
- return true;
- },
- "xsd:gYear": function(value){
- value.match(/^\/?(\d{4})(?:\d\d)?(?:\w|[\+\-]\d{2}:\d{2})?$/);
- if (!RegExp.$1 || RegExp.$1.length < 4)
- return false;
-
- var dt = new Date(value);
- if (dt.getFullYear() != parseFloat(RegExp.$1))
- return false;
-
- return true;
- },
- "xsd:gMonthDay": function(value){
- value = value.replace(/-/g, "/");
- value.match(/^\/\/(\d{2})\/(\d{2})(?:\w|[\+\-]\d{2}:\d{2})?$/);
-
- var dt = new Date(value);
- if (dt.getMonth() != parseFloat(RegExp.$1) - 1)
- return false;
- if (dt.getDate() != parseFloat(RegExp.$2))
- return false;
-
- return true;
- },
- "xsd:gDay": function(value){
- value = value.replace(/-/g, "/");
- value.match(/^\/{3}(\d{2})(?:\w|[\+\-]\d{2}:\d{2})?$/);
-
- var dt = new Date(value);
- if (dt.getDate() != parseFloat(RegExp.$1))
- return false;
-
- return true;
- },
- "xsd:gMonth": function(value){
- value = value.replace(/-/g, "/");
- value.match(/^\/{2}(\d{2})(?:\w|[\+\-]\d{2}:\d{2})?$/);
-
- var dt = new Date(value);
- if (dt.getMonth() != parseFloat(RegExp.$1) - 1)
- return false;
-
- return true;
- },
-
- //XSD datetypes
- "xsd:string": function(value){
- return typeof value == "string";
- },
- "xsd:boolean": function(value){
- return /^(true|false)$/i.test(value);
- },
- "xsd:base64Binary": function(value){
- return true;
- },
- "xsd:hexBinary": function(value){
- return /^(?:0x|x|#)?[A-F0-9]{0,8}$/i.test(value);
- },
- "xsd:float": function(value){
- return parseFloat(value) == value;
- },
- "xsd:decimal": function(value){
- return /^[0-9\.\-,]+$/.test(value);
- },
- "xsd:double": function(value){
- return parseFloat(value) == value;
- },
- "xsd:anyURI": function(value){
- return /^(?:\w+:\/\/)?(?:(?:[\w\-]+\.)+(?:[a-z]+)|(?:(?:1?\d?\d?|2[0-4]9|25[0-5])\.){3}(?:1?\d\d|2[0-4]9|25[0-5]))(?:\:\d+)?(?:\/([^\s\\\%]+|%[\da-f]{2})*)?$/i
- .test(value);
- },
- "xsd:QName": function(value){
- return true;
- },
- "xsd:normalizedString": function(value){
- return true;
- },
- "xsd:token": function(value){
- return true;
- },
- "xsd:language": function(value){
- return true;
- },
- "xsd:Name": function(value){
- return true;
- },
- "xsd:NCName": function(value){
- return true;
- },
- "xsd:ID": function(value){
- return true;
- },
- "xsd:IDREF": function(value){
- return true;
- },
- "xsd:IDREFS": function(value){
- return true;
- },
- "xsd:NMTOKEN": function(value){
- return true;
- },
- "xsd:NMTOKENS": function(value){
- return true;
- },
- "xsd:integer": function(value){
- return parseInt(value) == value;
- },
- "xsd:nonPositiveInteger": function(value){
- return parseInt(value) == value && value <= 0;
- },
- "xsd:negativeInteger": function(value){
- return parseInt(value) == value && value < 0;
- },
- "xsd:long": function(value){
- return parseInt(value) == value && value >= -2147483648
- && value <= 2147483647;
- },
- "xsd:int": function(value){
- return parseInt(value) == value;
- },
- "xsd:short": function(value){
- return parseInt(value) == value && value >= -32768 && value <= 32767;
- },
- "xsd:byte": function(value){
- return parseInt(value) == value && value >= -128 && value <= 127;
- },
- "xsd:nonNegativeInteger": function(value){
- return parseInt(value) == value && value >= 0;
- },
- "xsd:unsignedLong": function(value){
- return parseInt(value) == value && value >= 0 && value <= 4294967295;
- },
- "xsd:unsignedInt": function(value){
- return parseInt(value) == value && value >= 0;
- },
- "xsd:unsignedShort": function(value){
- return parseInt(value) == value && value >= 0 && value <= 65535;
- },
- "xsd:unsignedByte": function(value){
- return parseInt(value) == value && value >= 0 && value <= 255;
- },
- "xsd:positiveInteger": function(value){
- return parseInt(value) == value && value > 0;
- },
-
- //XForms datatypes
- "xforms:listItem": function(value){
- return true;
- },
- "xforms:listItems": function(value){
- return true;
- },
- "xforms:dayTimeDuration": function(value){
- return true;
- },
- "xforms:yearMonthDuration": function(value){
- return true;
- },
-
- //Javeline PlatForm datatypes
- "jpf:url": function(value){
- //@todo please make this better
- return /^\w+:\/\/([\w-]+\.)+\w{2,4}$/.test(value.trim());
- },
- "jpf:website": function(value){
- //@todo please make this better
- return /^(?:http:\/\/)?([\w-]+\.)+\w{2,4}$/.test(value.trim());
- },
- "jpf:email": function(value){
- return /^[A-Z0-9\.\_\%\-]+@(?:[A-Z0-9\-]+\.)+[A-Z]{2,4}$/i
- .test(value.trim());
- },
- "jpf:creditcard": function(value){
- value = value.replace(/ /g, "");
- value = value.pad(21, "0", jpf.PAD_LEFT);
- for (var total = 0, r, i = value.length; i >= 0; i--) {
- r = value.substr(i, 1) * (i % 2 + 1);
- total += r > 9 ? r - 9 : r;
- }
- return total % 10 === 0;
- },
- "jpf:expdate": function(value){
- value = value.replace(/-/g, "/");
- value = value.split("/");//.match(/(\d{2})\/(\d{2})/);
- var dt = new Date(value[0] + "/01/" + value[1]);
- //if(fulldate && dt.getFullYear() != parseFloat(value[1])) return false;
- if (dt.getYear() != parseFloat(value[1]))
- return false;//!fulldate &&
- if (dt.getMonth() != parseFloat(value[0]) - 1)
- return false;
-
- return true;
- },
- "jpf:wechars": function(value){
- return /^[0-9A-Za-z\xC0-\xCF\xD1-\xD6\xD8-\xDD\xDF-\xF6\xF8-\xFF -\.',]+$/
- .test(value)
- },
- "jpf:phonenumber": function(value){
- return /^[\d\+\- \(\)]+$/.test(value)
- },
- "jpf:faxnumber": function(value){
- return /^[\d\+\- \(\)]+$/.test(value)
- },
- "jpf:mobile": function(value){
- return /^[\d\+\- \(\)]+$/.test(value)
- }
- };
-
- var custumTypeHandlers = {};
-
- this.parse = function(xmlNode){
- if (xmlNode[jpf.TAGNAME] == "complextype")
- this.parseComplexType(xmlNode);
- else
- if (xmlNode[jpf.TAGNAME] == "simpletype")
- this.parseSimpleType(xmlNode);
- else {
- var i, nodes = $xmlns(xmlNode, "complextype", jpf.ns.xsd);
- for (i = 0; i < nodes.length; i++)
- this.parseComplexType(nodes[i]);
-
- nodes = $xmlns(xmlNode, "simpletype", jpf.ns.xsd);
- for (i = 0; i < nodes.length; i++)
- this.parseSimpleType(nodes[i]);
- }
- };
-
- this.getValue = function(xmlNode){
- return xmlNode.nodeType == 1
- ? jpf.getXmlValue(xmlNode, "text()")
- : xmlNode.nodeValue;
- };
-
- this.matchType = function(value, type){
- //check if type is type
- if (typeHandlers[type])
- return typeHandlers[type](value);
- return true;
- };
-
- this.parseComplexType = function(xmlNode){
- var func;
-
- custumTypeHandlers[xmlNode.getAttribute("name")] = func;
- };
-
- /* ***************** SIMPLE TYPES *******************/
-
- /*
- enumeration Defines a list of acceptable values
- fractionDigits Specifies the maximum number of decimal places allowed. Must be equal to or greater than zero
- length Specifies the exact number of characters or list items allowed. Must be equal to or greater than zero
- maxExclusive Specifies the upper bounds for numeric values (the value must be less than this value)
- maxInclusive Specifies the upper bounds for numeric values (the value must be less than or equal to this value)
- maxLength Specifies the maximum number of characters or list items allowed. Must be equal to or greater than zero
- minExclusive Specifies the lower bounds for numeric values (the value must be greater than this value)
- minInclusive Specifies the lower bounds for numeric values (the value must be greater than or equal to this value)
- minLength Specifies the minimum number of characters or list items allowed. Must be equal to or greater than zero
- pattern Defines the exact sequence of characters that are acceptable
- totalDigits Specifies the exact number of digits allowed. Must be greater than zero
- */
- var simpleTypeHandler = {
- //Direct childnodes
- "restriction": function(xmlNode, func){
- func.push("if (!jpf.XSDParser.matchType(value, '"
- + xmlNode.getAttribute("base") + "')) return false;");
-
- var nodes = xmlNode.childNodes;
- for (var i = 0; i < nodes.length; i++) {
- if (simpleTypeHandler[nodes[i][jpf.TAGNAME]])
- simpleTypeHandler[nodes[i][jpf.TAGNAME]](nodes[i], func);
- }
- },
-
- "list": function(xmlNode, func){},
-
- "union": function(xmlNode, func){},
-
- //Subnodes
- //These should also allow for dates
- "mininclusive": function(xmlNode, func){
- func.push("if (parseFloat(value) < " + xmlNode.getAttribute("value")
- + ") return false;");
- },
- "maxinclusive": function(xmlNode, func){
- func.push("if (parseFloat(value) > " + xmlNode.getAttribute("value")
- + ") return false;");
- },
- "minexclusive": function(xmlNode, func){
- func.push("if (parseFloat(value) => " + xmlNode.getAttribute("value")
- + ") return false;");
- },
- "maxexclusive": function(xmlNode, func){
- func.push("if (parseFloat(value) =< " + xmlNode.getAttribute("value")
- + ") return false;");
- },
- //This should also check for list items
- "maxlength": function(xmlNode, func){
- func.push("if (value.length > " + xmlNode.getAttribute("value")
- + ") return false;");
- },
- //This should also check for list items
- "minlength": function(xmlNode, func){
- func.push("if (value.length < " + xmlNode.getAttribute("value")
- + ") return false;");
- },
- //This should also check for list items
- "length": function(xmlNode, func){
- func.push("if (value.length != " + xmlNode.getAttribute("value")
- + ") return false;");
- },
- "fractiondigits": function(xmlNode, func){
- func.push("if (parseFloat(value) == value && value.split('.')[1].length != "
- + xmlNode.getAttribute("value") + ") return false;");
- },
- "totaldigits": function(xmlNode, func){
- func.push("if (new String(parseFloat(value)).length == "
- + xmlNode.getAttribute("value") + ") return false;");
- },
- "pattern": function(xmlNode, func){
- func.push("if (!/^" + xmlNode.getAttribute("value")
- .replace(/(\/|\^|\$)/g, "\\$1") + "$/.test(value)) return false;");
- },
- "enumeration": function(xmlNode, func){
- if (func.enum_done) return;
-
- var enum_nodes = $xmlns(xmlNode.parentNode, "enumeration", jpf.ns.xsd);
- func.enum_done = true;
- for (var re = [], k = 0; k < enum_nodes.length; k++)
- re.push(enum_nodes[k].getAttribute("value"));
- func.push("if (!/^(?:" + re.join("|") + ")$/.test(value)) return false;");
- },
- "maxscale": function(xmlNode, func){
- //http://www.w3.org/TR/2006/WD-xmlschema11-2-20060217/datatypes.html#element-maxScale
- },
- "minscale": function(xmlNode, func){
- //http://www.w3.org/TR/2006/WD-xmlschema11-2-20060217/datatypes.html#element-minScale
- }
- };
-
- this.parseSimpleType = function(xmlNode){
- var func = [];
- func.push("var value = jpf.XSDParser.getValue(xmlNode);");
-
- var nodes = xmlNode.childNodes;
- for (var i = 0; i < nodes.length; i++) {
- if (simpleTypeHandler[nodes[i][jpf.TAGNAME]])
- simpleTypeHandler[nodes[i][jpf.TAGNAME]](nodes[i], func);
- }
-
- func.push("return true;");
- custumTypeHandlers[xmlNode.getAttribute("name")] =
- new Function('xmlNode', func.join("\n"));
- };
-
- this.checkType = function(type, xmlNode){
- if (typeHandlers[type]) {
- var value = this.getValue(xmlNode);
- return typeHandlers[type](value);
- }
- else {
- if (custumTypeHandlers[type]) {
- return custumTypeHandlers[type](xmlNode);
- }
- else {
- //@todo MIKE: to be implemented?
- }
- }
- };
-};
-
-jpf.XSDParser = new jpf.XSDImplementation();
- - -/*FILEHEAD(/var/lib/jpf/src/core/parsers/js.js)SIZE(-1077090856)TIME(1226485886)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * Object returning an implementation of a JavaScript parser.
- *
- * @constructor
- * @parser
- *
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.9
- */
-jpf.JSImplementation = function(){
- //------------------------------------------------------------------------------------
-
- var types = ['[', '{', '(', 'text', 'xpath', 'word', 'sep', 'ws', 'semi', 'sh', 'op', 'col', 'str', 'regex', 'comment'];
- var closes = [']', '}', ')'];
- var reParse = new RegExp();
- reParse.compile("([\\w_\\.]+)|([\\s]*,[\\s]*)|([\\s]*;[\\s]*)|(\\/\\*)|(\\*\\/)|(\\/\\/)|([\\r\\n])|((?:[\\s]*)[\\$\\@\\#\\%\\^\\&\\*\\?\\!](?:[\\s]*))|([\\s]*[\\+\\-\\<\\>\\|\\=]+[\\s]*)|(\\s*\\:\\s*)|(\\s+)|(\\\\[\\\\\\{\\}\\[\\]\\\"\\'\\/])|(\\[)|(\\])|([\\s]*\\([\\s]*)|([\\s]*\\)[\\s]*)|([\\s]*\\{[\\s]*)|([\\s]*\\}[\\s]*)|(\\')|(\\\")|(\\/)", "g");
-
- //------------------------------------------------------------------------------------
-
- this.dump_tree = function(n, s, w){
- for (var i = 0; i < n.length; i++) {
- var m = n[i], t = m[0];
- if (t < 3) {
- s.push(w + types[t]);
- this.dump_tree(m[1], s, ' ' + w);
- s.push(closes[t]);
- s.push('\n');
- }
- else {
- s.push(w + types[t] + ': ' + m[1] + '\n');
- }
- }
- return s;
- };
-
- this.parse = function(str, trim_startspace){
- var err = []; // error list
- var tree = []; // parse tree
- var stack = []; // scopestack
- var node = tree;
- var blevel = 0, tpos = 0;
- var istr = 0, icc = 0;
- var lm = 0;
- var count = [0, 0, 0];
-
- //tokenize
- //return str;
- //str = str.replace(/\/\*[\s\S]*?\*\//gm,"");
- str.replace(reParse, function(m, word, sep, semi, c1, c2, c3, nl, sh,
- op, col, ws, bs1, bo, bc, po, pc, co, cc, q1, q2, re, pos){
- // stack helper functions
- function add_track(t){
- var txt = trim_startspace
- ? str.substr(tpos, pos - tpos)
- .replace(/[\r\n]\s*/, '').replace(/^\s*[\r\n]/, '')
- .replace(/[\r\n\t]/g, '')
- : str.substr(tpos, pos - tpos).replace(/[\r\n\t]/g, '');
- if (txt.length > 0) {
- node[node.length] = [t, txt, tpos, pos];
- }
- }
-
- function add_node(t, data){
- node[node.length] = [t, data, pos];
- }
-
- function add_sub(t){
- count[t]++;
- var n = [];
- node[node.length] = [t, n, pos];
- stack[stack.length] = node;
- node = n;
- }
-
- function pop_sub(t){
- count[t]--;
- if (stack.length == 0) {
- err[err.length] = ["extra " + closes[t], pos];
- }
- else {
- node = stack.pop();
- var ot = node[node.length - 1][0];
- if (ot != t) {
- err[err.length] = ["scope mismatch " + types[ot] + " with " + types[t], pos];
- }
- }
- }
-
- if (!istr) {
- if (word) {
- add_node(5, m);
- if (m == 'macro')
- lm = 1;
- else
- if (lm)
- macros[m] = 1, lm = 0;
- }
- if (sep)
- add_node(6, ',');
- if (ws)
- add_node(7, m);
- if (semi)
- add_node(8, m);
- if (sh)
- add_node(9, m);
- if (op)
- add_node(10, m);
- if (col)
- add_node(11, m);
- if (bo) {
- add_sub(0);
- }
- if (bc) {
- pop_sub(0);
- }
- if (co)
- add_sub(1);
- if (cc)
- pop_sub(1);
- if (po)
- add_sub(2);
- if (pc)
- pop_sub(2);
- }
- if (c3) {
- if (istr == 0) {
- istr = 5;
- tpos = pos + 2;
- }
- };
- if (nl) {
- if (istr == 5) {
- istr = 0;
- pos += 1;
- add_track(14);
- }
- }
- if (q1) {
- if (istr == 0) {
- istr = 1;
- tpos = pos;
- } else
- if (istr == 1) {
- istr = 0;
- pos += 1;
- add_track(12);
- }
- }
- if (q2) {
- if (istr == 0) {
- istr = 2;
- tpos = pos;
- } else
- if (istr == 2) {
- istr = 0;
- pos += 1;
- add_track(12);
- }
- }
- if (c1) {
- if (istr == 0) {
- istr = 4;
- tpos = pos + 2;
- };
- }
- if (c2) {
- if (istr == 4) {
- istr = 0;
- add_track(14);
- }
- }
- if (re) {
- if (istr == 0) {
- // only allow regex mode if we have no previous siblings or we have a , before us
- if (node.length == 0 || node[node.length - 1][0] == 6) {
- istr = 3;
- tpos = pos;
- } else
- add_node(10, m);
- }
- else
- if (istr == 3) {
- istr = 0;
- pos += 1;
- add_track(13);
- }
- }
- return m;
- });
- //return parse tree
- if (stack.length > 0)
- for (var i = stack.length - 1; i >= 0; i--) {
- var j = stack[i][stack[i].length - 1];
- err[err.length] = ["unclosed tag " + types[j[0]], j[2]];
- }
- return {
- 'tree' : tree,
- 'stack': stack,
- 'err' : err,
- 'count': count
- };
- };
-};
-jpf.JavascriptParser = new jpf.JSImplementation();
-
- - -/*FILEHEAD(/var/lib/jpf/src/core/parsers/jslt.js)SIZE(-1077090856)TIME(1238933672)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-//eval("var x = function(a){" + "alert(ruben)" + "}");
-
-/**
- * Object returning an implementation of an JSLT parser.
- * @todo Rik: please document this one extensively!
- *
- * Note: you cannot declare a variable with name node it is a deserved word
- *
- * @constructor
- * @parser
- *
- * @author Rik Arends
- * @version %I%, %G%
- * @since 0.9
- */
-jpf.JsltImplementation = function(){
- //@todo compile this one please!
- var bigRegExp = /([\w_\.]+)|(\s*,\s*)|(\s*;\s*)|((?:\s*)[\$\@\#\%\^\&\*\?\!](?:\s*))|(\s*[\+\-\<\>\|\=]+\s*)|(\s*\:\s*)|(\\[\\\{\}\[\]\"\'\/])|(\[)|(\])|(\s*\(\s*)|(\s*\)\s*)|(\s*\{\s*)|(\s*\}\s*)|(\')|(\")|(\/)|(\s+)/g;
-
- //------------------------------------------------------------------------------------
- // compile functions
- function isString(){
- if (typeof arguments[0] == 'string')
- return true;
- if (typeof arguments[0] == 'object' && arguments[0].constructor)
- return (arguments[0].constructor.toString().match(/string/i) != null);
- return false;
- }
-
- function jesc(s, esc){
- if (!esc)
- return s;
- if (!s)
- return '';
- if (esc.toLowerCase() == 'q')
- return s.replace(/&/g, "&").replace(/\'/g, "\\&squot")
- .replace(/\"/g, "\\"").replace(/\r?\n/g, "\\n");
- return s;
- }
-
- function jcpy(s, n, p){
- if (!n)
- return;
- if (p) {
-
- try {
- var t = n.selectNodes(p);
- } catch(e) {
- throw new Error(jpf.formatErrorString(0, this,
- "Selecting node for 'copy' JSLT ",
- "unxpected character in xpath \n" + e.message + "'"));
- }
-
- if (!t || t.length == 0)
- return;
- for (var i = 0; i < t.length; i++)
- s[s.length] = t[i].xml;
- }
- else
- s[s.length] = n.xml;
- }
-
- function jxml(n, p){
- if (!n)
- return;
- if (p) {
- var o = [];
-
- try {
- var t = n.selectNodes(p);
- } catch(e) {
- throw new Error(jpf.formatErrorString(0, this,
- "Selecting node for 'xml' JSLT ",
- "unxpected character in xpath \n" + e.message + "'"));
- }
-
- if (!t || t.length == 0)
- return;
- for (var i = 0; i < t.length; i++)
- o[o.length] = t[i].xml;
- }
- else
- return n.xml;
- return o.join('');
- }
-
- function jval(n, p){
- if (!n)
- return '';
-
- if (p) {
- try {
- n = n.selectSingleNode(p);
- } catch(e) {
- throw new Error(jpf.formatErrorString(0, this,
- "Selecting node in JSLT",
- "unxpected character in xpath \n" + e.message + "'"));
- }
- }
-
-
- if (!n)
- return '';
- if (n.nodeType == 1)
- n = n.firstChild;
- return n ? n.nodeValue : '';
- }
-
- function jloc(n, f, p){
- if (!n || !p)
- return;
- n = isString(p) ? n.selectSingleNode(p) : p;
- if (!n)
- return;
- f(n);
- }
-
- function jdbg(a){
- jpf.console.info(a)
- }
-
- function jnod(n, p){
- if (!n)
- return '';
- if (p) {
- try {
- n = n.selectSingleNode(p);
- } catch(e) {
- throw new Error(jpf.formatErrorString(0, this,
- "Selecting node in JSLT ",
- "unxpected character in xpath \n" + e.message + "'"));
- }
- }
- if (!n)
- return null;
- return n;
- }
-
- function jnds(n, p){
- if (!n)
- return '';
- if (p) {
- try {
- n = n.selectNodes(p);
- } catch(e) {
- throw new Error(jpf.formatErrorString(0, this,
- "Selecting nodes in JSLT ",
- "unxpected character in xpath \n" + e.message + "'"));
- }
- }
- if (!n)
- return null;
- return n;
- }
-
- function jexs(n, p){
- if (!n)
- return false;
- if (p) {
- try {
- n = n.selectSingleNode(p);
- } catch(e) {
- throw new Error(jpf.formatErrorString(0, this,
- "Selecting a node to check if it 'exists' in JSLT ",
- "unxpected character in xpath \n" + e.message + "'"));
- }
- }
- return n != null;
- }
-
- function jemp(n, p){
- if (!n)
- return false;
- if (p) {
- try {
- n = n.selectSingleNode(p);
- } catch(e) {
- throw new Error(jpf.formatErrorString(0, this,
- "Selecting a node to check if is 'empty' JSLT ",
- "unxpected character in xpath \n" + e.message + "'"));
- }
- }
- if (!n)
- return true;
- if (n.nodeType == 1)
- n = n.firstChild;
- return (n ? n.nodeValue : '').match(/^[\s\r\n\t]*$/) != null;
- }
-
- function jcnt(n, p){
- if (!n)
- return 0;
-
- try {
- var t = n.selectNodes(p);
- } catch(e) {
- throw new Error(jpf.formatErrorString(0, this,
- "Selecting nodes for 'count' JSLT ",
- "unxpected character in xpath \n" + e.message + "'"));
- }
-
- return t ? t.length : 0;
- }
-
- function jpak(n, f, p){
- var s = [];
- f(s, n);
- return s.join('');
- }
-
- function jstore(n, pk, f, p){
- if (!p)
- p = 'def';
- if (!pk[p])
- pk[p] = [];
- f(pk[p], n);
- return;
- }
-
- function jfetch(pk, p){
- if (!p)
- p = 'def';
- if (pk[p])
- return pk[p].join('');
- return '';
- }
-
- function jfra(f, t, sp, ep){
- if (!t)
- return;
- var end = ep == null ? t.length : Math.min(t.length, (sp + ep));
- for (var i = (sp == null) ? 0 : sp; i < end; i++)
- f(i, end, t[i]);
- }
-
- function jvls(n, p){
- var r = [];
- if (!n)
- return r;
-
- try {
- var t = n.selectNodes(p);
- } catch(e) {
- throw new Error(jpf.formatErrorString(0, this,
- "Selecting nodes for 'values' JSLT ",
- "unxpected character in xpath \n" + e.message + "'"));
- }
-
- if (!t)
- return r;
- for (var i = 0; i < t.length; i++) {
- n = t[i];
- if (n.nodeType == 1)
- n = n.firstChild;
- r[i] = n ? n.nodeValue : '';
- }
- return r;
- }
-
- function jpar(f, str){
- f ((typeof str != "string")
- ? str
- : parseXML(str).documentElement);
- }
-
- function jfor(n, f, p, sp, ep){
- if (!n)
- return;
-
- try {
- var t = n.selectNodes(p);
- } catch(e) {
- throw new Error(jpf.formatErrorString(0, this,
- "Selecting nodes in 'foreach' JSLT ",
- "unxpected character in xpath \n" + e.message + "'"));
- }
-
-
- var end = ep == null ? t.length : Math.min(t.length, (sp + ep));
- for (var i = (sp == null) ? 0 : sp; i < end; i++)
- f(i, end, t[i]);
- }
-
- // Sorting helpers
- var sort_intmask = ["", "0", "00", "000", "0000", "00000", "000000",
- "0000000", "00000000", "000000000", "0000000000", "00000000000",
- "000000000000", "0000000000000", "00000000000000"];
- var sort_dateFmtStr;
- var sort_dateFormat;
- var sort_dateReplace;
- function sort_dateFmt(str){
- sort_dateFmtStr = str;
- var result = str.match(/(D+|Y+|M+|h+|m+|s+)/g);
- if (!result)
- return;
- for (var pos = {}, i = 0; i < result.length; i++)
- pos[result[i].substr(0, 1)] = i + 1;
- sort_dateFormat = new RegExp(str.replace(/[^\sDYMhms]/g, '\\$1')
- .replace(/YYYY/, "(\\d\\d\\d\\d)")
- .replace(/(DD|YY|MM|hh|mm|ss)/g, "(\\d\\d)"));
- sort_dateReplace = "$" + pos["M"] + "/$" + pos["D"] + "/$" + pos["Y"];
- if (pos["h"])
- sort_dateReplace += " - $" + pos["h"] + ":$" + pos["m"] + ":$" + pos["s"];
- }
-
- // Sorting methods for sort()
- function sort_alpha(n){
- if (!n)
- return '';
- if (n.nodeType == 1)
- n = n.firstChild;
- return n ? n.nodeValue : '';
- }
-
- function sort_number(n){
- var t = sort_alpha(n);
- return (t.length < sort_intmask.length
- ? sort_intmask[sort_intmask.length - t.length]
- : "") + t;
- }
-
- function sort_date(n, args){
- if (!sort_dateFormat || (args && sort_dateFmtStr != args[0]))
- sort_dateFmt(args ? args[0] : "*");
- var t = sort_alpha(n), d;
- if (sort_dateFmtStr == '*')
- d = Date.parse(t);
- else
- d = (new Date(t.replace(sort_dateFormat, sort_dateReplace))).getTime();
- t = "" + parseInt(d);
- if (t == "NaN")
- t = "0";
- return (t.length < sort_intmask.length
- ? sort_intmask[sort_intmask.length - t.length]
- : "") + t;
- }
-
- function jsort(n, f, p, ps, sm, desc, sp, ep){
- sm = sm ? sm : sort_alpha;
- var sa = [], t = n.selectNodes(p), i = t.length, args = null;
- if (typeof sm != "function") {
- var m = sm.shift();
- args = sm;
- sm = m;
- }
-
- // build string-sortable list with sort method
- while (i--) {
- n = t[i].selectSingleNode(ps);
- if (n)
- sa[sa.length] = {
- toString: function(){
- return this.v;
- },
- pn: t[i],
- v: sm(n, args)
- };
- else
- sa[sa.length] = {
- toString: function(){
- return this.v;
- },
- pn: t[i],
- v: ''
- };
- }
- // sort it
- sa.sort();
-
- //iterate like foreach
- var end = ep == null ? sa.length : Math.min(sa.length, (sp + ep));
- var start = (sp == null) ? 0 : sp;
- if (desc) {
- for (i = end - 1; i >= start; i--)
- f(end - i - 1, end, sa[i].pn, sa[i].v);
- }
- else {
- for (i = start; i < end; i++)
- f(i, end, sa[i].pn, sa[i].v);
- }
- }
-
- function japl(s, n, ma, p){
- if (!n)
- return;
- var m = n.selectNodes(p || 'node()');
- for (var i = 0; i < m.length; i++) {
- n = m[i];
- var f = ma[0][n.tagName];
- if (f)
- f(s, n);
- else {
- for (var k = 1; k < ma.length; k++) {
- var sn = n.selectSingleNode(ma[k][0]);
- if (sn) {
- ma[k][1](s, sn);
- break;
- }
- }
- }
- }
- }
-
- function jmat(ma, f, p){
- var s = p.split(/\|/), all = true;
- for (var i = 0; i < s.length; i++) {
- if (!s[i].match(/^[\w_]+$/))
- all = false;
- ma[0][s[i]] = f;
- }
- if (!all) {
- p = "self::" + p.replace(/\|/g, "|self::");
- ma[ma.length] = [p, f];
- }
- }
-
- function joff(n){
- for (var p = n.parentNode.childNodes, i = p.length-1; i>=0; i--)
- if (p[i] == n)
- return i;
- return '';
- }
-
- //------------------------------------------------------------------------------------
-
- var types = ['[', '{', '(', 'text', 'xpath', 'word', 'sep', 'ws', 'semi',
- 'sh', 'op', 'col', 'str', 'regex'];
- var closes = [']', '}', ')'];
-
- var func = {
- 'last' : [0, '(i==len-1)'],
- 'first' : [0, '(i==0)'],
- 'offset' : [0, 'joff(n)'],
- 'out' : [0, 's[s.length]'],
- 'apply' : [1, ';japl(s,n,ma,', ');'],
- 'copy' : [1, ';jcpy(s,n,', ');'],
- 'xml' : [1, 'jxml(n,', ')'],
- 'value' : [1, 'jval(n,', ')'],
- 'exists' : [1, 'jexs(n,', ')'],
- 'empty' : [1, 'jemp(n,', ')'],
- 'values' : [1, 'jvls(n,', ')'],
- 'node' : [1, 'jnod(n,', ')'],
- 'nodes' : [1, 'jnds(n,', ')'],
- 'count' : [1, 'jcnt(n,', ')'],
- 'context' : [1, '(n=n.selectSingleNode(', '))'],
- 'foreach' : [2, ';jfor(n,function(i,len,n){', '},', ');'],
- 'sort' : [2, ';jsort(n,function(i,len,n,sv){', '},', ');'],
- 'local' : [2, ';jloc(n,function(n){', '},', ');'],
- 'match' : [2, ';jmat(ma,function(s,n){', '},', ');'],
- 'pack' : [2, 'jpak(n,function(s,n){', '},', ')'],
- 'store' : [2, 'jstore(n,os,function(s,n){', '},', ');'],
- 'fetch' : [1, 'jfetch(os,', ')'],
-
- 'parse' : [2, 'jpar(function(n){', '},', ');'],
- 'forarray': [3],
- 'macro' : [4],
- 'pragma' : [5],
- '_' : [6]
- };
- // s,n,i,len
-
- var short_0 = {
- '%': 's[s.length]='
- };
- var short_1 = {
- '$': ['jval(n,', ')'],
- '&': ['jnod(n,', ')'],
- '@': ['(n=n.selectSingleNode(', '))'],
- '~': ['jexs(n,', ')'],
- '!': ['!jexs(n,', ')'],
- '#': ['jcnt(n,', ')'],
- '^': [';japl(s,n,ma,', ');']
- };
- var short_2 = {
- '*': [';jfor(n,function(i,len,n){', '},', ')']
- };
-
- //------------------------------------------------------------------------------------
-
- function dump_tree(n, s, w){
- for (var i = 0; i < n.length; i++) {
- var m = n[i], t = m[0];
- if (t < 3) {
- s.push(w + types[t]);
- dump_tree(m[1], s, ' ' + w);
- s.push(closes[t]);
- s.push('\n');
- } else {
- s.push(w + types[t] + ': ' + m[1] + '\n');
- }
- }
- }
-
- this.jslt_inline = [];
-
- this.compile = function(str, trim_startspace){
- var pre;
-
- if (pre=str.match(/^var s\=\[(\d*)\]/)){
- if (pre[1] != '')
- return [this.jslt_inline[pre[1]], str];
-
- try {
- eval("var f = function(n){" + str + "};");
- } catch(e) {
- jpf.console.info(jpf.formatJS(str));
- throw new Error(jpf.formatErrorString(0, this,
- "Selecting node in JSLT",
- "Could not parse Precompiled JSLT with: \n" + e.message + "'"));
- }
-
-
- return [f, str];
- }
-
- var err = []; // error list
- var tree = []; // parse tree
- var stack = []; // scopestack
- var node = tree;
- var blevel = 0, tpos = 0;
- var istr = 0, icc = 0;
- var lm = 0;
- var macros = {};
- //tokenize
- str = str.replace(/\/\*[\s\S]*?\*\//gm, "");
- str.replace(bigRegExp,
- function(m, word, sep, semi, sh, op, col, bs1, bo, bc, po, pc, co, cc, q1, q2, re, ws, pos){
- // stack helper functions
- function add_track(t){
- var txt = trim_startspace ? str.substr(tpos, pos - tpos).replace(/[\r\n]\s*/, '').replace(/^\s*[\r\n]/, '').replace(/\\s/g, ' ').replace(/[\r\n\t]/g, '') : str.substr(tpos, pos - tpos).replace(/[\r\n\t]/g, '');
- if (txt.length > 0) {
- node[node.length] = [t, txt, tpos, pos];
- }
- }
-
- function add_node(t, data){
- node[node.length] = [t, data, pos];
- }
-
- function add_sub(t){
- var n = [];
- node[node.length] = [t, n, pos];
- stack[stack.length] = node;
- node = n;
- }
-
- function pop_sub(t){
- if (stack.length == 0) {
- err[err.length] = ["extra " + closes[t], pos];
- }
- else {
- node = stack.pop();
- var ot = node[node.length - 1][0];
- if (ot != t) {
- err[err.length] = ["scope mismatch " + types[ot] + " with " + types[t], pos];
- }
- }
- }
-
- // are we in textmode or entering textmode?
- if (blevel == 0 || (bc && blevel == 1 && !istr)) {
- if (icc == 0) {
- if (bo) {
- add_track(3);
- blevel++;
- } // begin codeblock
- if (bc) {
- if (blevel == 0)
- err[err.length] = ["extra ]", pos];
- else {
- blevel--;
- tpos = pos + 1;
- }
- } // end codeblock
- }
- if (co) {
- pos+=co.indexOf('{');
- add_track(3);
- tpos = pos + 1;
- icc++;
- } // add last text chunk
- if (cc) {
- add_track(4);
- tpos = pos + cc.indexOf('}') + 1;
- icc--;
- if (icc < 0)
- err[err.length] = ["extra }", pos];
- } // xpath chunk
- }
- else {
- if (!istr) {
- if (word) {
- add_node(5, m);
- if (m == 'macro')
- lm = 1;
- else
- if (lm)
- macros[m] = 1, lm = 0;
- }
- if (sep)
- add_node(6, ',');
- if (ws)
- add_node(7, m);
- if (semi)
- add_node(8, m);
- if (sh)
- add_node(9, m);
- if (op)
- add_node(10, m);
- if (col)
- add_node(11, m);
- if (bo) {
- blevel++;
- add_sub(0);
- }
- if (bc) {
- blevel--;
- pop_sub(0);
- }
- if (co)
- add_sub(1);
- if (cc)
- pop_sub(1);
- if (po)
- add_sub(2);
- if (pc)
- pop_sub(2);
- }
- if (q1) {
- if (istr == 0) {
- istr = 1;
- tpos = pos;
- }
- else
- if (istr == 1) {
- istr = 0;
- pos += 1;
- add_track(12);
- }
- }
- if (q2) {
- if (istr == 0) {
- istr = 2;
- tpos = pos;
- }
- else
- if (istr == 2) {
- istr = 0;
- pos += 1;
- add_track(12);
- }
- }
- if (re) {
- if (istr == 0) {
- // only allow regex mode if we have no previous siblings or we have a , before us
- if (node.length == 0 || node[node.length - 1][0] == 6) {
- istr = 3;
- tpos = pos;
- } else
- add_node(10, m);
- }
- else
- if (istr == 3) {
- istr = 0;
- pos += 1;
- add_track(13);
- }
- }
- }
- return m;
- });
- if (blevel == 0) {
- var txt = str.substr(tpos, str.length - tpos).replace(/[\r\n\t]/g, '');
- if (txt.length > 0) {
- node[node.length] = [3, txt, tpos, str.length];
- }
- }
- if (stack.length > 0)
- for (var i = stack.length - 1; i >= 0; i--) {
- var j = stack[i][stack[i].length - 1];
- err[err.length] = ["unclosed tag " + types[j[0]], j[2]];
- }
-
- var s = ['var s=[],ma=[{}],os={};'];
-
- var pragma_trace = 0;
- function line_pos(cpos){
- var l = 0;
- str.replace(/\n/g, function(m, pos){
- if (pos < cpos)
- l++;
- return m;
- });
- return l;
- }
-
- //recursive compile
- function compile_recur(s, n, offset){
-
- var k = n.length;
- var d, e;
- // var lt=14;
- for (var i = ((offset == null) ? 0 : offset); i < k; i++) {
- var t = n[i][0];
- // function expansion
- if (t == 5) {
- var nt1 = (i < k - 1) ? n[i + 1][0] : -1, nt2 = (i < k - 2) ? n[i + 2][0] : -1;
- var m = n[i][1];
- var d = func[m];
- // also dont insert ;'s
- if (d) {
- switch (d[0]) {
- case 0:
- s[s.length] = d[1];
- break;
- case 1: // () type function
- if (nt1 != 2) {
- err[err.length] = ["Function " + m + " syntax error", n[i][2]];
- }
- else {
- s[s.length] = d[1];
- if (!compile_recur(s, n[i + 1][1]))
- s[s.length] = 'null';
- s[s.length] = d[2];
- i++;
- }
- break;
- case 2: // () {} type function
- if (nt1 != 2 || nt2 != 1) {
- err[err.length] = ["Function " + m + " syntax error", n[i][2]];
- }
- else {
- s[s.length] = d[1];
- compile_recur(s, n[i + 2][1]);
- s[s.length] = d[2];
- if (!compile_recur(s, n[i + 1][1]))
- s[s.length] = 'null';
- s[s.length] = d[3];
- i += 2;
- }
- break;
- case 3://forarray
- //we should have ( word ws in .... , .. , .. ) {}
- var o, ok;
- if (i > k - 3 || n[i + 1][0] != 2 || n[i + 2][0] != 1 || (o = n[i + 1][1])[0][0] != 5 ||
- (ok = o.length) < 5 ||
- o[1][0] != 7 ||
- o[2][0] != 5 ||
- o[2][1] != 'in') {
- err[err.length] = ["forarray syntax error", n[i][2]];
- }
- else {
- s[s.length] = ';jfra(function(i,len,' + o[0][1] + '){';
- compile_recur(s, n[i + 2][1]);
- s[s.length] = '},';
- compile_recur(s, o, 3);
- s[s.length] = ');';
- i += 2;
- }
- break;
- case 4://macro
- //we should have ws, word, quote, code
- if (i >= k - 4 || n[i + 1][0] != 7 || n[i + 2][0] != 5 || n[i + 3][0] != 2 || n[i + 4][0] != 1) {
- err[err.length] = ["macro syntax error at", n[0][2]];
- }
- else {
- s[s.length] = 'function ' + n[i + 2][1] + '(s,n,';
- if (!compile_recur(s, n[i + 3][1]))
- s[s.length] = 'null';
- s[s.length] = '){';
- compile_recur(s, n[i + 4][1]);
- s[s.length] = '}';
- i += 4;
- }
- break;
- case 5://pragma
- {
- if (i >= k - 3 || n[i + 1][0] != 7 || n[i + 2][0] != 5 || n[i + 3][0] != 2) {
- err[err.length] = ["macro syntax error at", n[0][2]];
- }
- else {
- switch (n[i + 2][1]) {
- case 'trace':{
- var ts = [];
- compile_recur(ts, n[i + 3][1]);
- pragma_trace = eval(ts.join(''));
- }
- break;
- }
- }
- i += 3;
- }
- case 6://trace
- {
- s[s.length] = ';alert("Trace: ' + line_pos(n[i][2]) + '");';
- }
- }
- }
- else {
- if (macros[m] && nt1 == 2) {
- s[s.length] = m + '(s,n,';
- if (!compile_recur(s, n[i + 1][1]))
- s[s.length] = 'null';
- s[s.length] = ')';
- i++;
- }
- else
- s[s.length] = m;
- }
- // check our type
- }
- else //shorthand expansion
- if (t == 9) {
- var nt1 = (i < k - 1) ? n[i + 1][0] : -1, nt2 = (i < k - 2) ? n[i + 2][0] : -1;
- var m = n[i][1];
-
- if (nt1 == 12) {
- if (nt2 == 1) {
- if (d = short_2[m]) {
- s[s.length] = d[0];
- compile_recur(s, n[i + 2][1]);
- s[s.length] = d[1] + n[i + 1][1] + d[2];
- i += 2;
- lt = 1;
- } else
- s[s.length] = m;
- }
- else {
- if (d = short_1[m]) {
- if (nt2 == 11)
- s[s.length] = m;
- else {
- s[s.length] = d[0] + n[i + 1][1] + d[1];
- i++;
- }
- } else {
- if (d = short_0[m])
- s[s.length] = d;
- else
- s[s.length] = m;
- }
- }
- }
- else {
- if (d = short_0[m])
- s[s.length] = d;
- else
- s[s.length] = m;
- }
- }
- else { // normal add
- if (t < 3) {
- s[s.length] = types[t];
- compile_recur(s, n[i][1]);
- s[s.length] = closes[t];
-
- // ; insertion code
- if ((t == 1 && i < k - 1 && n[i + 1][0] == 5 && n[i + 1][1] != 'else') || // }word
- (t == 2 && i < k - 1 && n[i + 1][0] == 5 && !n[i + 1][1].match(/^\./) && // )word
- (i == 0 || n[i - 1][0] != 5 || !n[i - 1][1].match(/^(if|for)$/)))) {
- s[s.length] = ';';
- }
- }
- else {
- if (t == 3)
- s[s.length] = ';s[s.length]="' + n[i][1]
- .replace(/\"/g, "\\\"").replace(/\n/g, "\\n") + '";';
- else
- if (t == 4) {
- var m = n[i][1].match(/^\^([\w])\s?/);
- if (m) {
- s[s.length] = ';s[s.length]=jesc(jval(n,"'
- + n[i][1].substr(2)
- .replace(/"/g, "\\\"") + '"),"' + m[1] + '");';
- } else {
- s[s.length] = ';s[s.length]=jval(n,"'
- + n[i][1].replace(/"/g, "\\\"") + '");';
- }
- }
- else
- s[s.length] = n[i][1];
- }
- }
- //lt = n[i][0];
- }
- return k;
- }
- if (err.length == 0)
- compile_recur(s, tree);
-
- // return all parse errors
- if (err.length > 0) {
- var e = [];
- for (var i = 0; i < err.length; i++) {
- e[e.length] = 'Parse error(' + line_pos(err[i][1]) + '): ' + err[i][0] + '\n';
- }
- // lets spit out our parse tree
-
- //var out=[];
- //dump_tree(tree,out,'');
-
- throw new Error("Could not parse JSLT with: " + e.join('') + "\n");
- }
-
- s[s.length] = ";return s.join('');";
- var strJS = s.join('');
-
- try {
- eval("var f = function(n){" + strJS + "};");
- }
- catch (e) {
- //var treedump=[];
- //dump_tree(tree,treedump,'');
- jpf.console.info(jpf.formatJS(strJS));
- throw new Error("Could not parse JSLT with: " + e.message /*+ "\n" + treedump.join('')*/);
- }
-
- return [f, strJS];
- };
-
- /* ***********************************************
- //you can interchange nodes and strings
- apply(jsltStr, xmlStr);
- apply(jsltNode, xmlNode);
-
- returns string or false
- ************************************************/
- this.cache = [];
-
- this.apply = function(jsltNode, xmlNode){
- var jsltFunc, cacheId, jsltStr, doTest;
-
- //Type detection xmlNode
- xmlNode = jpf.xmldb.getBindXmlNode(xmlNode);
-
- //Type detection jsltNode
- if (typeof jsltNode == "object") {
- doTest = jpf.isTrue(jsltNode.getAttribute("test"));
-
- //check the jslt node for cache setting
- cacheId = jsltNode.getAttribute("cache");
- jsltFunc = this.cache[cacheId];
- if (!jsltFunc) {
- var jsltStr = [], textNodes = jsltNode.selectNodes('text()');
- for (var i = 0; i < textNodes.length; i++) {
- jsltStr = textNodes[i].nodeValue;
- if (jsltStr.trim())
- break;
- }
- }
- }
- else {
- cacheId = jsltNode;
- jsltFunc = this.cache[cacheId];
- if (!jsltFunc) {
- jsltStr = jsltNode;
- cacheId = null;
- }
- }
-
- //Compile string
- if (!jsltFunc)
- jsltFunc = this.compile(jsltStr);
-
- this.lastJslt = jsltStr;
- this.lastJs = jsltFunc[0]; //if it crashes here there is something seriously wrong
-
- //Invalid code - Syntax Error
- if (!jsltFunc[0])
- return false;
-
- //Caching
- if (!cacheId) {
- if (typeof jsltNode == "object") {
- cacheId = this.cache.push(jsltFunc) - 1
- jsltNode.setAttribute("cache", cacheId);
- }
- else
- this.cache[jsltStr] = jsltFunc;
- }
-
- //Execute JSLT
- if (!xmlNode)
- return '';
-
- var str = jsltFunc[0](xmlNode);
- if (doTest)
- jpf.getObject("XMLDOM", "<root>" + str.replace(/>/g, ">\n") + "</root>");
- return str;
- };
-};
-jpf.JsltInstance = new jpf.JsltImplementation();
-
- - -/*FILEHEAD(/var/lib/jpf/src/core/parsers/xpath.js)SIZE(-1077090856)TIME(1238933672)*/ - -jpf.runXpath = function(){
-
-/**
- * Workaround for the lack of having an XPath parser on safari
- * It works on Safari's document and XMLDocument object.
- *
- * It doesn't support the full XPath spec, but just enought for
- * the skinning engine which needs XPath on the HTML document.
- *
- * Supports:
- * - Compilation of xpath statements
- * - Caching of XPath statements
- *
- * @parser
- * @private
- */
-jpf.XPath = {
- cache : {},
-
- getSelf : function(htmlNode, tagName, info, count, num, sResult){
- var numfound = 0, result = null, data = info[count];
-
- if (data)
- data[0](htmlNode, data[1], info, count + 1, numfound++ , sResult);
- else
- sResult.push(htmlNode);
- },
-
- getChildNode : function(htmlNode, tagName, info, count, num, sResult){
- var numfound = 0, result = null, data = info[count];
-
- var nodes = htmlNode.childNodes;
- if (!nodes) return; //Weird bug in Safari
- for (var i = 0; i < nodes.length; i++) {
- if (nodes[i].nodeType != 1)
- continue;
-
- if (tagName && (tagName != nodes[i].tagName) && (nodes[i].style
- ? nodes[i].tagName.toLowerCase()
- : nodes[i].tagName) != tagName)
- continue;// || numsearch && ++numfound != numsearch
- htmlNode = nodes[i];
-
- if (data)
- data[0](nodes[i], data[1], info, count + 1, numfound++ , sResult);
- else
- sResult.push(nodes[i]);
- }
-
- //commented out : && (!numsearch || numsearch == numfound)
- },
-
- doQuery : function(htmlNode, qData, info, count, num, sResult){
- var result = null, data = info[count];
- var query = qData[0];
- var returnResult = qData[1];
- try {
- var qResult = eval(query);
- }catch(e){
- //jpf.console.error(e.name + " " + e.type + ":" + jpf.XPath.lastExpr + "\n\n" + query);
- return;
- }
-
- if (returnResult)
- return sResult.push(qResult);
- if (!qResult || qResult.dataType == "array" && !qResult.length)
- return;
-
- if (data)
- data[0](htmlNode, data[1], info, count + 1, 0, sResult);
- else
- sResult.push(htmlNode);
- },
-
- getTextNode : function(htmlNode, empty, info, count, num, sResult){
- var result = null, data = info[count];
-
- var nodes = htmlNode.childNodes;
- for (var i = 0; i < nodes.length; i++) {
- if (nodes[i].nodeType != 3 && nodes[i].nodeType != 4)
- continue;
-
- if (data)
- data[0](nodes[i], data[1], info, count + 1, i, sResult);
- else
- sResult.push(nodes[i]);
- }
- },
-
- getAnyNode : function(htmlNode, empty, info, count, num, sResult){
- var result = null, data = info[count];
-
- var sel = [], nodes = htmlNode.getElementsByTagName("*");//childNodes;
- for (var i = 0; i < nodes.length; i++) {
- if (data)
- data[0](nodes[i], data[1], info, count + 1, i, sResult);
- else
- sResult.push(nodes[i]);
- }
- },
-
- getAttributeNode : function(htmlNode, attrName, info, count, num, sResult){
- if (!htmlNode || htmlNode.nodeType != 1) return;
-
- if (attrName == "*") {
- var nodes = htmlNode.attributes;
- for (var i = 0; i < nodes.length; i++) {
- arguments.callee.call(this, htmlNode, nodes[i].nodeName, info, count, i, sResult);
- }
- return;
- }
-
- var result = null, data = info[count];
- var value = htmlNode.getAttributeNode(attrName);//htmlNode.attributes[attrName];//
-
- if (data)
- data[0](value, data[1], info, count + 1, 0, sResult);
- else if (value)
- sResult.push(value);
- },
-
- getAllNodes : function(htmlNode, x, info, count, num, sResult){
- var result = null, data = info[count];
- var tagName = x[0];
- var inclSelf = x[1];
- var prefix = x[2];
-
- if (inclSelf && (htmlNode.tagName == tagName || tagName == "*")) {
- if (data)
- data[0](htmlNode, data[1], info, count + 1, 0, sResult);
- else
- sResult.push(htmlNode);
- }
-
- if (tagName == "node()") {
- tagName = "*";
- prefix = "";
- if (jpf.isIE)
- var nodes = htmlNode.getElementsByTagName("*");
- else {
- var nodes = [];
- (function recur(x){
- for (var n, i = 0; i < x.childNodes.length; i++) {
- n = x.childNodes[i];
- if (n.nodeType != 1)
- continue;
- nodes.push(n);
- //@todo please dont seg fault, you mf
- if (n.tagName != "skin" && n.tagName != "jslt" && n.tagName != "ref" && n.parentNode.tagName != "bindings")
- recur(n);
- }
- })(htmlNode);
- }
- }
- else {
- var nodes = htmlNode.getElementsByTagName((prefix
- && (jpf.isGecko || jpf.isOpera) ? prefix + ":" : "") + tagName);
- }
-
- for (var i = 0; i < nodes.length; i++) {
- if (data)
- data[0](nodes[i], data[1], info, count + 1, i, sResult);
- else
- sResult.push(nodes[i]);
- }
- },
-
- getAllAncestorNodes : function(htmlNode, x, info, count, num, sResult){
- var result = null, data = info[count];
- var tagName = x[0];
- var inclSelf = x[1];
- var prefix = x[2];
-
- var i = 0, s = inclSelf ? htmlNode : htmlNode.parentNode;
- while (s && s.nodeType == 1) {
- if (s.tagName == tagName || tagName == "*" || tagName == "node()") {
- if (data)
- data[0](s, data[1], info, count + 1, ++i, sResult);
- else
- sResult.push(s);
- }
- s = s.parentNode
- }
- },
-
- getParentNode : function(htmlNode, empty, info, count, num, sResult){
- var result = null, data = info[count];
- var node = htmlNode.parentNode;
-
- if (data)
- data[0](node, data[1], info, count + 1, 0, sResult);
- else if (node)
- sResult.push(node);
- },
-
- //precsiblg[3] might not be conform spec
- getPrecedingSibling : function(htmlNode, tagName, info, count, num, sResult){
- var result = null, data = info[count];
-
- var node = htmlNode.previousSibling;
- while (node) {
- if (tagName != "node()" && (node.style
- ? node.tagName.toLowerCase()
- : node.tagName) != tagName){
- node = node.previousSibling;
- continue;
- }
-
- if (data)
- data[0](node, data[1], info, count+1, 0, sResult);
- else if (node) {
- sResult.push(node);
- break;
- }
- }
- },
-
- //flwsiblg[3] might not be conform spec
- getFollowingSibling : function(htmlNode, tagName, info, count, num, sResult){
- var result = null, data = info[count];
-
- var node = htmlNode.nextSibling;
- while (node) {
- if (tagName != "node()" && (node.style
- ? node.tagName.toLowerCase()
- : node.tagName) != tagName) {
- node = node.nextSibling;
- continue;
- }
-
- if (data)
- data[0](node, data[1], info, count+1, 0, sResult);
- else if (node) {
- sResult.push(node);
- break;
- }
- }
- },
-
- multiXpaths : function(contextNode, list, info, count, num, sResult){
- for (var i = 0; i < list.length; i++) {
- info = list[i][0];
- var rootNode = (info[3]
- ? contextNode.ownerDocument.documentElement
- : contextNode);//document.body
- info[0](rootNode, info[1], list[i], 1, 0, sResult);
- }
-
- sResult.makeUnique();
- },
-
- compile : function(sExpr){
- var isAbsolute = sExpr.match(/^\//);//[^\/]/
-
- sExpr = sExpr.replace(/\[(\d+)\]/g, "/##$1");
- sExpr = sExpr.replace(/\|\|(\d+)\|\|\d+/g, "##$1");
- sExpr = sExpr.replace(/\.\|\|\d+/g, ".");
- sExpr = sExpr.replace(/\[([^\]]*)\]/g, function(match, m1){
- return "/##" + m1.replace(/\|/g, "_@_");
- }); //wrong assumption think of |
-
- if(sExpr == "/" || sExpr == ".") return sExpr;
-
- //Mark // elements
- //sExpr = sExpr.replace(/\/\//g, "/[]/self::");
- sExpr = sExpr.replace(/\/\//g, "descendant::");
-
- //Check if this is an absolute query
- return this.processXpath(sExpr, isAbsolute);
- },
-
- processXpath : function(sExpr, isAbsolute){
- var results = new Array();
- sExpr = sExpr.replace(/'[^']*'/g, function(m){
- return m.replace("|", "_@_");
- });
-
- sExpr = sExpr.split("\|");
- for (var i = 0; i < sExpr.length; i++)
- sExpr[i] = sExpr[i].replace(/_\@\_/g, "|");//replace(/('[^']*)\_\@\_([^']*')/g, "$1|$2");
-
- if (sExpr.length == 1)
- sExpr = sExpr[0];
- else {
- for (var i = 0; i < sExpr.length; i++)
- sExpr[i] = this.processXpath(sExpr[i]);
- results.push([this.multiXpaths, sExpr]);
- return results;
- }
-
- var sections = sExpr.split("/");
- for (var i = 0; i < sections.length; i++) {
- if (sections[i] == "." || sections[i] == "")
- continue;
- else if (sections[i] == "..")
- results.push([this.getParentNode, null]);
- else if (sections[i].match(/^[\w-_\.]+(?:\:[\w-_\.]+){0,1}$/))
- results.push([this.getChildNode, sections[i]]);//.toUpperCase()
- else if (sections[i].match(/^\#\#(\d+)$/))
- results.push([this.doQuery, ["num+1 == " + parseInt(RegExp.$1)]]);
- else if (sections[i].match(/^\#\#(.*)$/)) {
- //FIX THIS CODE
- var query = RegExp.$1;
- var m = [query.match(/\(/g), query.match(/\)/g)];
- if (m[0] || m[1]) {
- while (!m[0] && m[1] || m[0] && !m[1]
- || m[0].length != m[1].length){
- if (!sections[++i]) break;
- query += "/" + sections[i];
- m = [query.match(/\(/g), query.match(/\)/g)];
- }
- }
-
- results.push([this.doQuery, [this.compileQuery(query)]]);
- }
- else if (sections[i] == "*")
- results.push([this.getChildNode, null]); //FIX - put in def function
- else if (sections[i].substr(0,2) == "[]")
- results.push([this.getAllNodes, ["*", false]]);//sections[i].substr(2) ||
- else if (sections[i].match(/descendant-or-self::node\(\)$/))
- results.push([this.getAllNodes, ["*", true]]);
- else if (sections[i].match(/descendant-or-self::([^\:]*)(?:\:(.*)){0,1}$/))
- results.push([this.getAllNodes, [RegExp.$2 || RegExp.$1, true, RegExp.$1]]);
- else if (sections[i].match(/descendant::([^\:]*)(?:\:(.*)){0,1}$/))
- results.push([this.getAllNodes, [RegExp.$2 || RegExp.$1, false, RegExp.$1]]);
- else if (sections[i].match(/ancestor-or-self::([^\:]*)(?:\:(.*)){0,1}$/))
- results.push([this.getAllAncestorNodes, [RegExp.$2 || RegExp.$1, true, RegExp.$1]]);
- else if (sections[i].match(/ancestor::([^\:]*)(?:\:(.*)){0,1}$/))
- results.push([this.getAllAncestorNodes, [RegExp.$2 || RegExp.$1, false, RegExp.$1]]);
- else if (sections[i].match(/^\@(.*)$/))
- results.push([this.getAttributeNode, RegExp.$1]);
- else if (sections[i] == "text()")
- results.push([this.getTextNode, null]);
- else if (sections[i] == "node()")
- results.push([this.getChildNode, null]);//FIX - put in def function
- else if (sections[i].match(/following-sibling::(.*)$/))
- results.push([this.getFollowingSibling, RegExp.$1.toLowerCase()]);
- else if (sections[i].match(/preceding-sibling::(.*)$/))
- results.push([this.getPrecedingSibling, RegExp.$1.toLowerCase()]);
- else if (sections[i] == "self::node()")
- results.push([this.getSelf, null]);
- else if (sections[i].match(/self::(.*)$/))
- results.push([this.doQuery, ["jpf.XPath.doXpathFunc(htmlNode, 'local-name') == '" + RegExp.$1 + "'"]]);
- else {
- var query = sections[i];
-
- //@todo FIX THIS CODE
- //add some checking here
- var m = [query.match(/\(/g), query.match(/\)/g)];
- if (m[0] || m[1]) {
- while (!m[0] && m[1] || m[0] && !m[1] || m[0].length != m[1].length) {
- if (!sections[++i]) break;
- query += "/" + sections[i];
- m = [query.match(/\(/g), query.match(/\)/g)];
- }
- }
-
- results.push([this.doQuery, [this.compileQuery(query), true]])
-
- //throw new Error("---- Javeline Error ----\nMessage : Could not match XPath statement: '" + sections[i] + "' in '" + sExpr + "'");
- }
- }
-
- results[0][3] = isAbsolute;
- return results;
- },
-
- compileQuery : function(code){
- var c = new jpf.CodeCompilation(code);
- return c.compile();
- },
-
- doXpathFunc : function(contextNode, type, nodelist, arg2, arg3, xmlNode){
- if (!nodelist || nodelist.length == 0)
- nodelist = "";
-
- if (type == "not")
- return !nodelist;
-
- if (typeof nodelist == "object" || nodelist.dataType == "array") {
- if (nodelist && !nodelist.length)
- nodelist = [nodelist];
-
- var res = false, value, xmlNode;
- for (var i = 0; i < nodelist.length; i++) {
- xmlNode = nodelist[i];
- if (!xmlNode || typeof xmlNode == "string")
- value = xmlNode;
- else {
- if (xmlNode.nodeType == 1 && xmlNode.firstChild && xmlNode.firstChild.nodeType != 1)
- xmlNode = xmlNode.firstChild;
- value = xmlNode.nodeValue;
- }
-
- if (res = arguments.callee.call(this, contextNode, type, value, arg2, arg3, xmlNode))
- return res;
- }
- return res;
- }
- else arg1 = nodelist;
-
- switch(type){
- case "position":
- return jpf.xmldb.getChildNumber(contextNode) + 1;
- case "format-number":
- return jpf.formatNumber(arg1); //@todo this should actually do something
- case "floor":
- return Math.floor(arg1);
- case "ceiling":
- return Math.ceil(arg1);
- case "starts-with":
- return arg1 ? arg1.substr(0, arg2.length) == arg2 : false;
- case "string-length":
- return arg1 ? arg1.length : 0;
- case "count":
- return arg1 ? arg1.length : 0;
- case "last":
- return arg1 ? arg1[arg1.length-1] : null;
- case "local-name":
- return xmlNode ? xmlNode.tagName : contextNode.tagName;//[jpf.TAGNAME]
- case "substring":
- return arg1 && arg2 ? arg1.substring(arg2, arg3 || 0) : "";
- case "contains":
- return arg1 && arg2 ? arg1.indexOf(arg2) > -1 : false;
- case "concat":
- for (var str="", i = 1; i < arguments.length; i++) {
- if (typeof arguments[i] == "object") {
- str += getNodeValue(arguments[i][0]);
- continue;
- }
- str += arguments[i];
- }
- return str;
- case "translate":
- for (var i = 0; i < arg2.length; i++) {
- arg1 = arg1.replace(arg2.substr(i,1), arg3.substr(i,1));
- }
- return arg1;
- }
- },
-
- selectNodeExtended : function(sExpr, contextNode, match){
- var sResult = this.selectNodes(sExpr, contextNode);
-
- if (sResult.length == 0) return null;
- if (!match) return sResult;
-
- for (var i = 0; i < sResult.length; i++) {
- if (getNodeValue(sResult[i]) == match)
- return [sResult[i]];
- }
-
- return null;
- },
-
- getRoot : function(xmlNode){
- while (xmlNode.parentNode && xmlNode.parentNode.nodeType == 1)
- xmlNode = xmlNode.parentNode;
-
- return xmlNode;
- },
-
- selectNodes : function(sExpr, contextNode){
- if (!this.cache[sExpr])
- this.cache[sExpr] = this.compile(sExpr);
-
- if (sExpr.length > 20) {
- this.lastExpr = sExpr;
- this.lastCompile = this.cache[sExpr];
- }
-
- if (typeof this.cache[sExpr] == "string"){
- if (this.cache[sExpr] == ".")
- return [contextNode];
- if (this.cache[sExpr] == "/") {
- return [(contextNode.nodeType == 9
- ? contextNode.documentElement
- : this.getRoot(contextNode))];
- }
- }
-
- if (typeof this.cache[sExpr] == "string" && this.cache[sExpr] == ".")
- return [contextNode];
-
- var info = this.cache[sExpr][0];
-
- var rootNode = (info[3]
- ? (contextNode.nodeType == 9
- ? contextNode.documentElement
- : this.getRoot(contextNode))
- : contextNode);//document.body*/
- var sResult = [];
-
- info[0](rootNode, info[1], this.cache[sExpr], 1, 0, sResult);
-
- return sResult;
- }
-};
-
-function getNodeValue(sResult){
- if (sResult.nodeType == 1)
- return sResult.firstChild ? sResult.firstChild.nodeValue : "";
- if (sResult.nodeType > 1 || sResult.nodeType < 5)
- return sResult.nodeValue;
- return sResult;
-}
-
-/**
- * @constructor
- * @private
- */
-jpf.CodeCompilation = function(code){
- this.data = {
- F : [],
- S : [],
- I : [],
- X : []
- };
-
- this.compile = function(){
- code = code.replace(/ or /g, " || ");
- code = code.replace(/ and /g, " && ");
- code = code.replace(/!=/g, "{}");
- code = code.replace(/=/g, "==");
- code = code.replace(/\{\}/g, "!=");
-
- // Tokenize
- this.tokenize();
-
- // Insert
- this.insert();
-
- code = code.replace(/, \)/g, ", htmlNode)");
-
- return code;
- };
-
- this.tokenize = function(){
- //Functions
- var data = this.data.F;
- code = code.replace(/(translate|format-number|contains|substring|local-name|last|position|round|starts-with|string|string-length|sum|floor|ceiling|concat|count|not)\s*\(/g,
- function(d, match){
- return (data.push(match) - 1) + "F_";
- }
- );
-
- //Strings
- var data = this.data.S;
- code = code.replace(/'([^']*)'/g, function(d, match){
- return (data.push(match) - 1) + "S_";
- });
- code = code.replace(/"([^"]*)"/g, function(d, match){
- return (data.push(match) - 1) + "S_";}
- );
-
- //Xpath
- var data = this.data.X;
- code = code.replace(/(^|\W|\_)([\@\.\/A-Za-z\*][\*\.\@\/\w\-]*(?:\(\)){0,1})/g,
- function(d, m1, m2){
- return m1 + (data.push(m2) - 1) + "X_";
- });
- code = code.replace(/(\.[\.\@\/\w]*)/g, function(d, m1, m2){
- return (data.push(m1) - 1) + "X_";
- });
-
- //Ints
- var data = this.data.I;
- code = code.replace(/(\d+)(\W)/g, function(d, m1, m2){
- return (data.push(m1) - 1) + "I_" + m2;
- });
- };
-
- this.insert = function(){
- var data = this.data;
- code = code.replace(/(\d+)X_\s*==\s*(\d+S_)/g, function(d, nr, str){
- return "jpf.XPath.selectNodeExtended('"
- + data.X[nr].replace(/'/g, "\\'") + "', htmlNode, " + str + ")";
- });
-
- code = code.replace(/(\d+)([FISX])_/g, function(d, nr, type){
- var value = data[type][nr];
-
- if (type == "F") {
- return "jpf.XPath.doXpathFunc(htmlNode, '" + value + "', ";
- }
- else if (type == "S") {
- return "'" + value + "'";
- }
- else if (type == "I") {
- return value;
- }
- else if (type == "X") {
- return "jpf.XPath.selectNodeExtended('"
- + value.replace(/'/g, "\\'") + "', htmlNode)";
- }
- });
- };
-};
-
-}
- - -/*FILEHEAD(/var/lib/jpf/src/core/debug/debug.js)SIZE(-1077090856)TIME(1238933674)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -/** - * Returns a string giving information on a javascript object. - * - * @param {mixed} obj the object to investigate - */ -jpf.vardump = function(obj, depth, recur,endless){ - if (!obj) return obj + ""; - if (!depth) depth = 0; - if (!endless)endless = {}; - - var str = "{\n"; - switch (obj.dataType) { - case "string": - return "\"" + obj + "\""; - case "number": - return obj; - case "boolean": - return obj ? "true" : "false"; - case "date": - return "Date[" + new Date() + "]"; - case "array": - for (var i = 0; i < obj.length; i++) { - str += "\t".repeat(depth+1) + i + " => " - + (!recur && depth > 0 - ? typeof obj[i] - : jpf.vardump(obj[i], depth + 1, recur,endless)) + "\n"; - } - str += "\t".repeat(depth) + "}"; - - return str; - default: - if(endless[obj])return "{recur}"; - endless[obj]=1; - - if (typeof obj == "function") - return "function"; - if (obj.nodeType !== undefined && obj.style && depth != 0) - return "HTML Element [" + obj.tagName + "]"; - if (obj.nodeType !== undefined) - return "XML Element [" + obj.tagName + "]"; - //return depth == 0 ? "[ " + (obj.xml || obj.serialize()) + " ]" : "XML Element"; - if (!recur && depth > 0) - return "object"; - - //((typeof obj[prop]).match(/(function|object)/) ? RegExp.$1 : obj[prop]) - for (var prop in obj) { - try { - str += "\t".repeat(depth+1) + prop + " => " - + (!recur && depth > 0 - ? typeof obj[prop] - : jpf.vardump(obj[prop], depth + 1, recur,endless)) + "\n"; - } catch(e) { - str += "\t".repeat(depth+1) + prop + " => [ERROR]\n"; - } - } - str += "\t".repeat(depth-1) + "}"; - - return str; - } -} - -String.prototype.s = function(){ - return this.replace(/[\r\n]/g, ""); -} - -/** - * Alerts string giving information on a javascript object. - * - * @param {mixed} obj the object to investigate - */ -jpf.alert_r = function(obj, recur){ - alert(jpf.vardump(obj, null, !recur)); -} - -/** - * Object timing the time between one point and another. - * - * @param {Boolean} nostart whether the profiler should start measuring at creation. - * @constructor - */ -jpf.ProfilerClass = function(nostart){ - this.totalTime = 0; - - /** - * Starts the timer. - * @param {Boolean} clear resets the total time. - */ - this.start = function(clear){ - if (clear) this.totalTime = 0; - this.startTime = new Date().getTime(); - - this.isStarted = true; - } - - /** - * Stops the timer. - * @method - */ - this.stop = - this.end = function(){ - if (!this.startTime) return; - this.totalTime += new Date().getTime() - this.startTime; - this.isStarted = false; - } - - /** - * Sends the total time to the console. - * @param {String} msg Message displayed in the console. - */ - this.addPoint = function(msg){ - this.end(); - jpf.console.time("[TIME] " + (msg || "Profiled Section") + ": " + this.totalTime + "ms"); - this.start(true); - } - - if (!nostart) - this.start(); -}; - -jpf.Latometer = new jpf.ProfilerClass(true);//backward compatibility - - - -/*FILEHEAD(/var/lib/jpf/src/core/debug/debugwin.js)SIZE(-1077090856)TIME(1239018216)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -jpf.DebugInfoStack = []; - -Function.prototype.toHTMLNode = function(highlight){ - var code, line1, line2; - - TYPE_OBJECT = "object"; - TYPE_NUMBER = "number"; - TYPE_STRING = "string"; - TYPE_ARRAY = "array"; - TYPE_DATE = "date"; - TYPE_REGEXP = "regexp"; - TYPE_BOOLEAN = "boolean"; - TYPE_FUNCTION = "function"; - TYPE_DOMNODE = "dom node"; - TYPE_JAVNODE = "Javeline Component"; - - STATE_UNDEFINED = "undefined"; - STATE_NULL = "null"; - STATE_NAN = "nan"; - STATE_INFINITE = "infinite"; - - /** - * @private - */ - function getType(variable){ - if (variable === null) - return STATE_NULL; - if (variable === undefined) - return STATE_UNDEFINED; - if (typeof variable == "number" && isNaN(variable)) - return STATE_NAN; - if (typeof variable == "number" && !isFinite(variable)) - return STATE_INFINITE; - - - if (typeof variable == "object") { - if (variable.hasFeature) - return TYPE_JAVNODE; - if (variable.tagName || variable.nodeValue) - return TYPE_DOMNODE; - } - - if (variable.dataType == undefined) - return TYPE_OBJECT; - - return variable.dataType; - } - - //anonymous - code = this.toString(); - var endLine1 = code.indexOf("\n"); - line1 = code.slice(0, endLine1); - line2 = code.slice(endLine1+1); - - var res = /^function(\s+(.*?)\s*|\s*?)\((.*)\)(.*)$/.exec(line1); - if (res) { - var name = res[1]; - var args = res[3]; - var last = res[4]; //NOT USED? - - if (this.arguments) { - var argName, namedArgs = args.split(","); - args = []; - - for (var i = 0; i < this.arguments.length; i++) { - //if(i != 0 && arr[i]) args += ", "; - argName = (namedArgs[i] || "__NOT_NAMED__").trim();// args += "<b>" + arr[i] + "</b>"; - - var info = ["Name: " + argName]; - var id = jpf.DebugInfoStack.push(info) - 1; - - args.push("<a href='javascript:void(0)' onclick='alert(jpf.DebugInfoStack[" - + id + "].join(\"\\n\"));event.cancelBubble=true;'>" + argName + "</a>"); - info.push("Type: " + getType(this.arguments[i])); - info.push("Value: " + jpf.vardump(this.arguments[i], null, false)); - } - } - else if (jpf.isGecko) { - args = args.splitSafe(","); - var result = []; - var argName; - for (var i = 0; i < args.length; i++) { - var firstChar = args[i].charAt(0); - - if (firstChar == "[") - argName = "object"; - else if (firstChar == '"') - argName = "string"; - else if (firstChar == 't' || firstChar == 'f') - argName = "boolean"; - else - argName = "number"; - - var info = ["Type: " + argName]; - var id = jpf.DebugInfoStack.push(info) - 1; - - result.push("<a href='javascript:void(0)' onclick='alert(jpf.DebugInfoStack[" - + id + "].join(\"\\n\"));event.cancelBubble=true;'>" + argName + "</a>"); - info.push("Value: " + jpf.vardump(args[i], null, false)); - } - - args = result; - } - - line2 = line2.replace(/\{/ , ""); - line2 = line2.substr(0, line2.length-2); - - if (!highlight) { - //fine common start whitespace count - line2 = jpf.debugwin.outdent(line2); - line2 = line2.replace(/ /g, " "); - line2 = line2.replace(/\t/g, " "); - line2 = line2.replace(/\n/g, "</nobr><br><nobr> "); - line2 = "{<br><nobr> " + line2 + "</nobr><br>}"; - } - else { - line2 = "{\n" + line2 + "\n}\n"; - var div = dp.SyntaxHighlighter.HighlightString(line2, false, false); - } - - var d = document.createElement("div"); - res = "<div>\ - <div style='padding:0px 0px 2px 0px;cursor:default;' onclick=\"\ - var oFirst = this.getElementsByTagName('img')[0];\ - var oLast = this.getElementsByTagName('div')[0];\ - if (oLast.style.display == 'block') {\ - oLast.style.display = 'none';\ - oFirst.src='" + jpf.debugwin.resPath + "arrow_right.gif';\ - } else {\ - oLast.style.display = 'block';\ - oFirst.src='" + jpf.debugwin.resPath + "arrow_down.gif';\ - }\ - if (jpf.layout)\ - jpf.layout.forceResize(jpf.debugwin.oExt);\ - event.cancelBubble=true\">\ - <nobr>" - + (this.url - ? "<a href='" + this.url + "' target='_blank' style='float:right'>" - + jpf.getFilename(this.url) + - " (" + this.line + ")</a>" - : "") - + "<img width='9' height='9' src='" + jpf.debugwin.resPath - + "arrow_right.gif' style='margin:0 3px 0 2px;' />" - + (name.trim() || "anonymous") + "(" + args.join(", ") + ") \ - </nobr>\ - <div onclick='event.cancelBubble=true' onselectstart='if (jpf.dragmode.mode) return false; event.cancelBubble=true' style='\ - cursor: text;\ - display: none;\ - padding: 0px;\ - background-color: #f6f6f6;\ - color: #222;\ - overflow: auto;\ - margin-top: 2px;'>\ - <blockquote></blockquote>\ - </div>\ - </div>\ - </div>"; - d.innerHTML = res; - var b = d.getElementsByTagName("blockquote")[0]; - - if (highlight) { - b.replaceNode(div); - } - else { - b.insertAdjacentHTML("beforeBegin", line2); - b.parentNode.removeChild(b); - } - - return d.firstChild; - } - else { - return this.toString(); - } -} - -/* ***************** - ** Error Handler ** - *******************/ - -jpf.debugwin = { - useDebugger : jpf.getcookie("debugger") == "true", - profileGlobal: jpf.getcookie("profileglobal") == "true", - resPath : "", - errorTable : "debug_panel_errortable", - contextDiv : "debug_panel_jmlcontext", - stackTrace : "debug_panel_stacktrace",//null, //blockquote[0] - logView : "jvlnviewlog", - debugConsole : "jpfDebugExpr", - - outdent : function(str, skipFirst){ - var lines = str.split("\n"); - for (var min = 1000, m, i = skipFirst ? 1 : 0; i < lines.length; i++) { - if (!lines[i].trim()) - continue; - - m = lines[i].match(/^[\s \t]+/); - if (!m) { - min = 0; - break; - } - else min = Math.min(min, m[0].length); - } - if (min) { - for (var i = skipFirst ? 1 : 0; i < lines.length; i++) { - lines[i] = lines[i].substr(min); - } - } - return lines.join("\n"); - }, - - init : function(){ - if (jpf.getcookie("highlight") == "true" && self.BASEPATH) { - //<script class="javascript" src="../Library/Core/Highlighter/shCore.uncompressed.js"></script> - //<script class="javascript" src="../Library/Core/Highlighter/shBrushJScript.js"></script> - jpf.include(BASEPATH + "Library/Core/Highlighter/shCore.uncompressed.js"); - jpf.include(BASEPATH + "Library/Core/Highlighter/shBrushJScript.js"); - //<link type="text/css" rel="stylesheet" href="../Library/Core/Highlighter/SyntaxHighlighter.css" /> - jpf.loadStylesheet(BASEPATH + "Library/Core/Highlighter/SyntaxHighlighter.css"); - } - else if (self.SyntaxHighlighterCSS) { - jpf.importCssString(document, SyntaxHighlighterCSS); - } - else { - jpf.setcookie("highlight", false) - } - - if (!this.useDebugger) { - jpf.debugwin.toggleDebugger(false); - //window.onerror = jpf.debugwin.errorHandler; - - if (jpf.isGecko) - var error = Error; - - if (jpf.isOpera || jpf.isSafari || jpf.isGecko) { - self.Error = function(msg){ - jpf.debugwin.errorHandler(msg, location.href, 0); - } - self.Error.custom = true; - } - - if (jpf.isGecko) { - jpf.addEventListener("load", function(){ - self.Error = error; - }); - } - } - - if (jpf.getcookie("profilestartup") == "true" && !jpf.profiler.isRunning) { - if (this.profileGlobal) - jpf.profiler.init(window, 'window'); - else - jpf.profiler.init(jpf, 'jpf'); - jpf.profiler.start(); - } - - jpf.addEventListener("hotkey", function(e){ - if (e.keyCode == 120 || e.ctrlKey && e.altKey && e.keyCode == 68) { - jpf.debugwin.activate(); - } - }) - }, - - hide : function(){ - this.oExt.style.display = "none"; - document.body.style.marginRight = "0"; - }, - - show : function(e, filename, linenr){ - var list = [], seen = {}, i; - - if (!jpf.isIE && !Error.custom) { - var stack = new Error().stack.split("\n"); - for (i = 0; i < stack.length; i++) { - stack[i].trim().match(/^([\w_\$]*)(\(.*?\))?@(.*?):(\d+)$/); - var name = RegExp.$1; - var args = RegExp.$2; - var url = RegExp.$3; - var line = RegExp.$4; - - list.push(Function.prototype.toHTMLNode.call({ - toString : function(){ - return "function " + name + (args || "()") + "{\n...\n}"; - }, - url : url, - line: line - })); - } - - /* - Error()@:0 - ([object Object],"file:///C:/Development/javeline/platform/source/trunk/list.html",0)@file:///C:/Development/javeline/platform/source/trunk/core/debug/debugwin.js:241 - ("User forced debug window to show","file:///C:/Development/javeline/platform/source/trunk/list.html",0,true)@file:///C:/Development/javeline/platform/source/trunk/core/debug/debugwin.js:1305 - ()@file:///C:/Development/javeline/platform/source/trunk/core/debug/debugwin.js:1317 - @file:///C:/Development/javeline/platform/source/trunk/elements/appsettings.js:163 - - */ - } - else { - //Opera doesnt support caller... weird... - try { - var loop = end = jpf.isIE - ? this.show.caller.caller - : this.show.caller.caller - ? this.show.caller.caller.caller - : this.show.caller.caller; - if (loop) { - try { - do { - if (seen[loop.toString()]) - break; //recursion checker - seen[loop.toString()] = true; - //str += loop.toHTML(); - list.push(loop.toHTMLNode(jpf.getcookie("highlight") == "true")); - loop = loop.caller; - } - while (list.length < 30 && loop && loop.caller && loop.caller.caller != loop); - } - catch(a) { - list=[]; - } - } - } - catch(e){} - } - - if (!jpf.debugwin.win) - this.createWindow(); - - if (e) { - var parsed = this.formatError(e); - this.errorTable.innerHTML = parsed.table; - this.errorTable.parentNode.style.display = "block"; - - if (parsed.jmlcontext.trim()) { - this.contextDiv.parentNode.style.display = "block"; - this.contextDiv.innerHTML = parsed.jmlcontext; - } - else - this.contextDiv.parentNode.style.display = "none"; - } - else { - this.errorTable.parentNode.style.display = "none"; - this.contextDiv.parentNode.style.display = "none"; - } - - if (list.length) { - this.stackTrace.innerHTML = ""; - for (i = 0; i < list.length; i++) - this.stackTrace.appendChild(list[i]); - - this.stackTrace.parentNode.style.display = "block"; - } - else { - this.stackTrace.parentNode.style.display = "none"; - } - - this.oExt.style.display = "block"; - jpf.layout.forceResize(this.oExt); - this.logView.scrollTop = this.logView.scrollHeight; - - //!self.ERROR_HAS_OCCURRED && - if (jpf.addEventListener) { - jpf.addEventListener("debug", function(e){ - if (!jpf.debugwin.logView) return; - - jpf.debugwin.logView.insertAdjacentHTML("beforeend", e.message); - jpf.debugwin.logView.style.display = "block"; - jpf.debugwin.logView.scrollTop = jpf.debugwin.logView.scrollHeight; - }); - } - }, - - formatError: function(e) { - var parse = e.message.split(/\n===\n/), - jmlContext = jpf.highlightXml(parse[1] ? jpf.debugwin.outdent(parse[1].trim(true), true).replace(/\t/g, " ").replace(/ /g, " ") : "") - //.replace(/</g, "<").replace(/\n/g, "<br />") - errorMessage = parse[0].replace(/---- Javeline Error ----\n/g, "") - .replace(/</g, "<").replace(/Message: \[(\d+)\]/g, "Message: [<a title='Visit the manual on error code $1' style='color:blue;text-decoration:none;' target='_blank' href='http://developer.javeline.net/projects/platform/wiki/ErrorCodes#$1'>$1</a>]"), - //.replace(/(\n|^)([\w ]+:)/gm, "$1<strong>$2</strong>"),//.replace(/\n/g, "<br />"), - errorTable = []; - - errorMessage.replace(/(?:([\w ]+):(.*)(?:\n|$)|([\s\S]+))/gi, function(m, m1, m2) { - if (!errorTable.length) - errorTable.push("<table border='0' cellpadding='0' cellspacing='0'>"); - if (m1) { - if (errorTable.length != 1) { - errorTable.push("</td></tr>"); - } - errorTable.push("<tr><td class='debug_error_header'>", - m1, ":</td><td>", m2, "</td>", "</tr>"); - } - else { - if (errorTable[errorTable.length - 1] != "</tr>") - errorTable.push("</td></tr><tr><td> </td>", "<td>"); - else - errorTable.push("<tr><td> </td>", "<td>"); - errorTable.push(m); - } - }); - errorTable.push("</td></tr></table>"); - - return {table: errorTable.join(''), jmlcontext: jmlContext || ""}; - }, - - states : {}, - setSelected : function(clear){ - var oSelect = document.getElementById("dbgMarkupSelect"); - - for (var selected, value = "", i = 0; i < oSelect.childNodes.length; i++) { - if (oSelect.childNodes[i].selected) { - value = oSelect.childNodes[i].text; - selected = oSelect.childNodes[i]; - break; - } - } - - if (clear) { - if (this.lastValue) - this.states[this.lastValue] = document.getElementById("dbgMarkupInput").value; - document.getElementById("dbgMarkupInput").value = this.states[value] || ""; - } - - this.lastValue = value; - - if (value.match(/^JML/)) { - if (dbgMarkup.getModel()) - dbgMarkup.getModel().unregister(dbgMarkup); - - if (selected.value) - dbgMarkup.load(jpf.includeStack[selected.value]); - else - dbgMarkup.load(jpf.JmlParser.$jml); - - return; - } - - var xpath = document.getElementById("dbgMarkupInput").value; - var instruction = value + (value.match(/^#/) ? ":select" : "") - + (xpath ? ":" + xpath : ""); - - jpf.setModel(instruction, dbgMarkup); - }, - - exec : function(action){ - if (!action.match(/undo|redo/) && !dbgMarkup.selected) - return alert("There is no xml element selected. Action not executed"); - - switch(action){ - case "remove": - dbgMarkup.remove(dbgMarkup.selected, true); - break; - case "undo": - dbgMarkup.getActionTracker().undo(); - break; - case "redo": - dbgMarkup.getActionTracker().redo(); - break; - case "textnode": - dbgMarkup.setTextNode(dbgMarkup.selected, "new value"); - break; - case "attribute": - dbgMarkup.setAttributeValue(dbgMarkup.selected, "new", "value"); - break; - } - }, - - initMarkup : function(oHtml){ - if (!jpf.JmlParser) - return;// alert("Sorry, the depencies for the Data Debugger could not be loaded"); - - if (oHtml.getAttribute("inited")) return; - oHtml.setAttribute("inited", "true"); - - /** - * @todo change the .attribute to be in the debugmarkup namespace - * @todo fix the edit state - */ - var skinXml = '\ - <j:skin id="debug" xmlns:j="' + jpf.ns.jml + '">\ - <j:markupedit name="debugmarkup">\ - <j:style><![CDATA[\ - .debugmarkup{\ - background : url(' + this.resPath + 'splitter_docs.gif) no-repeat 50% bottom;\ - font-family : Monaco, \'Courier New\';\ - font-size : 11px;\ - cursor : default;\ - padding-bottom : 4px;\ - }\ - .debugmarkup blockquote{\ - margin : 0;\ - padding : 0px;\ - overflow : auto;\ - width : 100%;\ - height : 100%;\ - position : relative;\ - line-height : 1.4em;\ - }\ - .debugmarkup dl,\ - .debugmarkup dt,\ - .debugmarkup dd{\ - margin : 0;\ - display:inline;\ - }\ - .debugmarkup dt,\ - .debugmarkup span{\ - color : #0000FF;\ - }\ - .debugmarkup dt{\ - cursor : hand;\ - cursor : pointer;\ - }\ - .attribute dl,\ - .attribute dt,\ - .attribute dd{\ - display : inline;\ - }\ - #override .debugmarkup .textedit{\ - background-color : white;\ - color : black;\ - border : 1px solid black;\ - padding : 1px 2px 1px 2px;\ - margin : 2px -4px -2px -3px;\ - line-height : 1em;\ - }\ - #override strong.textedit{\ - position : relative;\ - }\ - #override DIV .attribute DT,\ - #override DIV .attribute DD{\ - cursor : text;\ - }\ - .attribute dt{\ - color : #191970;\ - }\ - .attribute dd{\ - color : #FF0000;\ - }\ - .debugmarkup dt,\ - .attribute,\ - .debugmarkup .selected span{}\ - .debugmarkup dl.attribute{\ - padding : 0 0 0 5px;\ - }\ - .debugmarkup dl{\ - height : 18px;\ - white-space : normal;\ - }\ - .debugmarkup dl dt{\ - white-space : normal;\ - padding : 1px 2px 2px 2px;\ - }\ - .debugmarkup dl dl{\ - height : 14px;\ - white-space : nowrap;\ - }\ - .debugmarkup dl dl dt{\ - white-space : nowrap;\ - }\ - /*\*/html>body*.debugmarkup dl{height : 12px;}/**/\ - .debugmarkup span{\ - display : inline;\ - padding : 2px;\ - }\ - .debugmarkup u{\ - text-decoration : none;\ - }\ - .debugmarkup strong{\ - font-weight : normal;\ - }\ - .debugmarkup .textnode strong{\ - cursor : text;\ - }\ - .debugmarkup DIV{\ - cursor : default;\ - padding : 0 0 0 14px;\ - position : relative;\ - }\ - .debugmarkup .selected dl,\ - .debugmarkup .selected dd,\ - .debugmarkup .selected dt,\ - .debugmarkup .selected span,\ - .debugmarkup .selected strong{\ - background-color : #25a8e7;\ - color : #FFFFFF;\ - }\ - #override .debugmarkup .highlight{\ - background-color : #FFFF00;\ - color : #000000;\ - }\ - .debugmarkup I{\ - width : 9px;\ - height : 9px;\ - position : absolute;\ - left : 2px;\ - top : 5px;\ - background-repeat : no-repeat;\ - }\ - .debugmarkup I.pluslast {\ - background-image:url(' + this.resPath + 'splus.gif);\ - }\ - .debugmarkup I.minlast {\ - background-image:url(' + this.resPath + 'smin.gif);\ - }\ - .debugmarkup I.plus {\ - background-image:url(' + this.resPath + 'splus.gif);\ - }\ - .debugmarkup I.min {\ - background-image:url(' + this.resPath + 'smin.gif);\ - }\ - .debugmarkup DIV BLOCKQUOTE{\ - margin : 0;\ - padding : 0 0 0 10px;\ - display : none;\ - height : 0;\ - overflow : hidden;\ - width : auto;\ - }\ - ]]></j:style>\ - <j:presentation>\ - <j:main container="blockquote" startclosed="false">\ - <div class="debugmarkup">\ - <blockquote> </blockquote>\ - </div>\ - </j:main>\ - <j:item class="dl" begintag="dl/dt" begintail="dl/span" endtag="span" attributes="dl" openclose="i" select="dl" container="blockquote">\ - <div><dl><dt>-</dt><span> </span></dl><blockquote> </blockquote><span>-</span><i> </i></div>\ - </j:item>\ - <j:attribute name="dt" value="dd">\ - <dl class="attribute"><dt> </dt>="<dd> </dd>"</dl>\ - </j:attribute>\ - <j:textnode text="strong" tag="u">\ - <strong class="textnode"><u> </u><strong>-</strong></strong>\ - </j:textnode>\ - <j:loading>\ - <div class="loading"><span> </span><label>Loading...</label></div>\ - </j:loading>\ - <j:empty container=".">\ - <div class="empty"></div>\ - </j:empty>\ - </j:presentation>\ - </j:markupedit>\ - </j:skin>'; - jpf.skins.Init(jpf.xmldb.getXml(skinXml)); - - document.documentElement.setAttribute("id", "override"); - - var oInt = document.getElementById("jpf_markupcontainer"); - jpf.test = oHtml; - - //Get all models - var options, i, list = jpf.nameserver.getAllNames("model"); - for (options = [], i = 0; i < list.length; i++) - options.push("<option>" + list[i] + "</option>"); - - //Get all components - list = jpf.all; - for (i = 0; i < list.length; i++) { - if (list[i] && list[i].name && list[i].hasFeature - && list[i].hasFeature(__DATABINDING__)) - options.push("<option>#" + list[i].name + "</option>"); - } - - if (!options.length) - options.push("<option></option>"); - - options.push("<option>JML Main</option>"); - for (i = 0; i < jpf.includeStack.length; i++) { - if (typeof jpf.includeStack[i] == "boolean") continue; - options.push("<option value='" + i + "'>JML " - + jpf.getFilename(jpf.includeStack[i].getAttribute("filename")) - + "</option>"); - } - - options = options.join('').replace(/option>/, "option selected='1'>"); - var first = options ? options.match(/>([^<]*)</)[1] : ""; - - oHtml.getElementsByTagName("label")[0].insertAdjacentHTML("afterend", - "<select id='dbgMarkupSelect' style='margin-top:2px;float:left;' onchange='jpf.debugwin.setSelected(true)' onkeydown='event.cancelBubble=true;'>" + options + "</select>"); - - //<button onclick='jpf.debugwin.setSelected()' onkeydown='event.cancelBubble=true;'>Change</button>\ - var xml = jpf.xmldb.getXml("\ - <j:parent xmlns:j='" + jpf.ns.jml + "'>\ - <j:markupedit skin='debugmarkup' skinset='debug' " + (first ? "model='" + first + "'" : "") + " id='dbgMarkup' render-root='true' height='160' minheight='110' resizable='vertical'>\ - <j:bindings>\ - <j:traverse select='node()[local-name(.)]' />\ - </j:bindings>\ - <j:actions><j:remove /><j:setAttributeValue /><j:renameAttribute /><j:setTextNode /></j:actions>\ - </j:markupedit>\ - </j:parent>\ - "); - - if (jpf.isIE) { - xml.ownerDocument.setProperty("SelectionNamespaces", - "xmlns:j='" + jpf.ns.jml + "'"); - } - - //Reset loading state in case of an error during init - var j = jpf.JmlParser; - j.sbInit = {}; - j.hasNewSbStackItems = false; - j.stateStack = [] - j.modelInit = [] - j.hasNewModelStackItems = false; - j.loaded = true; - - //Load JML - j.parseMoreJml(xml, oInt); - - if (jpf.layout && !jpf.hasSingleRszEvent) { - jpf.layout.setRules(jpf.getFirstElement(oInt), "resize", - "jpf.layout.forceResize(jpf.debugwin.oExt);"); - jpf.layout.activateRules(oInt.firstChild); - } - }, - - PROFILER_ELEMENT : null, - PROFILER_BUTTON : null, - PROFILER_HEADS : null, - PROFILER_SUMMARY : null, - PROFILER_PROGRESS : '<span class="debug_profilermsg debug_progress">The profiler is running. Click \'Stop\' to see its report.</span>', - PROFILER_NOPROGRESS: '<span class="debug_profilermsg">The profiler is currently inactive. Click \'Start\' to begin profiling your code.<span>', - initProfiler: function(oHtml) { - this.PROFILER_ELEMENT = document.getElementById('jpfProfilerOutput'); - this.PROFILER_BUTTON = document.getElementById('jpfProfilerAction'); - this.PROFILER_SUMMARY = document.getElementById('jpfProfilerSummary'); - this.showProgress(); - - if (jpf.profiler.isRunning) - this.toggleFold(document.getElementById('jpfProfilerPanel')); - }, - - startStop: function(input) { - input.disabled = true; - if (!jpf.profiler.isRunning) { - if (!jpf.profiler.isInitialized()) { - if (this.profileGlobal) - jpf.profiler.init(window, 'window'); - else - jpf.profiler.init(jpf, 'jpf'); - } - jpf.profiler.start(); - this.showProgress(); - } - else { - var data = jpf.profiler.stop(); - this.PROFILER_ELEMENT.innerHTML = data.html; - this.PROFILER_SUMMARY.innerHTML = data.duration + "ms, " + data.total + " calls"; - this.PROFILER_BUTTON.innerHTML = "Start"; - } - input.disabled = false; - }, - - showProgress: function() { - if (!this.PROFILER_ELEMENT) return; - if (jpf.profiler.isRunning) { - this.PROFILER_ELEMENT.innerHTML = this.PROFILER_PROGRESS; - //this.PROFILER_BUTTON.innerHTML = "Stop"; - } - else { - this.PROFILER_ELEMENT.innerHTML = this.PROFILER_NOPROGRESS; - //this.PROFILER_BUTTON.innerHTML = "Start"; - } - }, - - resortResult: function(th) { - //if (!radio.checked) return; - var data = jpf.profiler.resortStack(parseInt(th.getAttribute('rel'))); - - this.PROFILER_ELEMENT.innerHTML = data.html; - this.PROFILER_SUMMARY.innerHTML = data.duration + "ms, " + data.total + " calls"; - }, - - toggleProfileStartup: function(checked) { - if (jpf.setcookie) - jpf.setcookie("profilestartup", checked); - }, - - toggleProfileGlobal: function(checked) { - this.profileGlobal = checked; - if (checked) - jpf.profiler.reinit(window, 'window'); - else - jpf.profiler.reinit(jpf, 'jpf'); - if (jpf.setcookie) - jpf.setcookie("profileglobal", checked); - }, - - toggleFold: function(oNode, corrScroll, corrFocus) { - if (typeof corrScroll == "undefined") - corrScroll = false; - if (typeof corrFocus == "undefined") - corrFocus = false; - - var oFirst = oNode.getElementsByTagName('img')[0]; - var oLast = oNode.lastChild; - while (oLast.nodeType != 1) - oLast = oLast.previousSibling; - - if (jpf.getStyle(oLast, "display") == "block"){ - oLast.style.display = "none"; - oFirst.src = this.resPath + "arrow_gray_right.gif"; - } - else { - oLast.style.display = "block"; - oFirst.src = this.resPath + "arrow_gray_down.gif"; - if (corrScroll) - oLast.scrollTop = oLast.scrollHeight; - if (corrFocus) { - oFirst = oLast.firstChild; - while (oFirst.nodeType != 1) oFirst = oFirst.nextSibling; - oFirst.focus(); - } - } - - if (jpf.layout) - jpf.layout.forceResize(this.oExt); - }, - - $getOption : function(){ - return 7; // muuh? what's this? - }, - - focusFix : {"INPUT":1,"TEXTAREA":1,"SELECT":1}, - createWindow : function (e, stackTrace, errorInfo){ - if (!jpf.debugwin.win) - jpf.debugwin.win = document.getElementById("jpf_debugwin"); - if (jpf.debugwin.win) return; - - var elError, p, m, o; - - if (document.body) { - elError = document.body.appendChild(document.createElement("div")); - elError.id = "jpf_debugwin"; - } - else { - document.write("<div id='jpf_debugwin'></div>"); - elError = document.getElementById("jpf_debugwin"); - } - - elError.style.position = jpf.supportFixedPosition ? "fixed" : "absolute"; - - elError.host = this; - this.name = "Debug Window"; - this.tagName = "debugwin"; - - elError.onmousedown = function(e) { - if (!e) e = event; - - if (jpf.hasFocusBug - && !jpf.debugwin.focusFix[(e.srcElement || e.target).tagName]) { - jpf.window.$focusfix(); - } - - (e || event).cancelBubble = true; - }; - - this.dispatchEvent = function(){} - elError.onkeydown = - elError.onkeyup = function(e){ - if (!e) e = event; - - if (jpf.debugwin.focusFix[(e.srcElement || e.target).tagName]) - (e || event).cancelBubble = true; - } - - if (jpf.isIE) { - jpf.setStyleRule("BODY", "overflow", "", 0); - - p = jpf.getBox(jpf.getStyle(document.body, "padding")); - m = jpf.getBox(jpf.getStyle(document.body, "margin")); - o = [jpf.getStyle(document.documentElement, "overflow"), - jpf.getStyle(document.documentElement, "overflowX"), - jpf.getStyle(document.documentElement, "overflowY")]; - } - else { - p = [parseInt(jpf.getStyle(document.body, "padding-top")), - parseInt(jpf.getStyle(document.body, "padding-right")), - parseInt(jpf.getStyle(document.body, "padding-bottom")), - parseInt(jpf.getStyle(document.body, "padding-left"))]; - m = [parseInt(jpf.getStyle(document.body, "margin-top")), - parseInt(jpf.getStyle(document.body, "margin-right")), - parseInt(jpf.getStyle(document.body, "margin-bottom")), - parseInt(jpf.getStyle(document.body, "margin-left"))]; - o = [jpf.getStyleRule("html", "overflow") || "auto", - jpf.getStyleRule("html", "overflow-x") || "auto", - jpf.getStyleRule("html", "overflow-y") || "auto"]; - } - - this.resPath = (jpf.appsettings.resourcePath || jpf.basePath) + "resources/"; - - jpf.importCssString(document, "\ - html{\ - height : 100%;\ - overflow : hidden;\ - overflow-x : hidden;\ - overflow-y : hidden;\ - margin-bottom : " + (p[0] + m[0] + p[2] + m[2]) + "px;\ - }\ - body{\ - height : 100%;\ - position : relative;\ - overflow : " + o[0] + ";\ - overflow-x : " + o[1] + ";\ - overflow-y : " + o[2] + ";\ - margin : 0 605px 0 0;\ - padding : " + (p[0] + m[0]) + "px " + - (p[1] + m[1]) + "px " + - (p[2] + m[2]) + "px " + - (p[3] + m[3]) + "px;\ - width : auto;\ - }\ - #jpf_debugwin {\ - top: 0px;\ - border-left: 1px solid #bbb;\ - text-align: left;\ - width: 500px;\ - background: #fff url(" + this.resPath + "splitter_handle_vertical.gif) no-repeat 1px 50%;\ - right: 0px;\ - font-family: 'Lucida Grande', Arial, Monaco, 'MS Sans Serif';\ - font-size: 11px;\ - color: #333;\ - overflow: hidden;\ - z-index: 99999;\ - height: 100%;\ - padding-left: 4px;\ - display : none;\ - }\ - #cbTW, #cbHighlight, #toggledebug{\ - float: left;\ - }\ - #jpf_debugwin button, #jpf_debugwin select, #jpf_debugwin input, #jpf_debugwin label{\ - font-size: 10px;\ - }\ - #override #jpf_debugwin{\ - letter-spacing: 0;\ - font-family: 'Lucida Grande', Arial;\ - }\ - #jpf_debugwin label{\ - padding: 5px 0 0 1px;\ - width: auto;\ - }\ - #jpf_debugwin button{\ - padding: 0;\ - margin: 0 0 2px 0;\ - }\ - #jpf_debugwin .debug_header{\ - position: relative;\ - background: url(" + this.resPath + "backgrounds.png) repeat-x 0 -145px;\ - border-bottom: 1px solid #505050;\ - height: 66px;\ - -moz-user-select: none;\ - -khtml-user-select: none;\ - user-select: none;\ - }\ - #jpf_debugwin .debug_header_cont{\ - background: url(" + this.resPath + "ajax_logo.png) no-repeat right 4px;\ - width: 100%;\ - height: 66px;\ - }\ - #jpf_debugwin .debug_closebtn,\ - #jpf_debugwin .debug_closebtn_hover{\ - cursor: hand;\ - cursor: pointer;\ - right: 0px;\ - top: 3px;\ - z-index: 1000;\ - margin: 0px;\ - width: 16px;\ - height: 16px;\ - overflow: hidden;\ - padding: 0;\ - position: absolute;\ - background: url(" + this.resPath + "buttons.png) no-repeat -176px -16px;\ - }\ - #jpf_debugwin .debug_closebtn_hover{\ - background-position: -176px 0px;\ - }\ - #jpf_debugwin .debug_logos{\ - background: url(" + this.resPath + "jpf_logo.png) no-repeat 5px 5px;\ - position: absolute;\ - top: 0px;\ - height: 50px;\ - width: 200px;\ - padding: 14px 4px 4px 68px;\ - margin: 0;\ - font-family: Arial, sans-serif, Tahoma, Verdana, Helvetica;\ - color: #fff;\ - font-weight: 100;\ - font-size: 14px;\ - letter-spacing: 0px;\ - line-height: 15px;\ - }\ - #jpf_debugwin .debug_logos .debug_jpf{\ - display: block;\ - }\ - #jpf_debugwin .debug_logos .debug_jpf strong{\ - font-weight: 900;\ - font-family: \'Arial Black\';\ - letter-spacing: -1px;\ - }\ - #jpf_debugwin .debug_logos .debug_jpf_slogan{\ - font-style: italic;\ - font-size: 9px;\ - line-height: 10px;\ - display : block;\ - }\ - #jpf_debugwin .debug_panel_head .debug_btn{\ - top:3px;\ - position:relative;\ - background: url(" + this.resPath + "buttons.png) no-repeat -192px 0;\ - width: 16px;\ - height: 16px;\ - }\ - #jpf_debugwin .debug_panel_head .debug_btn_down{\ - background-position: -192px -16px;\ - }\ - #jpf_debugwin .debug_toolbar{\ - position: relative;\ - height: 22px;\ - background: url(" + this.resPath + "backgrounds.png) repeat-x 0 -57px;\ - padding: 0 0 0 4px;\ - font-size: 10px;\ - vertical-align: middle;\ - overflow: hidden;\ - -moz-user-select: none;\ - -khtml-user-select: none;\ - user-select: none;\ - }\ - #jpf_debugwin .debug_toolbar_inner{\ - border-top: 1px solid #cacaca;\ - border-bottom: 1px solid #cacaca;\ - }\ - #jpf_debugwin .debug_toolbar .debug_btn{\ - position: relative;\ - border-right: 1px solid #b8b8b8;\ - width: 24px;\ - height: 22px;\ - float: left;\ - cursor: pointer;\ - cursor: hand;\ - }\ - #jpf_debugwin .debug_toolbar .debug_btnright{\ - float: right !important;\ - border-right: none;\ - border-left: 1px solid #b8b8b8;\ - }\ - #jpf_debugwin .debug_toolbar .debug_btn span{\ - position: absolute;\ - background: url(" + this.resPath + "buttons.png) no-repeat 0 0;\ - width: 16px;\ - height: 16px;\ - top: 4px;\ - left: 4px;\ - }\ - #jpf_debugwin .debug_toolbar .debug_btn span.reboot{\ - background-position: -16px 0;\ - }\ - #jpf_debugwin .debug_toolbar .debug_btn span.undo{\ - background-position: -32px 0;\ - }\ - #jpf_debugwin .debug_toolbar .debug_btn span.redo{\ - background-position: -48px 0;\ - }\ - #jpf_debugwin .debug_toolbar .debug_btn span.online{\ - background-position: -64px 0;\ - }\ - #jpf_debugwin .debug_toolbar .debug_btn span.offline{\ - background-position: -80px 0;\ - }\ - #jpf_debugwin .debug_toolbar .debug_btn span.reset{\ - background-position: -96px 0;\ - }\ - #jpf_debugwin .debug_toolbar .debug_btn span.start{\ - background-position: -112px 0;\ - }\ - #jpf_debugwin .debug_toolbar .debug_btn span.remove{\ - background-position: -128px 0;\ - }\ - #jpf_debugwin .debug_toolbar .debug_btn span.textnode{\ - background-position: -144px 0;\ - }\ - #jpf_debugwin .debug_toolbar .debug_btn span.attribute{\ - background-position: -160px 0;\ - }\ - #jpf_debugwin .debug_toolbar .debug_btn_down span.exec{\ - background-position: 0 -16px;\ - }\ - #jpf_debugwin .debug_toolbar .debug_btn_down span.reboot{\ - background-position: -16px -16px;\ - }\ - #jpf_debugwin .debug_toolbar .debug_btn_down span.undo{\ - background-position: -32px -16px;\ - }\ - #jpf_debugwin .debug_toolbar .debug_btn_down span.redo{\ - background-position: -48px -16px;\ - }\ - #jpf_debugwin .debug_toolbar .debug_btn_down span.online{\ - background-position: -64px -16px;\ - }\ - #jpf_debugwin .debug_toolbar .debug_btn_down span.offline{\ - background-position: -80px -16px;\ - }\ - #jpf_debugwin .debug_toolbar .debug_btn_down span.reset{\ - background-position: -96px -16px;\ - }\ - #jpf_debugwin .debug_toolbar .debug_btn_down span.start{\ - background-position: -112px -16px;\ - }\ - #jpf_debugwin .debug_toolbar .debug_btn_down span.remove{\ - background-position: -128px -16px;\ - }\ - #jpf_debugwin .debug_toolbar .debug_btn_down span.textnode{\ - background-position: -144px -16px;\ - }\ - #jpf_debugwin .debug_toolbar .debug_btn_down span.attribute{\ - background-position: -160px -16px;\ - }\ - #jpf_debugwin .debug_footer{\ - width: 100%;\ - position: relative;\ - bottom: 0px;\ - border-bottom: 0;\ - border-left: 1px solid #a3a3a3;\ - -moz-user-select: none;\ - -khtml-user-select: none;\ - user-select: none;\ - }\ - #jpf_debugwin .debug_footer img{\ - position: absolute;\ - top: 0px;\ - right: 0px;\ - border: 0;\ - margin: 0;\ - padding: 0;\ - }\ - #jpf_debugwin .debug_panel{\ - cursor:default;\ - border-left: 1px solid #a3a3a3;\ - padding: 0;\ - margin: 0;\ - font-family: 'Lucida Grande', 'MS Sans Serif', Arial;\ - }\ - #jpf_debugwin .debug_panel_head{\ - background: url(" + this.resPath + "backgrounds.png) repeat-x 0 0;\ - height: 17px;\ - padding: 2px 0 0 0;\ - -moz-user-select: none;\ - -khtml-user-select: none;\ - user-select: none;\ - }\ - #jpf_debugwin .debug_panel_head img{\ - margin: 2px 0 0 6px;\ - }\ - #jpf_debugwin .debug_panel_head strong{\ - color: #826e6e;\ - }\ - #jpf_debugwin .debug_panel_headsub{\ - margin-right: 5px;\ - float: right;\ - margin-top: -4px;\ - }\ - #jpf_debugwin .debug_panel_body_base{\ - cursor: text;\ - background: white url(" + this.resPath + "shadow.gif) no-repeat 0 0;\ - padding: 4px;\ - font-family: Monaco, Courier New;\ - margin: 0;\ - }\ - #jpf_debugwin .debug_panel_body_error{\ - padding: 0;\ - margin: 0;\ - }\ - #jpf_debugwin .debug_panel_body_error table{\ - font-family: 'Lucida Grande', 'MS Sans Serif', Arial;\ - font-size: 10px;\ - width: 100%;\ - }\ - #jpf_debugwin .debug_panel_body_error td{\ - padding: 2px;\ - border-bottom: 1px solid #e4e4e4;\ - border-left: 1px solid #e4e4e4;\ - margin: 0;\ - }\ - #jpf_debugwin .debug_panel_body_error .debug_error_header{\ - background-color: #449ad0;\ - border-bottom: 1px solid #79afd1;\ - border-left: none;\ - padding-left: 4px;\ - color: #fff;\ - width: 65px;\ - -moz-user-select: none;\ - -khtml-user-select: none;\ - user-select: none;\ - }\ - #jpf_debugwin .debug_panel_body_none{\ - display: none;\ - }\ - #jpf_debugwin .debug_panel_body_markup{\ - padding: 0;\ - white-space: nowrap;\ - }\ - #jpf_debugwin .debug_panel_body_jml{\ - padding: 0;\ - white-space: nowrap;\ - padding : 10px;\ - font-family : 'Lucida Grande', Verdana;\ - font-size : 8.5pt;\ - white-space : normal;\ - overflow : auto;\ - max-height : 200px;\ - }\ - #jpf_debugwin .debug_panel_body_data{\ - min-height: 130px;\ - white-space: nowrap;\ - overflow: auto;\ - display: none;\ - padding : 0;\ - }\ - #jpf_debugwin .debug_panel_body_profiler{\ - padding: 0px;\ - font-family: 'Lucida Grande', 'MS Sans Serif', Arial;\ - font-size: 9px;\ - height: 180px;\ - overflow: auto;\ - display: block;\ - }\ - #jpf_debugwin .debug_panel_body_log{\ - height: 250px;\ - overflow: auto;\ - font-size: 8pt;\ - font-family: 'Lucida Grande', Verdana;\ - }\ - #jpf_debugwin .debug_panel_body_console{\ - width: 391px;\ - height: 100px;\ - border: 0;\ - overflow: auto;\ - font-size: 12px;\ - }\ - #jpf_debugwin .debug_profilermsg{\ - margin: 4px;\ - font-weight: 500;\ - height: 20px;\ - line-height: 20px;\ - vertical-align: middle;\ - overflow: visible;\ - padding: 4px;\ - }\ - #jpf_debugwin .debug_progress{\ - background-image: url(" + this.resPath + "progress.gif);\ - background-repeat: no-repeat;\ - background-position: center left;\ - padding-left: 22px;\ - }\ - #jpf_debugwin .debug_console_btn{\ - font-family: 'Lucida Grande', 'MS Sans Serif', Arial;\ - font-size: 8pt;\ - margin: 0 0 0 3px;\ - }\ - #jpf_debugwin .debug_check_use{\ - position: relative;\ - top: 4px;\ - font-family: 'Lucida Grande', 'MS Sans Serif', Arial;\ - font-size: 8pt;\ - }"); - - document.body.style.display = "block"; - - var canViewMarkup = jpf.nameserver && jpf.markupedit ? true : false, - useProfiler = false; - - elError.innerHTML = "\ - <div class='debug_header'>\ - <div class='debug_header_cont'>\ - <div onselectstart='if (jpf.dragmode.mode) return false; event.cancelBubble=true' class='debug_logos'>\ - \ - </div>\ - <div class='debug_closebtn' onmouseover='this.className=\"debug_closebtn_hover\"' \ - onmouseout='this.className=\"debug_closebtn\"' onclick='jpf.debugwin.hide()' title='Close'> </div>\ - </div>\ - </div>\ - <div class='debug_panel' onclick='jpf.debugwin.toggleFold(this);'>\ - <div class='debug_panel_head'>\ - <img width='9' height='9' src='" + this.resPath + "arrow_gray_down.gif' /> \ - <strong>Error</strong>\ - </div>\ - <div id='" + this.errorTable + "' onclick='event.cancelBubble=true' \ - onselectstart='if (jpf.dragmode.mode) return false; event.cancelBubble=true'\ - class='debug_panel_body_base debug_panel_body_error'>@todo</div>\ - </div>\ - <div class='debug_panel' onclick='jpf.debugwin.toggleFold(this);'>\ - <div class='debug_panel_head'>\ - <img width='9' height='9' src='" + this.resPath + "arrow_gray_down.gif' /> \ - <strong>JML related to the error</strong>\ - </div>\ - <div id='" + this.contextDiv + "' onclick='event.cancelBubble=true' \ - onselectstart='if (jpf.dragmode.mode) return false; event.cancelBubble=true' \ - class='debug_panel_body_base debug_panel_body_jml'>@todo</div>\ - </div>\ - <div class='debug_panel' onclick='jpf.debugwin.toggleFold(this);'>\ - <div class='debug_panel_head'>\ - <img width='9' height='9' src='" + this.resPath + "/arrow_gray_right.gif' /> \ - <strong>Stack Trace</strong>\ - </div>\ - <div id='" + this.stackTrace + "' class='debug_panel_body_base debug_panel_body_none'></div>\ - </div>" + - (canViewMarkup - ? "<div class='debug_panel' onclick='jpf.debugwin.initMarkup(this);jpf.debugwin.toggleFold(this);'>\ - <div class='debug_panel_head'>\ - <img width='9' height='9' src='" + this.resPath + "arrow_gray_right.gif' /> \ - <strong>Live Data Debugger (beta)</strong>\ - </div>\ - <div onclick='event.cancelBubble=true' onselectstart='if (jpf.dragmode.mode) return false; event.cancelBubble=true'\ - class='debug_panel_body_base debug_panel_body_markup debug_panel_body_none'>\ - <div id='jpf_markupcontainer'> </div>\ - <div class='debug_toolbar debug_toolbar_inner'>\ - <label style='float:left'>Model:</label>\ - <label style='float:left'>XPath:</label><input id='dbgMarkupInput' onkeydown='if(event.keyCode==13) jpf.debugwin.setSelected(true);event.cancelBubble=true;' style='margin-top:2px;width:90px;float:left'/>\ - <div onclick='jpf.debugwin.exec(\"remove\")' class='debug_btn debug_btnright' title='Remove'\ - onmousedown='jpf.debugwin.btnMouseDown(this)' onmouseup='jpf.debugwin.btnMouseUp(this)'>\ - <span class='remove'> </span>\ - </div>\ - <div onclick='jpf.debugwin.exec(\"textnode\")' class='debug_btn debug_btnright' title='Textnode'\ - onmousedown='jpf.debugwin.btnMouseDown(this)' onmouseup='jpf.debugwin.btnMouseUp(this)'>\ - <span class='textnode'> </span>\ - </div>\ - <div onclick='jpf.debugwin.exec(\"attribute\")' class='debug_btn debug_btnright' title='Attribute'\ - onmousedown='jpf.debugwin.btnMouseDown(this)' onmouseup='jpf.debugwin.btnMouseUp(this)'>\ - <span class='attribute'> </span>\ - </div>\ - <div onclick='jpf.debugwin.exec(\"redo\")' class='debug_btn debug_btnright' title='Redo'\ - onmousedown='jpf.debugwin.btnMouseDown(this)' onmouseup='jpf.debugwin.btnMouseUp(this)'>\ - <span class='redo'> </span>\ - </div>\ - <div onclick='jpf.debugwin.exec(\"undo\")' class='debug_btn debug_btnright' title='Undo'\ - onmousedown='jpf.debugwin.btnMouseDown(this)' onmouseup='jpf.debugwin.btnMouseUp(this)'>\ - <span class='undo'> </span>\ - </div>\ - </div>\ - </div>\ - </div>" - : "") + - (useProfiler - ? "<div class='debug_panel' id='jpfProfilerPanel' onclick='jpf.debugwin.toggleFold(this);'>\ - <div class='debug_panel_head'>\ - <img width='9' height='9' src='" + this.resPath + "arrow_gray_right.gif' /> \ - <strong>Javascript Profiler (beta)</strong>\ - </div>\ - <div onclick='event.cancelBubble=true' onselectstart='if (jpf.dragmode.mode) return false; event.cancelBubble=true' style='display:none;'>\ - <div id='jpfProfilerOutput' class='debug_panel_body_base debug_panel_body_profiler'></div>\ - <div id='jpfProfilerSummary' style='float:right;font-size:9px;margin-right:10px;'></div>\ - <div class='debug_toolbar debug_toolbar_inner'>\ - <div id='jpfProfilerAction' onclick='jpf.debugwin.startStop(this);' class='debug_btn' title='Start'\ - onmousedown='jpf.debugwin.btnMouseDown(this)' onmouseup='jpf.debugwin.btnMouseUp(this)'>\ - <span class='start'> </span>\ - </div>\ - <input id='cbProfileGlobal' type='checkbox' onclick='\ - jpf.debugwin.toggleProfileGlobal(this.checked);\ - event.cancelBubble = true;'" + (this.profileGlobal ? " checked='checked'" : "") + "/>\ - <label for='cbProfileGlobal' onclick='event.cancelBubble=true'>\ - Profile window object\ - </label>\ - <input id='cbProfileStartup' type='checkbox' onclick='\ - jpf.debugwin.toggleProfileStartup(this.checked);\ - event.cancelBubble = true;'" + (jpf.isTrue(jpf.getcookie("profilestartup")) ? " checked='checked'" : "") + "/>\ - <label for='cbProfileStartup' onclick='event.cancelBubble=true'>\ - Profile startup\ - </label>\ - </div>\ - </div>\ - </div>" - : "") + - "<div class='debug_panel' onclick='jpf.debugwin.toggleFold(this, true);'>\ - <div class='debug_panel_head'>\ - <div class='debug_panel_headsub'>\ - <div class='debug_btn' title='Open window'\ - onmouseover='jpf.debugwin.btnMouseDown(this)' onmouseout='jpf.debugwin.btnMouseUp(this)'\ - onclick='\ - jpf.debugwin.showLogWindow();\ - event.cancelBubble = true;'\ - > </div>\ - </div>\ - <img width='9' height='9' src='" + this.resPath + "arrow_gray_down.gif' /> \ - <strong>Log Viewer</strong>\ - </div>\ - <div id='" + this.logView + "' onclick='event.cancelBubble=true'\ - onselectstart='if (jpf.dragmode.mode) return false; event.cancelBubble=true'\ - class='debug_panel_body_base debug_panel_body_log'>" - + jpf.console.debugInfo.join('').replace(/\{imgpath\}/g, this.resPath) + - "</div>\ - </div>\ - <div class='debug_panel' onclick='jpf.debugwin.toggleFold(this, false, true);'>\ - <div class='debug_panel_head'>\ - <img width='9' height='9' src='" + this.resPath + "arrow_gray_down.gif' /> \ - <strong>Javascript console</strong>\ - </div>\ - <div onclick='event.cancelBubble=true'>\ - <textarea id='" + this.debugConsole + "' onkeydown='return jpf.debugwin.consoleTextHandler(event);'\ - onselectstart='if (jpf.dragmode.mode) return false; event.cancelBubble=true'\ - class='debug_panel_body_base debug_panel_body_console'>" + jpf.getcookie('jsexec') + "</textarea>\ - <div class='debug_toolbar debug_toolbar_inner'>\ - <div id='jpfDebugExec' onclick='jpf.debugwin.jRunCode(jpf.debugwin.debugConsole.value)' title='Run Code'\ - class='debug_btn' onmousedown='jpf.debugwin.btnMouseDown(this)' onmouseup='jpf.debugwin.btnMouseUp(this)'>\ - <span class='exec'> </span>\ - </div>\ - <div onclick='jpf.debugwin.run(\"reboot\")' class='debug_btn' title='Reboot Application'\ - onmousedown='jpf.debugwin.btnMouseDown(this)' onmouseup='jpf.debugwin.btnMouseUp(this)'>\ - <span class='reboot'> </span>\ - </div>\ - <div onclick='jpf.debugwin.run(\"undo\")' class='debug_btn' title='Undo'\ - onmousedown='jpf.debugwin.btnMouseDown(this)' onmouseup='jpf.debugwin.btnMouseUp(this)'>\ - <span class='undo'> </span>\ - </div>\ - <div onclick='jpf.debugwin.run(\"redo\")' class='debug_btn' title='Redo'\ - onmousedown='jpf.debugwin.btnMouseDown(this)' onmouseup='jpf.debugwin.btnMouseUp(this)'>\ - <span class='redo'> </span>\ - </div>\ - <div onclick='jpf.debugwin.run(\"reset\")' class='debug_btn' title='Clear offline cache'\ - onmousedown='jpf.debugwin.btnMouseDown(this)' onmouseup='jpf.debugwin.btnMouseUp(this)'>\ - <span class='reset'> </span>\ - </div>\ - <div onclick='jpf.debugwin.run(\"online\")' class='debug_btn' title='Go Online'\ - onmousedown='jpf.debugwin.btnMouseDown(this)' onmouseup='jpf.debugwin.btnMouseUp(this)'>\ - <span class='online'> </span>\ - </div>\ - <div onclick='jpf.debugwin.run(\"offline\")' class='debug_btn' title='Go Offline'\ - onmousedown='jpf.debugwin.btnMouseDown(this)' onmouseup='jpf.debugwin.btnMouseUp(this)'>\ - <span class='offline'> </span>\ - </div>\ - </div>\ - </div>\ - </div>\ - <div id='lastElement' class='debug_footer debug_toolbar'>\ - <input id='toggledebug' type='checkbox' onclick='jpf.debugwin.toggleDebugger(this.checked)'" + (jpf.isTrue(jpf.getcookie("debugger")) ? " checked='checked'" : "") + " />\ - <label for='toggledebug' class='debug_check_use'>Use browser's debugger</label>\ - <a href='http://www.javeline.com' target='_blank'><img src='" + this.resPath + "javeline_logo_small.png' /></a>\ - </div>"; - - this.errorTable = document.getElementById(this.errorTable); - this.contextDiv = document.getElementById(this.contextDiv); - this.stackTrace = document.getElementById(this.stackTrace); - this.logView = document.getElementById(this.logView); - this.debugConsole = document.getElementById(this.debugConsole); - - if (!this.oExt && jpf.Interactive) { - this.oExt = elError; - this.pHtmlDoc = document; - - this.$propHandlers = []; - jpf.inherit.call(this, jpf.Interactive); - - this.minwidth = 400; - this.minheight = 442; - this.maxwidth = 10000; - this.maxheight = 10000; - - this.resizable = "horizontal"; - this.resizeOutline = true; - this.$propHandlers["resizable"].call(this, "horizontal"); - - if (jpf.isIE) { - this.debugConsole.parentNode.style.width = "auto"; - this.debugConsole.parentNode.style.paddingTop = "108px"; - this.debugConsole.style.position = "absolute"; - this.debugConsole.style.marginTop = "-108px"; - } - - if (jpf.layout) { - jpf.layout.setRules(elError, "resize", - "var oHtml = document.getElementById('" + elError.id + "');\ - var o = document.getElementById('jvlnviewlog');\ - var l = document.getElementById('lastElement');\ - var scrollHeight = l.offsetTop + l.offsetHeight;\ - var shouldSize = scrollHeight - o.offsetHeight + 200 < oHtml.offsetHeight;\ - o.style.height = (shouldSize\ - ? oHtml.offsetHeight - scrollHeight + o.offsetHeight - 8\ - : 190) + 'px';\ - oHtml.style.overflowY = shouldSize ? 'hidden' : 'auto';\ - oHtml.style.right = '0px';\ - oHtml.style.left = '';\ - document.body.style.marginRight = \ - oHtml.offsetWidth + 'px';\ - var o = document.getElementById('jpfDebugExpr');\ - if (o.parentNode.offsetWidth)\ - o.style.width = (o.parentNode.offsetWidth \ - - (jpf.isGecko ? 4 : 8)) + 'px';\ - "); - jpf.layout.activateRules(elError); - } - } - else - this.oExt = elError; - - if (jpf.hasFocusBug) - jpf.sanitizeTextbox(this.debugConsole); - - clearInterval(jpf.Init.interval); - ERROR_HAS_OCCURRED = true; - - this.initProfiler(this); - - jpf.getWindowWidth = function(){ - return document.body.offsetWidth; - } - jpf.getWindowHeight = function(){ - return document.body.offsetHeight; - } - }, - - run : function(action){ - switch(action){ - case "undo": - jpf.window.getActionTracker().undo(); - break; - case "redo": - jpf.window.getActionTracker().redo(); - break; - case "reset": - jpf.offline.clear(); - break; - case "reboot": - jpf.reboot(); - break; - case "online": - if (jpf.offline.detector.detection != "manual") { - jpf.console.info("Switching to manually network detection."); - jpf.offline.detector.detection = "manual"; - jpf.offline.detector.stop(); - } - - jpf.offline.goOnline(); - break; - case "offline": - if (jpf.offline.detector.detection != "manual") { - jpf.console.info("Switching to manually network detection."); - jpf.offline.detector.detection = "manual"; - jpf.offline.detector.stop(); - } - - jpf.offline.goOffline() - break; - } - }, - - jRunCode : function(code){ - jpf.setcookie("jsexec", code); - - jpf.console.write("<span style='color:blue'><span style='float:left'>>>></span><div style='margin:0 0 0 30px'>" - + code.replace(/ /g, " ").replace(/\t/g, " ").replace(/</g, "<").replace(/\n/g, "<br />") + "</div></span>", "info", null, null, null, true); - - var doIt = function(){ - var x = eval(code); - - if (x === null) - x = "null"; - else if (x === undefined) - x = "undefined"; - - try { - jpf.console.write((x.nodeType && !x.nodeFunc ? x.outerHTML || x.xml || x.serialize() : x.toString()) - .replace(/</g, "<") - .replace(/\n/g, "<br />"), "info", null, null, null, true); - }catch(e){ - jpf.console.write(x - ? "Could not serialize object" - : x, "error", null, null, null, true); - } - } - - if (jpf.debugwin.useDebugger) - doIt(); - else { - try{ - doIt(); - } - catch(e) { - jpf.console.write(e.message, "error", null, null, null, true); - } - } - }, - - consoleTextHandler: function(e) { - if (!e) e = window.event; - var oArea = e.target || e.srcElement; - if (e.keyCode == 9) { - document.getElementById("jpfDebugExec").focus(); - e.cancelBubble = true; - return false; - } - else if(e.keyCode == 13 && e.ctrlKey) { - jpf.debugwin.jRunCode(oArea.value); - return false; - } - }, - - btnMouseDown: function(oBtn) { - oBtn.className = oBtn.className.replace("debug_btn_down", "") - + " debug_btn_down"; - }, - - btnMouseUp: function(oBtn) { - oBtn.className = "debug_btn" - + ((oBtn.className.indexOf('right') > -1) ? " debug_btnright" : ""); - }, - - consoleBtnHandler: function(e) { - if (!e) e = window.event; - if (e.shiftKey && e.keyCode == 9) { - e.cancelBubble = true; - return false; - } - }, - - consoleExecHandler: function(e) { - if (!e) e = window.event; - if (e.shiftKey && e.keyCode == 9) { - document.getElementById("jpfDebugExpr").focus(); - e.cancelBubble = true; - return false; - } - }, - - showLogWindow : function (checked){ - jpf.console.showWindow(); - }, - - toggleHighlighting : function (checked){ - jpf.setcookie("highlight", checked); - }, - - toggleDebugger : function(checked){ - this.useDebugger = checked; - - if (jpf.setcookie) - jpf.setcookie("debugger", checked) - - if (!checked) { - window.onerror = this.errorHandler; - } - else - window.onerror = null; - }, - - errorHandler : function(message, filename, linenr, isForced){ - if (!message) message = ""; - var e = message - ? { - message : message.indexOf("jml file") > -1 - ? message - : "js file: [line: " + linenr + "] " - + jpf.removePathContext(jpf.hostPath, filename) + "\n" + message - } - : null; - - if (!isForced) { - jpf.console.error("[line " + linenr + "] " + message - .split(/\n\n===\n/)[0].replace(/</g, "<") - .replace(/\n/g, "<br />")); - } - - jpf.debugwin.show(e, filename, linenr); - - return true; - }, - - activate : function(msg){ - //jpf.debugwin.toggleDebugger(false); - - if (document.getElementById("jpf_debugwin")) { - document.getElementById("jpf_debugwin").style.display = "block"; - - if (jpf.layout) - jpf.layout.forceResize(this.oExt); - } - else { - jpf.debugwin.errorHandler(msg, null, null, true); - } - } -} - -jpf.showDebugWindow = function(){ - jpf.debugwin.activate(); -} - - - -/*FILEHEAD(/var/lib/jpf/src/core/debug/profiler.js)SIZE(-1077090856)TIME(1238933674)*/ - -/** - * $Id$ - * Profiler class - * @class Profiler - * @version $Rev$ - * @author Mike de Boer (info AT mikedeboer.nl) - */ - -jpf.profiler = { - stackTrace : {}, //object - keepsafe for all profiled function during a cycle - previousStack : null, //object - keeping hold of the stackTrace of the previous cycle - isRunning : false, //bool - TRUE when the Profiler is running a cycle - pointers : {}, //object - keepsafe for functions that have been decorated with a Profiler function template (for back reference) - hasPointers : false, //bool - TRUE when the profiler has one or more function pointers in storage to profile - precision : 3, //number - output precision of timers (in Profiler reports) - runs : 0, //number - number of cycles being ran - sortMethod : 2, //number - identifies the sorting method: see Profiler#SORT_BY_* constants - - //the following functions take care of asynchronous nature of ECMAscript function calls, by utilizing queues: - startBusy : false, //bool - TRUE when the Profiler is busy profiling a function call - startQueue : [], //array - A queue holding Profiling requests from function pointers (START) - startQueueTimer: null, //mixed - Timer that, while running, will try to purge the startQueue - endBusy : false, //bool - TRUE when the Profiler is busy ending a function call (thus calculating the running time for that function) - endQueue : [], //array - A queue holding Profiling requests from function pointers (END) - endQueueTimer : null, //mixed - Timer that, while running, will try to purge the endQueue - - /** - * Initialize the Profiler. - * Usage: pass objects, holding (a) collection(s) of function(s) as arguments - * to this function and it transforms those functions, so that they may be Profiled. - * Example: - * Profiler.init( - * Object1, 'Object1', - * Object2, 'Object2 - Sample', - * Object3.prototype, 'Object3 - A prototype', - * ); - * Note: there is no limit in how long the arguments list can be. However, - * your application may become less response as the list grows larger. - * - * @param {Object} Parameter 1 must always be an object - * @param {String} 2nd parameter must always be a string, describing the object. - * @type {void} - */ - init: function() { - var i, j, obj, objName, pName, canProbe; - for (i = 0; i < arguments.length; i += 2) { - if (typeof arguments[i] == "object") { - obj = arguments[i]; - if (obj == this) //don't profile meself! - continue; - if (!obj || (typeof obj['__profilerId'] != "undefined" && (!obj.prototype - || obj.prototype.$profilerId != obj.$profilerId))) //infinite loop detection - continue; - if (obj.nodeType) //don't allow DOM interface pointers to be profiled. - continue; - obj.$profilerId = this.recurDetect.push(obj) - 1; - objName = arguments[(i + 1)]; - if (objName.indexOf('contentDocument') > -1) - alert(1); - for (j in obj) { - pName = objName + "." + j; - canProbe = false; - try { - var tmp = typeof obj[j]; - canProbe = true; - } - catch(e) {} - if (canProbe === false) - continue; - if (typeof obj[j] == "function" && typeof obj[j]['nameSelf'] == "undefined") { - obj[j].nameSelf = pName; - this.pointers['pointer_to_' + pName] = obj[j]; - var k, props = {}; - for (k in obj[j]) props[k] = obj[j][k]; - var _proto = obj[j].prototype ? obj[j].prototype : null; - obj[j] = Profiler_functionTemplate(); - for (k in props) obj[j][k] = props[k]; - if (_proto) { - obj[j].prototype = _proto; - this.init(_proto, pName + '.prototype'); - } - obj[j].nameSelf = pName; - if (!this.hasPointers) - this.hasPointers = true; - } - else if (typeof obj[j] == "object") { - this.init(obj[j], pName); - } - } - } - } - }, - - recurDetect : [], - - uniqueNumber: 0, - /** - * API: Wrap a function with the profiler template function to make sure - * it is also profiled. - * - * @param {Function} func - * @type {void} - */ - wrapFunction: function(func){ - var pName = "anonymous" + this.uniqueNumber++; - func.nameSelf = pName; - this.pointers['pointer_to_' + pName] = func; - - func = Profiler_functionTemplate(); - func.nameSelf = pName; - }, - - /** - * Do as if jpf.profiler is loaded all over again with its default values, - * except for rounding precision, the total number of runs (still valid - * count) and the active sorting method. - * After - memory safe - deinit, the call is passed to {@link core.profiler.method.init} with - * the original arguments. Therefore, you should call this function exactly - * like you call init(). - * Note : if you notice memory leakage after execution of this function, - * please contact us! - * Note2: we cannot clear our collection of pointers, simply because they - * have been decorated with {@link Profiler_functionTemplate}. - * Therefore each call to reinit may yield different result, because - * the old stack of pointers is still active. - * - * @type {void} - */ - reinit: function() { - this.stackTrace = {} - this.previousStack = null; - this.isRunning = false; - - this.startBusy = this.endBusy = false; - this.startQueue = []; - this.endQueue = []; - this.endQueueTimer = this.startQueueTimer = null; - - this.init.apply(this, arguments); - }, - - /** - * Returns whether the profiler is ready to run. A simple way of telling the - * callee that one or more pointers are in memory by now. - */ - isInitialized: function() { - return (this.hasPointers === true); - }, - - /** - * Register the start of a function call (or, at least, of its pointer) - * - * @param {String} sName The complete name of the function (ID) - * @type {void} - */ - registerStart: function(sName) { - if (this.isRunning) { - if (this.startBusy) { - if (sName) this.startQueue.push(sName); - this.startQueueTimer = setTimeout("jpf.profiler.registerStart()", 200); - } - else { - this.startBusy = true; - clearTimeout(this.startQueueTimer); - - var todo = (this.startQueue.length) ? this.startQueue : []; - this.startQueue = []; - if (sName) todo.push(sName); - - for (var i = 0; i < todo.length; i++) { - if (!this.stackTrace[todo[i]]) { - this.stackTrace[todo[i]] = { - called : 1, - fullName : sName, - internalExec: 0, - executions : [[new Date(), null]] - }; - } - else { - this.stackTrace[todo[i]].called++; - this.stackTrace[todo[i]].executions.push([new Date(), null]); - } - } - this.startBusy = false; - } - } - }, - - /** - * Register the end of a function call (or, at least, of its pointer). - * this means that the Profiling ends and running times will be recorded here. - * - * @param {String} sName The complete name of the function (ID) - * @type {void} - */ - registerEnd: function(sName) { - if (this.isRunning) { - if (!this.stackTrace[sName]) return; - if (this.endBusy) { - if (sName) - this.endQueue.push([sName, arguments.callee.caller.caller - ? arguments.callee.caller.caller.nameSelf - : null]); - this.endQueueTimer = setTimeout("jpf.profiler.registerEnd()", 200); - } - else { - this.endBusy = true; - clearTimeout(this.endQueueTimer); - - var todo = (this.endQueue.length) ? this.endQueue : []; - this.endQueue = []; - - if (sName) - todo.push([sName, arguments.callee.caller.caller - ? arguments.callee.caller.caller.nameSelf - : null]); - - for (var i = 0; i < todo.length; i++) { - iLength = this.stackTrace[todo[i][0]].executions.length - 1; - if (this.stackTrace[todo[i][0]].executions[iLength][1] == null) { - this.stackTrace[todo[i][0]].executions[iLength][1] = new Date(); - if (todo[i][1] && this.stackTrace[todo[i][1]]) { - this.stackTrace[todo[i][1]].internalExec += - this.stackTrace[todo[i][0]].executions[iLength][1] - - this.stackTrace[todo[i][0]].executions[iLength][0]; - } - } - } - this.endBusy = false; - } - } - }, - - /** - * Start a new cycle of the Profiler. - * - * @type {void} - */ - start: function() { - this.reset(); - this.isRunning = true; - }, - - /** - * Stop the current cycle of the Profiler and output the result. - * - * @type {mixed} - */ - stop: function() { - if (this.isRunning) this.runs++; - this.isRunning = false; - return this.report(); - }, - - /** - * Clear the stackTrace of the previous cycle and clarify that it's not - * running/ timing stuff anymore. - * - * @type {void} - */ - reset: function() { - delete this.stackTrace; - this.stackTrace = {}; - this.isRunning = false; - }, - - /** - * Prepare the raw data of a finished Profiler cycle and send it through - * to the report builder. - * - * @see Profiler#buildReport - * @type {mixed} - */ - report: function() { - var i, j, dur, stack, trace, callsNo; - - this.stackTrace.totalCalls = this.stackTrace.totalAvg = this.stackTrace.totalDur = 0; - - for (i in this.stackTrace) { - if (!this.stackTrace[i].fullName) continue; - - stack = this.stackTrace[i]; - callsNo = stack.executions.length; - stack.time = stack.max = 0; - stack.min = Infinity; - for (j = 0; j < stack.executions.length; j++) { - trace = stack.executions[j]; - dur = (trace[1] - trace[0]); - //@fixme: is [dur < 0] --> [dur = 0] a valid assumption? - if (isNaN(dur) || !isFinite(dur) || dur < 0) dur = 0; - - if (stack.max < dur) - stack.max = dur; - if (stack.min > dur) - stack.min = dur; - else if (stack.min == Infinity && stack.max > 0) - stack.min = stack.max; - - stack.time += dur; - } - stack.avg = stack.time / callsNo; - stack.avg = parseFloat(((isNaN(stack.avg) || !isFinite(stack.avg)) ? 0 : stack.avg).toFixed(this.precision)); - stack.min = parseFloat(((isNaN(stack.min) || !isFinite(stack.min)) ? 0 : stack.min).toFixed(this.precision)); - stack.max = parseFloat(stack.max.toFixed(this.precision)); - - this.stackTrace.totalCalls += callsNo; - this.stackTrace.totalDur += stack.time; - } - this.stackTrace.totalDur = parseFloat(this.stackTrace.totalDur.toFixed(this.precision)); - - this.stackTrace.totalAvg = parseFloat(this.stackTrace.totalDur / this.stackTrace.totalCalls); - this.stackTrace.totalAvg = parseFloat(this.stackTrace.totalAvg.toFixed(this.precision)); - - return this.buildReport(this.stackTrace); - }, - - /** - * Tranform the raw Profiler data into a nicely formatted report. - * Right now, I only implemented an xHTML output, no XML or JSON yet. - * @todo: add XML and/ or JSON standard output methods. - * - * @param {Object} stackTrace - * @param {Boolean} withContainer - * @type {String} - */ - buildReport: function(stackTrace, withContainer) { - if (typeof wihContainer == "undefined") withContainer = true; - - var out = withContainer ? ['<div id="profiler_report_' + this.runs + '">'] : ['']; - - var row0 = '#fff'; - var row1 = '#f5f5f5'; - var funcColor = '#006400'; - var active = "background: url(./core/debug/resources/tableHeaderSorted.gif) repeat-x top left;"; - - out.push('<table border="0" style="border: 1px solid #d7d7d7; width: 100%; margin: 0 4px 0 0; padding: 0;" cellpadding="2" cellspacing="0">\ - <tr style="\ - background:#d9d9d9 url(./core/debug/resources/tableHeader.gif) repeat-x top left;\ - height: 16px;\ - cursor: hand;\ - cursor: pointer;\ - ">\ - <th style="\ - border-right: 1px solid #9c9c9c;\ - border-left: 1px solid #d9d9d9;\ - border-bottom: 1px solid #9c9c9c;\ - padding: 0; margin: 0;', - (this.sortMethod == jpf.profiler.SORT_BY_FUNCTIONNAME ? active : ""), - '" rel="3" \ - onclick="jpf.debugwin.resortResult(this);" \ - title="" width="110">Function</th>\ - <th style="\ - border-right: 1px solid #9c9c9c;\ - border-left: 1px solid #d9d9d9;\ - border-bottom: 1px solid #9c9c9c;\ - padding: 0; margin: 0;', - (this.sortMethod == jpf.profiler.SORT_BY_CALLS ? active : ""), - '" rel="1" \ - onclick="jpf.debugwin.resortResult(this);"\ - title="Number of times function was called.">Calls</th>\ - <th style="\ - border-right: 1px solid #9c9c9c;\ - border-left: 1px solid #d9d9d9;\ - border-bottom: 1px solid #9c9c9c;\ - padding: 0; margin: 0;', - (this.sortMethod == jpf.profiler.SORT_BY_PERCENTAGE ? active : ""), - '" rel="2" \ - onclick="jpf.debugwin.resortResult(this);" \ - title="Percentage of time spent on this function.">Percentage</th>\ - <th style="\ - border-right: 1px solid #9c9c9c;\ - border-left: 1px solid #d9d9d9;\ - border-bottom: 1px solid #9c9c9c;\ - padding: 0; margin: 0;', - (this.sortMethod == jpf.profiler.SORT_BY_OWNTIME ? active : ""), - '" rel="8" \ - onclick="jpf.debugwin.resortResult(this);" \ - title="Time spent in function, excluding nested calls.">Own Time</th>\ - <th style="\ - border-right: 1px solid #9c9c9c;\ - border-left: 1px solid #d9d9d9;\ - border-bottom: 1px solid #9c9c9c;\ - padding: 0; margin: 0;', - (this.sortMethod == jpf.profiler.SORT_BY_TIME ? active : ""), - '" rel="4" \ - onclick="jpf.debugwin.resortResult(this);" \ - title="Time spent in function, including nested calls.">Time</th>\ - <th style="\ - border-right: 1px solid #9c9c9c;\ - border-left: 1px solid #d9d9d9;\ - border-bottom: 1px solid #9c9c9c;\ - padding: 0; margin: 0;', - (this.sortMethod == jpf.profiler.SORT_BY_AVERAGE ? active : ""), - '" rel="5" \ - onclick="jpf.debugwin.resortResult(this);" \ - title="Average time, including function calls.">Avg</th>\ - <th style="\ - border-right: 1px solid #9c9c9c;\ - border-left: 1px solid #d9d9d9;\ - border-bottom: 1px solid #9c9c9c;\ - padding: 0; margin: 0;', - (this.sortMethod == jpf.profiler.SORT_BY_MINIMUM ? active : ""), - '" rel="6" \ - onclick="jpf.debugwin.resortResult(this);" \ - title="Minimum time, including function calls.">Min</th>\ - <th style="\ - border-right: 1px solid #9c9c9c;\ - border-left: 1px solid #d9d9d9;\ - border-bottom: 1px solid #9c9c9c;\ - padding: 0; margin: 0;', - (this.sortMethod == jpf.profiler.SORT_BY_MAXIMUM ? active : ""), - '" rel="7" \ - onclick="jpf.debugwin.resortResult(this);" \ - title="Maximum time, including function calls.">Max</th>\ - </tr>'); - - var rowColor, sortedStack = this.sortStack(stackTrace); - for (i = 0; i < sortedStack.length; i++) { - stack = stackTrace[sortedStack[i][0]]; - rowColor = (i % 2 == 0) ? row0 : row1; - out.push('<tr style="background-color: ', rowColor, '; padding: 0; margin: 0; ">\ - <td class="functionname" style="\ - color: ', funcColor, ';\ - font-family: Monaco, Courier New;\ - font-size: 10px;\ - ">' + stack.fullName + '</td>\ - <td class="callscount">' + stack.executions.length + '</td>\ - <td class="duration_percentage">' + stack.perc + '%</td>\ - <td class="duration_owntime">' + (stack.time - stack.internalExec) + 'ms</td>\ - <td class="duration_time">' + stack.time + 'ms</td>\ - <td class="duration_average">' + stack.avg + 'ms</td>\ - <td class="duration_min">' + stack.min + 'ms</td>\ - <td class="duration_max">' + stack.max + 'ms</td>\ - </tr>'); - } - - out.push('</table>'); - if (withContainer) - out.push('</div>'); - - this.previousStack = stackTrace; - return { - html : out.join(''), - total : stackTrace.totalCalls, - duration: stackTrace.totalDur - }; - }, - - /** - * Apply sorting to a stacktrace of a finished cycle. This function also - * implements the calculation of percentages for each running stack. - * The sorting order is configurable (ascending or descending). - * Sorting methods: - * SORT_BY_CALLS - number of times each function is called - * SORT_BY_PERCENTAGE - relative amount of time each function call consumed, compared to the total cycle running time. DEFAULT. - * SORT_BY_FUNCTIONNAME - alphabetical by name of function. - * SORT_BY_TIME - time it took for the function itself to finish a call, including the waits for child functions - * SORT_BY_AVERAGE - time it took for a function to finish its call - including the waits for child functions - devided by the total number of calls. - * SORT_BY_MINIMUM - lowest recorded time it took for a function to finish its call - including the waits for child functions. - * SORT_BY_MAXIMUM - highest recorded time it took for a function to finish its call - including the waits for child functions. - * SORT_BY_OWNTIME - time it took for the function itself to finish a call, excluding the waits for child functions - * - * @param {Object} stackTrace to (re)sort - * @type {Array} - */ - sortStack: function(stackTrace) { - var i, stack, aSorted = []; - - for (i in stackTrace) { - if (!stackTrace[i].fullName) continue; - stack = stackTrace[i]; - stack.perc = 100 - Math.round((Math.abs(stack.time - stackTrace.totalDur) / stackTrace.totalDur) * 100); - - switch (this.sortMethod) { - case jpf.profiler.SORT_BY_CALLS : - aSorted.push([i, (stack.executions.length - 1)]); - break; - default: - case jpf.profiler.SORT_BY_PERCENTAGE : - aSorted.push([i, stack.perc]); - break; - case jpf.profiler.SORT_BY_FUNCTIONNAME : - aSorted.push([i, stack.fullName.toLowerCase()]); - break; - case jpf.profiler.SORT_BY_TIME : - aSorted.push([i, stack.time]); - break; - case jpf.profiler.SORT_BY_AVERAGE : - aSorted.push([i, stack.avg]); - break; - case jpf.profiler.SORT_BY_MINIMUM : - aSorted.push([i, stack.min]); - break; - case jpf.profiler.SORT_BY_MAXIMUM : - aSorted.push([i, stack.max]); - break; - case jpf.profiler.SORT_BY_OWNTIME : - aSorted.push([i, (stack.time - stack.internalExec)]); - break; - } - } - - return aSorted.sort((this.sortMethod == jpf.profiler.SORT_BY_FUNCTIONNAME) - ? this.sortingHelperAsc - : this.sortingHelperDesc); - }, - - /** - * Sort the last known complete stackTrace again, with a new method - * - * @param {Number} sortMethod to sort the stack with - * @type {String} - */ - resortStack: function(sortMethod) { - if (this.previousStack) { - this.sortMethod = parseInt(sortMethod); - return this.buildReport(this.previousStack, false); - } - return ""; - }, - - /** - * Provide the ascending sorting order to the report generator - * - * @param {mixed} a Variable to be compared - * @param {mixed} b Variable next in line to be compared - * @type {Number} - */ - sortingHelperAsc: function(a, b) { - if (a[1] < b[1]) - return -1; - else if (a[1] > b[1]) - return 1; - else - return 0; - }, - - /** - * Provide the descending sorting order to the report generator - * - * @param {mixed} a Variable to be compared - * @param {mixed} b Variable next in line to be compared - * @type {Number} - */ - sortingHelperDesc: function(a, b) { - if (a[1] > b[1]) - return -1; - else if (a[1] < b[1]) - return 1; - else - return 0; - }, - - /** - * Try to retrieve the name of a function from the object itself - * - * @param {Function} funcPointer Variable next in line to be compared - * @type {String} - * @deprecated - */ - getFunctionName: function(funcPointer) { - var regexpResult = funcPointer.toString().match(/function(\s*)(\w*)/); - if (regexpResult && regexpResult.length >= 2 && regexpResult[2]) { - return regexpResult[2]; - } - return 'anonymous'; - } -}; - -jpf.profiler.SORT_BY_CALLS = 1; -jpf.profiler.SORT_BY_PERCENTAGE = 2; -jpf.profiler.SORT_BY_FUNCTIONNAME = 3; -jpf.profiler.SORT_BY_TIME = 4; -jpf.profiler.SORT_BY_AVERAGE = 5; -jpf.profiler.SORT_BY_MINIMUM = 6; -jpf.profiler.SORT_BY_MAXIMUM = 7; -jpf.profiler.SORT_BY_OWNTIME = 8; - -jpf.profiler.BLACKLIST = { - 'jpf.profiler' : 1 -}; - -/** - * Transform a generic function to be Profile-able, independent of its implementation. - * - * @type {Function} - */ -var Profiler_functionTemplate = function() { - return function() { - jpf.profiler.registerStart(arguments.callee.nameSelf); - var ret = jpf.profiler.pointers['pointer_to_' + arguments.callee.nameSelf].apply(this, arguments); - jpf.profiler.registerEnd(arguments.callee.nameSelf); - return ret; - }; -}; - -/*FILEHEAD(/var/lib/jpf/src/elements/_base/basetab.js)SIZE(-1077090856)TIME(1238944817)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * Baseclass of a paged element. (i.e. {@link element.tab}, {@link element.pages}, {@link element.form}).
- *
- * @constructor
- * @baseclass
- * @allowchild page
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.8
- *
- * @event beforeswitch
- * cancellable: Prevents the page to become active.
- * object:
- * {Mixed} previous the name or number of the current page.
- * {Number} previousId the number of the current page.
- * {jpf.page} previousPage the current page.
- * {Mixed} next the name or number of the page the will become active.
- * {Number} nextId the number of the page the will become active.
- * {jpf.page} nextpage the page the will become active.
- * @event afterswitch
- * object:
- * {Mixed} previous the name or number of the previous page.
- * {Number} previousId the number of the previous page.
- * {jpf.page} previousPage the previous page.
- * {Mixed} next the name or number of the current page.
- * {Number} nextId the number of the the current page.
- * {jpf.page} nextpage the the current page.
- */
-jpf.BaseTab = function(){
- this.isPaged = true;
- this.$focussable = jpf.KEYBOARD;
- this.canHaveChildren = true;
-
- /**
- * Sets the current page of this element.
- * @param {mixed} page the name of numer of the page which is made active.
- */
- this.set = function(page, noEvent){
- if (noEvent)
- return this.$propHandlers["activepage"].call(this, page, noEvent);
-
- return this.setProperty("activepage", page);
- }
-
- var inited = false;
- var ready = false;
-
- /**** Properties and Attributes ****/
-
- this.$supportedProperties.push("activepage", "activepagenr");
-
- /**
- * @attribute {Number} activepagenr the child number of the active page.
- * Example
- * This example uses property binding to maintain consistency between a
- * dropdown which is used as a menu, and a pages element
- * <code>
- * <j:dropdown id="ddMenu">
- * <j:item value="0">Home</j:item>
- * <j:item value="1">General</j:item>
- * <j:item value="2">Advanced</j:item>
- * </j:drodown>
- *
- * <j:pages activepagenr="[ddMenu.value]">
- * <j:page>
- * <h1>Home Page</h1>
- * </j:page>
- * <j:page>
- * <h1>General Page</h1>
- * </j:page>
- * <j:page>
- * <h1>Advanced Page</h1>
- * </j:page>
- * </j:pages>
- * </code>
- */
- this.$propHandlers["activepagenr"] =
-
- /**
- * @attribute {String} activepage the name of the active page.
- * Example:
- * <code>
- * <j:tab activepage="general">
- * <j:page id="home">
- * ...
- * </j:page>
- * <j:page id="advanced">
- * ...
- * </j:page>
- * <j:page id="general">
- * ...
- * </j:page>
- * </j:tab>
- * </code>
- */
- this.$propHandlers["activepage"] = function(next, noEvent){
- if (!inited) return;
-
- var page, info = {};
- var page = this.$findPage(next, info);
-
- if (!page) {
- jpf.console.warn("Setting tab page which doesn't exist, \
- referenced by name: '" + next + "'");
-
- return false;
- }
-
- if (page.parentNode != this) {
- jpf.console.warn("Setting active page on page component which \
- isn't a child of this tab component. Cancelling.");
-
- return false;
- }
-
- if (!page.visible || page.disabled) {
- jpf.console.warn("Setting active page on page component which \
- is not visible or disabled. Cancelling.");
-
- return false;
- }
-
- //If page is given as first argument, let's use its position
- if (next.tagName) {
- next = info.position;
- this.activepage = page.name || next;
- }
-
- //Call the onbeforeswitch event;
- if (!noEvent) {
- var oEvent = {
- previous : this.activepage,
- previousId : this.activepagenr,
- previousPage : this.$activepage,
- next : next,
- nextId : info.position,
- nextpage : page
- };
-
- if (this.dispatchEvent("beforeswitch", oEvent) === false) {
- //Loader support
- if (this.hideLoader)
- this.hideLoader();
-
- return false;
- }
- }
-
- //Maintain an activepagenr property (not reentrant)
- this.activepagenr = info.position;
- this.setProperty("activepagenr", info.position);
-
- //Deactivate the current page, if any, and activate the new one
- if (this.$activepage)
- this.$activepage.$deactivate();
-
- page.$activate();
- this.$activepage = page;
- this.scrollIntoView(page);
-
- //Loader support
- if (this.hideLoader) {
- if (page.isRendered)
- this.hideLoader();
- else {
- //Delayed rendering support
- page.addEventListener("afterrender", function(){
- this.parentNode.hideLoader();
- });
- }
- }
-
- if (!noEvent) {
- if (page.isRendered)
- this.dispatchEvent("afterswitch", oEvent);
- else {
- //Delayed rendering support
- page.addEventListener("afterrender", function(){
- this.parentNode.dispatchEvent("afterswitch", oEvent);
- });
- }
- }
-
- return true;
- };
-
- /**** Public methods ****/
-
- /**
- * Retrieves an array of all the page elements of this element.
- */
- this.getPages = function(){
- var r = [], nodes = this.childNodes;
- for (var i = 0, l = nodes.length; i < l; i++) {
- if (nodes[i].tagName == "page")
- r.push(nodes[i]);
- }
- return r;
- };
-
- /**
- * Retrieves a page element by it's name or child number
- * @param {mixed} nameOrId the name or child number of the page element to retrieve.
- * @return {Page} the found page element.
- */
- this.getPage = function(nameOrId){
- return !jpf.isNot(nameOrId)
- && this.$findPage(nameOrId) || this.$activepage;
- };
-
- /**
- * Add a new page element
- * @param {String} [caption] the text displayed on the button of the page.
- * @param {String} [name] the name of the page which is can be referenced by.
- * @return {page} the created page element.
- */
- this.add = function(caption, name){
- var page = jpf.document.createElement("page");
- if (name)
- page.setAttribute("id", name);
- page.setAttribute("caption", caption);
- this.appendChild(page);
- this.scrollIntoView(page);
- return page;
- };
-
- /**
- * Removes a page element from this element.
- * @param {mixed} nameOrId the name or child number of the page element to remove.
- * @return {Page} the removed page element.
- */
- this.remove = function(nameOrId){
- var page = this.$findPage(nameOrId);
- if (!page)
- return false;
-
- page.removeNode();
- this.setScrollerState();
- return page;
- };
-
-
- var SCROLLANIM_INIT = {
- scrollOn: false,
- steps : 15,
- interval: 10,
- size : 0,
- left : 0
- };
- var bAnimating = false;
-
- /**
- * Set the state scroller buttons: enabled, disabled or completely hidden,
- * depending on the state of the tab buttons
- *
- * @param {Boolean} [bOn] Indicates whether to turn the scroll buttons on or off
- * @param {Number} [iBtns] Specifies the buttons to set the state of. Can be SCROLL_LEFT, SCROLL_RIGHT or SCROLL_BOTH
- * @type {void}
- */
- this.setScrollerState = function(bOn, iBtns) {
- if (!ready || !this.$hasButtons || !this.oScroller) return;
-
- if (typeof bOn == "undefined"){
- bOn = (this.oButtons.offsetWidth > this.oExt.offsetWidth);
- iBtns = jpf.BaseTab.SCROLL_BOTH;
- }
-
- if (iBtns & jpf.BaseTab.SCROLL_BOTH && bOn !== SCROLLANIM_INIT.scrollOn) {
- // in case of HIDING the scroller: check if the anim stuff has reverted
- SCROLLANIM_INIT.scrollOn = bOn;
- if (!bOn)
- this.oButtons.style.left = SCROLLANIM_INIT.left + "px";
- //else
- // TODO: scroll active tab into view if it becomes hidden beneath scroller node(s)
- }
-
- this.oScroller.style.display = (iBtns & jpf.BaseTab.SCROLL_BOTH && !bOn)
- ? "none"
- : "";
- if (typeof iBtns == "undefined")
- iBtns = jpf.BaseTab.SCROLL_BOTH;
- if ((iBtns & jpf.BaseTab.SCROLL_LEFT) || (iBtns & jpf.BaseTab.SCROLL_BOTH))
- this.$setStyleClass(this.oLeftScroll, bOn ? "" : "disabled",
- bOn ? ["disabled"] : null);
- if ((iBtns & jpf.BaseTab.SCROLL_RIGHT) || (iBtns & jpf.BaseTab.SCROLL_BOTH))
- this.$setStyleClass(this.oRightScroll, bOn ? "" : "disabled",
- bOn ? ["disabled"] : null);
- };
-
- /**
- * Corrects the state of the scroller buttons when the state of external
- * components change, like on a resize event of a window.
- *
- * @type {void}
- */
- this.correctScrollState = function() {
- if (!ready || !this.$hasButtons || !this.oScroller) return;
-// if (this.oButtons.offsetLeft < 0)
-// this.oButtons.style.left = (this.oExt.offsetWidth
-// - this.oButtons.offsetWidth - this.oScroller.offsetWidth) + "px";
- this.setScrollerState();
- };
-
- /**
- * Retrieves the utmost left or right boundaries of the tab buttons strip that
- * can be scrolled to. The tabs cannot scroll any further than these boundaries
- *
- * @param {Number} dir Determines which boundary side to look at; SCROLL_LEFT or SCROLL_RIGHT
- * @param {Boolan} [useCache] Used only when tabs are draggable. Not implemented.
- * @type {Number}
- */
- function getAnimationBoundary(dir, useCache) {
- if (SCROLLANIM_INIT.size <= 0) {
- SCROLLANIM_INIT.left = this.oButtons.offsetLeft;
- SCROLLANIM_INIT.size = Math.round(this.firstChild.oButton.offsetWidth);
- }
- if (dir & jpf.BaseTab.SCROLL_LEFT) {
- return SCROLLANIM_INIT.left;
- }
- else if (dir & jpf.BaseTab.SCROLL_RIGHT) {
- // TODO: support Drag n Drop of tabs...
- //if (typeof useCache == "undefined") useCache = false;
- //if (!tabcontrol.drag) tabcontrol.drag = {};
- //if (useCache && tabcontrol.drag.boundCache)
- // return tabcontrol.drag.boundCache;
- var oNode = this.oButtons.childNodes[this.oButtons.childNodes.length - 1];
-
- return this.oExt.offsetWidth - (oNode.offsetLeft + oNode.offsetWidth
- + (this.oScroller.offsetWidth + 4));// used to be tabcontrol.drag.boundCache;
- }
- }
-
- /**
- * Event handler; executed when the user pressed one of the two scroll buttons
- * (left or right one). If the tab-buttons strip may/ can be scrolled, the
- * respective behavior is called.
- *
- * @param {Event} e Event object, usually a mousedown event from a scroller-button
- * @param {Number} dir Direction to scroll; SCROLL_LEFT or SCROLL_RIGHT
- * @type {void}
- */
- this.scroll = function(e, dir) {
- if (!ready || !this.$hasButtons || !this.oScroller) return;
- if (!e) e = window.event;
- if (bAnimating && e.type != "dblclick") return;
- bAnimating = true;
-
- if (typeof dir == "undefined")
- dir = jpf.BaseTab.SCROLL_LEFT;
-
- jpf.tween.clearQueue(this.oButtons, true);
- var iCurrentLeft = this.oButtons.offsetLeft;
-
- //get maximum left offset for either direction
- var iBoundary = getAnimationBoundary.call(this, dir);
- if (dir & jpf.BaseTab.SCROLL_LEFT) {
- if (iCurrentLeft === iBoundary) {
- bAnimating = false;
- return this.setScrollerState(false, jpf.BaseTab.SCROLL_LEFT);
- }
- //one scroll animation scrolls by a SCROLLANIM_INIT.size px.
- var iTargetLeft = iCurrentLeft + (e.type == "dblclick"
- ? SCROLLANIM_INIT.size * 3
- : SCROLLANIM_INIT.size);
- if (iTargetLeft > iBoundary)
- iTargetLeft = iBoundary;
-
- if (iTargetLeft === iBoundary)
- this.setScrollerState(false, jpf.BaseTab.SCROLL_LEFT);
- this.setScrollerState(true, jpf.BaseTab.SCROLL_RIGHT);
-
- //start animated scroll to the left
- jpf.tween.single(this.oButtons, {
- steps : SCROLLANIM_INIT.steps,
- interval: SCROLLANIM_INIT.interval,
- from : iCurrentLeft,
- to : iTargetLeft,
- type : "left",
- anim : jpf.tween.NORMAL,
- onfinish: function() { bAnimating = false; }
- });
- }
- else if (dir & jpf.BaseTab.SCROLL_RIGHT) {
- this.setScrollerState(true);
- var _self = this;
- if (iCurrentLeft === iBoundary) {
- return jpf.tween.single(this.oButtons, {
- steps : SCROLLANIM_INIT.steps,
- interval: SCROLLANIM_INIT.interval,
- from : iCurrentLeft,
- to : iCurrentLeft - 24,
- type: "left",
- anim: jpf.tween.EASEOUT,
- onfinish: function(oNode, options) {
- jpf.tween.single(oNode, {
- steps : SCROLLANIM_INIT.steps,
- interval: SCROLLANIM_INIT.interval,
- from : iCurrentLeft - 24,
- to : iCurrentLeft,
- type : "left",
- anim : jpf.tween.EASEIN,
- onfinish: function() {
- _self.setScrollerState(false, jpf.BaseTab.SCROLL_RIGHT);
- bAnimating = false;
- }
- });
- }
- });
- }
- //one scroll animation scrolls by a SCROLLANIM_INIT.size px.
- var iTargetLeft = iCurrentLeft - (e.type == "dblclick"
- ? SCROLLANIM_INIT.size * 3
- : SCROLLANIM_INIT.size);
- //make sure we don't scroll more to the right than the
- //maximum left:
- if (iTargetLeft < iBoundary)
- iTargetLeft = iBoundary;
- //start animated scroll to the right
- jpf.tween.single(this.oButtons, {
- steps : SCROLLANIM_INIT.steps,
- interval: SCROLLANIM_INIT.interval,
- from : iCurrentLeft,
- to : iTargetLeft,
- type : "left",
- anim : jpf.tween.NORMAL,
- onfinish: function() { bAnimating = false; }
- });
- }
- };
-
- /**
- * If a tabpage is outside of the users' view, this function scrolls that
- * tabpage into view smoothly.
- *
- * @param {j:page} oPage The page to scroll into view
- * @type {void}
- */
- this.scrollIntoView = function(oPage) {
- bAnimating = false;
- if (!ready || !this.$hasButtons || !this.oScroller)
- return;
- bAnimating = true;
- if (this.oButtons.offsetWidth < this.oExt.offsetWidth)
- return this.setScrollerState(false);
-
- var iTabLeft = oPage.oButton.offsetLeft;
- var iTabWidth = oPage.oButton.offsetWidth;
- var iCurrentLeft = this.oButtons.offsetLeft;
-
- if (SCROLLANIM_INIT.size <= 0) {
- SCROLLANIM_INIT.left = this.oButtons.offsetLeft;
- SCROLLANIM_INIT.size = Math.round(this.firstChild.oButton.offsetWidth);
- }
- this.oButtons.style.left = iCurrentLeft;
-
- var iRealWidth = this.oExt.offsetWidth,
- iScrollCorr = this.oScroller.offsetWidth + 4,
- iTargetLeft = null;
-
- if ((iTabLeft + iTabWidth) > ((iRealWidth - iScrollCorr) - iCurrentLeft)) //scroll to the right
- iTargetLeft = (-(iTabLeft - SCROLLANIM_INIT.left)
- + (iRealWidth - iTabWidth - iScrollCorr));
- else if ((iCurrentLeft + iTabLeft) < SCROLLANIM_INIT.left) //sroll to the left
- iTargetLeft = SCROLLANIM_INIT.left - iTabLeft;
-
- if (iTargetLeft !== null) {
- this.setScrollerState(true);
- jpf.tween.clearQueue(this.oButtons, true);
-
- jpf.tween.single(this.oButtons, {
- steps : SCROLLANIM_INIT.steps,
- interval: SCROLLANIM_INIT.interval,
- from : iCurrentLeft,
- to : iTargetLeft,
- type : "left",
- anim : jpf.tween.NORMAL,
- onfinish: function() { bAnimating = false; }
- });
- }
- else
- bAnimating = false;
- };
-
-
- /**** DOM Hooks ****/
-
- this.$domHandlers["removechild"].push(function(jmlNode, doOnlyAdmin){
- if (doOnlyAdmin)
- return;
-
- if (this.firstChild == jmlNode && jmlNode.nextSibling)
- jmlNode.nextSibling.$first();
- if (this.lastChild == jmlNode && jmlNode.previousSibling)
- jmlNode.previousSibling.$last();
-
- if (this.$activepage == jmlNode) {
- if (jmlNode.nextSibling || jmlNode.previousSibling)
- this.set(jmlNode.nextSibling || jmlNode.previousSibling);
- else {
- this.setScrollerState();
- this.$activepage =
- this.activepage =
- this.activepagenr = null;
- }
- }
- else
- this.setScrollerState();
- });
-
- this.$domHandlers["insert"].push(function(jmlNode, beforeNode, withinParent){
- if (jmlNode.tagName != "page")
- return;
-
- if (!beforeNode) {
- if (this.lastChild)
- this.lastChild.$last(true);
- jmlNode.$last();
- }
-
- if(!this.firstChild || beforeNode == this.firstChild) {
- if (this.firstChild)
- this.firstChild.$first(true);
- jmlNode.$first();
- }
-
- if (this.$activepage) {
- var info = {};
- this.$findPage(this.$activepage, info);
-
- if (this.activepagenr != info.position) {
- if (parseInt(this.activepage) == this.activepage) {
- this.activepage = info.position;
- this.setProperty("activepage", info.position);
- }
- this.activepagenr = info.position;
- this.setProperty("activepagenr", info.position);
- }
- }
- else if (!this.$activepage)
- this.set(jmlNode);
- });
-
- /**** Private state handling functions ****/
-
- this.$findPage = function(nameOrId, info){
- var node, nodes = this.childNodes;
- for (var t = 0, i = 0, l = nodes.length; i < l; i++) {
- node = nodes[i];
- if (node.tagName == "page" && (t++ == nameOrId
- || (nameOrId.tagName && node || node.name) == nameOrId)) {
- if (info)
- info.position = t - 1;
- return node;
- }
- }
-
- return null;
- };
-
- this.$enable = function(){
- var nodes = this.childNodes;
- for (var i = 0, l = nodes.length; i < l; i++) {
- if (nodes[i].enable)
- nodes[i].enable();
- }
- };
-
- this.$disable = function(){
- var nodes = this.childNodes;
- for (var i = 0, l = nodes.length; i < l; i++) {
- if (nodes[i].disable)
- nodes[i].disable();
- }
- };
-
- /**** Keyboard support ****/
-
-
- this.addEventListener("keydown", function(e){
- if (!this.$hasButtons)
- return;
-
- var key = e.keyCode;
- var ctrlKey = e.ctrlKey;
- var shiftKey = e.shiftKey;
-
- switch (key) {
- case 9:
- break;
- case 13:
- break;
- case 32:
- break;
- case 37:
- //LEFT
- var pages = this.getPages();
- prevPage = this.activepagenr - 1;
- while (prevPage >= 0 && !pages[prevPage].visible)
- prevPage--;
-
- if (prevPage >= 0)
- this.setProperty("activepage", prevPage)
- break;
- case 39:
- //RIGHT
- var pages = this.getPages();
- nextPage = this.activepagenr + 1;
- while (nextPage < pages.length && !pages[nextPage].visible)
- nextPage++;
-
- if (nextPage < pages.length)
- this.setProperty("activepage", nextPage)
- break;
- default:
- return;
- }
- //return false;
- }, true);
-
-
- /**** Init ****/
-
- this.inherit(jpf.Presentation); /** @inherits jpf.Presentation */
-
- this.editableParts = {"button" : [["caption", "@caption"]]};
-
- this.$loadChildren = function(callback){
- var page = false, f = false, i, _self = this;
-
- inited = true;
-
- if (this.$hasButtons) {
- this.oButtons = this.$getLayoutNode("main", "buttons", this.oExt);
- this.oButtons.setAttribute("id", this.uniqueId + "_buttons");
- }
-
- this.oPages = this.$getLayoutNode("main", "pages", this.oExt);
-
- // add scroller node(s)
- this.oScroller = this.$getLayoutNode("main", "scroller", this.oPages);
- if (this.oScroller) {
- this.oLeftScroll = this.oScroller.firstChild;
- this.oRightScroll = this.oScroller.lastChild;
- var sLeft = 'var o=jpf.lookup(' + this.uniqueId + ');\
- if (this.className.indexOf("disabled") == -1) {\
- o.$setStyleClass(this, "click");\
- o.scroll(event, jpf.BaseTab.SCROLL_LEFT);\
- }\
- if(!jpf.isSafariOld) this.onmouseout()';
- var sRight = 'var o=jpf.lookup(' + this.uniqueId + ');\
- if (this.className.indexOf("disabled") == -1) {\
- o.$setStyleClass(this, "click");\
- o.scroll(event, jpf.BaseTab.SCROLL_RIGHT);\
- }\
- if(!jpf.isSafariOld) this.onmouseout()'
- this.oLeftScroll.setAttribute("onmousedown", sLeft);
- this.oLeftScroll.setAttribute("ondblclick", sLeft);
- this.oRightScroll.setAttribute("onmousedown", sRight);
- this.oRightScroll.setAttribute("ondblclick", sRight);
- [this.oLeftScroll, this.oRightScroll].forEach(function(elBtn) {
- elBtn.setAttribute("onmouseover", 'var o = jpf.lookup('
- + _self.uniqueId + ');\
- if(!this.disabled) o.$setStyleClass(this, "over");');
- elBtn.setAttribute("onmouseout", 'var o = jpf.lookup('
- + _self.uniqueId + ');\
- if (!this.disabled) o.$setStyleClass(this, "", ["over"]);');
- elBtn.setAttribute("onmouseup", 'var o=jpf.lookup(' + _self.uniqueId + ');\
- o.$setStyleClass(this, "", ["click"]);');
- });
- }
-
- //Skin changing support
- if (this.oInt) {
- //jpf.JmlParser.replaceNode(oPages, this.oPages);
- this.oInt = this.oPages;
- page = true;
-
- var node, nodes = this.childNodes;
- for (i = 0; i < nodes.length; i++) {
- node = nodes[i];
- node.$draw(true);
- node.$skinchange();
- node.$loadJml();
- }
- }
- else {
- this.oInt = this.oPages;
-
- //Let's not parse our children, when we've already have them
- if (this.childNodes.length) {
- ready = true;
- this.setScrollerState();
- return;
- }
-
- //Build children
- var node, nodes = this.$jml.childNodes;
- for (i = 0; i < nodes.length; i++) {
- node = nodes[i];
- if (node.nodeType != 1) continue;
-
- var tagName = node[jpf.TAGNAME];
- if ("page|case".indexOf(tagName) > -1) {
- page = new jpf.page(this.oPages, tagName).loadJml(node, this);
-
- //Set first page marker
- if (!f) page.$first(f = page);
-
- //Call callback
- if (callback)
- callback.call(page, node);
- }
- else if(tagName == "comment"){
- //ignore
- }
- else if (callback) {
- callback(tagName, node);
- }
- else {
- throw new Error(jpf.formatErrorString(0, this,
- "Parsing children of tab component",
- "Unknown component found as child of tab", node));
- }
- }
-
- //Set last page marker
- if (page !== f)
- page.$last();
- }
-
- //Set active page
- if (page) {
- this.activepage = (this.activepage !== undefined
- ? this.activepage
- : this.activepagenr) || 0;
- this.$propHandlers.activepage.call(this, this.activepage);
- }
- else {
- jpf.JmlParser.parseChildren(this.$jml, this.oExt, this);
- this.isPages = false;
- }
-
- ready = true;
- window.setTimeout(function() {
- _self.setScrollerState();
- }, 0);
- };
-};
-
-jpf.BaseTab.SCROLL_LEFT = 0x0001;
-jpf.BaseTab.SCROLL_RIGHT = 0x0002;
-jpf.BaseTab.SCROLL_BOTH = 0x0004;
-
-/**
- * A page in a paged element. (i.e. a page in a {@link element.tab})
- *
- * @constructor
- * @define page
- * @allowchild {elements}, {anyjml}
- * @addnode elements
- *
- * @inherits jpf.DelayedRender
- *
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.8
- */
-jpf.page = jpf.component(jpf.NODE_HIDDEN, function(){
- this.visible = true;
- this.canHaveChildren = 2;
- this.$focussable = false;
-
- this.editableParts = {"button" : [["caption", "@caption"]]};
-
- /**
- * Sets the caption of the button of this element.
- * @param {String} caption the text displayed on the button of this element.
- */
- this.setCaption = function(caption){
- this.setProperty("caption", caption);
- };
-
- /**** Delayed Render Support ****/
-
- //Hack
- this.addEventListener("beforerender", function(){
- this.parentNode.dispatchEvent("beforerender", {
- page : this
- });
- });
-
- this.addEventListener("afterrender", function(){
- this.parentNode.dispatchEvent("afterrender", {
- page : this
- });
- });
-
- /**** Properties ****/
-
- this.$booleanProperties["visible"] = true;
- this.$booleanProperties["fake"] = true;
- this.$supportedProperties.push("fake", "caption", "icon", "type");
-
- /**
- * @attribute {String} caption the text displayed on the button of this element.
- */
- this.$propHandlers["caption"] = function(value){
- if (!this.parentNode)
- return;
-
- var node = this.parentNode
- .$getLayoutNode("button", "caption", this.oButton);
-
- if (node.nodeType == 1)
- node.innerHTML = value;
- else
- node.nodeValue = value;
- };
-
- this.$propHandlers["visible"] = function(value){
- if (!this.parentNode)
- return;
-
- if (value) {
- this.oExt.style.display = "";
- if (this.parentNode.$hasButtons)
- this.oButton.style.display = "block";
-
- if (!this.parentNode.$activepage) {
- this.parentNode.set(this);
- }
- }
- else {
- if (this.$active) {
- this.$deactivate();
-
- // Try to find a next page, if any.
- var nextPage = this.parentNode.activepagenr + 1;
- var pages = this.parentNode.getPages()
- var len = pages.length
- while (nextPage < len && !pages[nextPage].visible)
- nextPage++;
-
- if (nextPage == len) {
- // Try to find a previous page, if any.
- nextPage = this.parentNode.activepagenr - 1;
- while (nextPage >= 0 && len && !pages[nextPage].visible)
- nextPage--;
- }
-
- if (nextPage >= 0)
- this.parentNode.set(nextPage);
- else {
- this.parentNode.activepage =
- this.parentNode.activepagenr =
- this.parentNode.$activepage = null;
- }
- }
-
- this.oExt.style.display = "none";
- if (this.parentNode.$hasButtons)
- this.oButton.style.display = "none";
- }
- };
-
- /**
- * @attribute {Boolean} fake whether this page actually contains elements or
- * only provides a button in the paged parent element.
- */
- this.$propHandlers["fake"] = function(value){
- if (this.oExt) {
- jpf.removeNode(this.oExt);
- this.oInt = this.oExt = null;
- }
- };
-
- this.$propHandlers["type"] = function(value) {
- this.setProperty("fake", true);
- this.relPage = this.parentNode.getPage(value);
- if (this.$active)
- this.$activate();
- };
-
- /**** DOM Hooks ****/
-
- this.$domHandlers["remove"].push(function(doOnlyAdmin){
- if (this.oButton) {
- if (position & 1)
- this.parentNode.$setStyleClass(this.oButton, "", ["firstbtn", "firstcurbtn"]);
- if (position & 2)
- this.parentNode.$setStyleClass(this.oButton, "", ["lastbtn"]);
- }
-
- if (!doOnlyAdmin) {
- if (this.oButton)
- this.oButton.parentNode.removeChild(this.oButton);
-
- if (this.parentNode.$activepage == this) {
- if (this.oButton)
- this.parentNode.$setStyleClass(this.oButton, "", ["curbtn"]);
- this.parentNode.$setStyleClass(this.oExt, "", ["curpage"]);
- }
- }
- });
-
- this.$domHandlers["reparent"].push(function(beforeNode, pNode, withinParent){
- if (!this.$jmlLoaded)
- return;
-
- if (!withinParent && this.skinName != pNode.skinName) {
- //@todo for now, assuming dom garbage collection doesn't leak
- this.$draw();
- this.$skinchange();
- this.$loadJml();
- }
- else if (this.oButton && pNode.$hasButtons)
- pNode.oButtons.insertBefore(this.oButton,
- beforeNode && beforeNode.oButton || null);
- });
-
- /**** Private state functions ****/
-
- var position = 0;
- this.$first = function(remove){
- if (remove) {
- position -= 1;
- this.parentNode.$setStyleClass(this.oButton, "",
- ["firstbtn", "firstcurbtn"]);
- }
- else {
- position = position | 1;
- this.parentNode.$setStyleClass(this.oButton, "firstbtn"
- + (this.parentNode.$activepage == this ? " firstcurbtn" : ""));
- }
- };
-
- this.$last = function(remove){
- if (remove) {
- position -= 2;
- this.parentNode.$setStyleClass(this.oButton, "", ["lastbtn"]);
- }
- else {
- position = position | 2;
- this.parentNode.$setStyleClass(this.oButton, "lastbtn");
- }
- };
-
- this.$deactivate = function(fakeOther){
- if (this.disabled)
- return false;
-
- this.$active = false
-
- if (this.parentNode.$hasButtons) {
- if (position > 0)
- this.parentNode.$setStyleClass(this.oButton, "", ["firstcurbtn"]);
- this.parentNode.$setStyleClass(this.oButton, "", ["curbtn"]);
- }
-
- if ((!this.fake || this.relPage) && !fakeOther)
- this.parentNode.$setStyleClass(this.fake
- ? this.relPage.oExt
- : this.oExt, "", ["curpage"]);
- };
-
- this.$activate = function(){
- if (this.disabled)
- return false;
-
- if (this.parentNode.$hasButtons) {
- if (position > 0)
- this.parentNode.$setStyleClass(this.oButton, "firstcurbtn");
- this.parentNode.$setStyleClass(this.oButton, "curbtn");
- }
-
- if (!this.fake || this.relPage) {
- this.parentNode.$setStyleClass(this.fake
- ? this.relPage.oExt
- : this.oExt, "curpage");
-
- if (jpf.layout)
- jpf.layout.forceResize(this.fake ? this.relPage.oInt : this.oInt);
- }
-
- this.$active = true;
-
- this.$render();
-
- if (!this.fake && jpf.isIE) {
- var cls = this.oExt.className;
- this.oExt.className = "rnd" + Math.random();
- this.oExt.className = cls;
- }
- };
-
- this.$skinchange = function(){
- if (this.caption)
- this.$propHandlers["caption"].call(this, this.caption);
-
- if (this.icon)
- this.$propHandlers["icon"].call(this, this.icon);
- };
-
- /**** Init ****/
-
- this.$draw = function(isSkinSwitch){
- this.skinName = this.parentNode.skinName;
-
- var sType = this.$jml.getAttribute("type")
- if (sType) {
- this.fake = true;
- this.relPage = this.parentNode.getPage(sType) || null;
- }
-
- if (this.parentNode.$hasButtons) {
- //this.parentNode.$removeEditable(); //@todo multilingual support is broken when using dom
-
- this.parentNode.$getNewContext("button");
- var elBtn = this.parentNode.$getLayoutNode("button");
- elBtn.setAttribute(this.parentNode.$getOption("main", "select") || "onmousedown",
- 'jpf.lookup(' + this.parentNode.uniqueId + ').set(jpf.lookup('
- + this.uniqueId + '));if(!jpf.isSafariOld) this.onmouseout()');
- elBtn.setAttribute("onmouseover", 'var o = jpf.lookup('
- + this.parentNode.uniqueId + ');if(jpf.lookup(' + this.uniqueId
- + ') != o.$activepage) o.$setStyleClass(this, "over");');
- elBtn.setAttribute("onmouseout", 'var o = jpf.lookup('
- + this.parentNode.uniqueId + '); o.$setStyleClass(this, "", ["over"]);');
- this.oButton = jpf.xmldb.htmlImport(elBtn, this.parentNode.oButtons);
-
- this.parentNode.$makeEditable("button", this.oButton, this.$jml);
-
- if (!isSkinSwitch && this.nextSibling && this.nextSibling.oButton)
- this.oButton.parentNode.insertBefore(this.oButton, this.nextSibling.oButton);
-
- this.oButton.host = this;
- }
-
- if (this.fake)
- return;
-
- if (this.oExt)
- this.oExt.parentNode.removeChild(this.oExt); //@todo mem leaks?
-
- this.oExt = this.parentNode.$getExternal("page",
- this.parentNode.oPages, null, this.$jml);
- this.oExt.host = this;
- };
-
- this.$loadJml = function(x){
- if (this.fake)
- return;
-
- if (this.oInt) {
- var oInt = this.parentNode
- .$getLayoutNode("page", "container", this.oExt);
- oInt.setAttribute("id", this.oInt.getAttribute("id"));
- this.oInt = jpf.JmlParser.replaceNode(oInt, this.oInt);
- }
- else {
- this.oInt = this.parentNode
- .$getLayoutNode("page", "container", this.oExt);
- jpf.JmlParser.parseChildren(this.$jml, this.oInt, this, true);
- }
- };
-
- this.$destroy = function(){
- if (this.oButton) {
- this.oButton.host = null;
- this.oButton = null;
- }
- };
-}).implement(
- jpf.DelayedRender
-);
-
- - -/*FILEHEAD(/var/lib/jpf/src/elements/_base/basebutton.js)SIZE(-1077090856)TIME(1238944817)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * Baseclass of an element that has one or two states and can be clicked on to
- * trigger an action. (i.e. {@link element.button} or {@link element.checkbox}).
- *
- * @constructor
- * @baseclass
- * @author Abe Ginner
- * @version %I%, %G%
- * @since 0.8
- *
- * @event click Fires when the user presses a mousebutton while over this element and then let's the mousebutton go.
- */
-
-jpf.BaseButton = function(pHtmlNode){
- var refKeyDown = 0; // Number of keys pressed.
- var refMouseDown = 0; // Mouse button down?
- var mouseOver = false; // Mouse hovering over the button?
- var mouseLeft = false; // Has the mouse left the control since pressing the button.
- var _self = this;
-
- /**** Properties and Attributes ****/
-
- /**
- * @attribute {string} background sets a multistate background. The arguments
- * are seperated by pipes '|' and are in the order of:
- * 'imagefilename|mapdirection|nrofstates|imagesize'
- * The mapdirection argument may have the value of 'vertical' or 'horizontal'.
- * The nrofstates argument specifies the number of states the iconfile contains:
- * 1 - normal
- * 2 - normal, hover
- * 3 - normal, hover, down
- * 4 - normal, hover, down, disabled
- * The imagesize argument specifies how high or wide each icon is inside the
- * map, depending of the mapdirection argument.
- *
- * Example:
- * A 3 state picture where each state is 16px high, vertically spaced
- * <code>
- * background="threestates.gif|vertical|3|16"
- * </code>
- */
- this.$propHandlers["background"] = function(value){
- var oNode = this.$getLayoutNode("main", "background", this.oExt);
- if (!oNode)
- return jpf.console.warn("No background defined in the Button skin", "button");
-
- if (value) {
- var b = value.split("|");
- this.$background = b.concat(["vertical", 2, 16].slice(b.length - 1));
-
- oNode.style.backgroundImage = "url(" + this.mediaPath + b[0] + ")";
- oNode.style.backgroundRepeat = "no-repeat";
- }
- else {
- oNode.style.backgroundImage = "";
- oNode.style.backgroundRepeat = "";
- this.$background = null;
- }
- }
-
- /**** Keyboard Support ****/
-
- this.addEventListener("keydown", function(e){
- var key = e.keyCode;
- var ctrlKey = e.ctrlKey;
- var shiftKey = e.shiftKey;
-
- switch (key) {
- case 13:
- if (this.tagName != "checkbox")
- this.oExt.onmouseup(e.htmlEvent, true);
- break;
- case 32:
- if (!e.htmlEvent.repeat) { // Only when first pressed, not on autorepeat.
- refKeyDown++;
- return this.$updateState(e.htmlEvent);
- } else
- return false;
- }
- }, true);
-
- this.addEventListener("keyup", function(e){
- var key = e.keyCode;
-
- switch (key) {
- case 32:
- refKeyDown--;
-
- if (refKeyDown < 0) {
- refKeyDown = 0;
- return;
- }
-
- if (refKeyDown + refMouseDown == 0 && !this.disabled) {
- this.oExt.onmouseup(e, true);
- }
-
- return this.$updateState(e);
- }
- }, true);
-
- /**** Private state handling methods ****/
-
- this.states = {
- "Out" : 1,
- "Over" : 2,
- "Down" : 3
- };
-
- this.$updateState = function(e, strEvent) {
- if (this.disabled || e.reset) {
- refKeyDown = 0;
- refMouseDown = 0;
- mouseOver = false;
- return false;
- }
-
- if (refKeyDown > 0
- || (refMouseDown > 0 && mouseOver)
- || (this.isBoolean && this.value)) {
- this.$setState ("Down", e, strEvent);
- }
- else if (mouseOver)
- this.$setState ("Over", e, strEvent);
- else
- this.$setState ("Out", e, strEvent);
- }
-
- this.$setupEvents = function() {
- this.oExt.onmousedown = function(e) {
- if (!e) e = event;
-
- if (_self.$notfromext && (e.srcElement || e.target) == this) - return;
-
- refMouseDown = 1;
- mouseLeft = false;
- _self.$updateState(e, "mousedown");
- };
- this.oExt.onmouseup = function(e, force) {
- if (!e) e = event;
- //if (e) e.cancelBubble = true;
-
- if (!force && (!mouseOver || !refMouseDown))
- return;
-
- refMouseDown = 0;
- _self.$updateState (e, "mouseup");
-
- // If this is coming from a mouse click, we shouldn't have left the button.
- if (_self.disabled || (e && e.type == "click" && mouseLeft == true))
- return false;
-
- // If there are still buttons down, this is not a real click.
- if (refMouseDown + _self.refKeyDown)
- return false;
-
- if (_self.$clickHandler && _self.$clickHandler())
- _self.$updateState (e || event, "click");
- else
- _self.dispatchEvent("click", {htmlEvent : e});
-
- return false;
- };
-
- this.oExt.onmousemove = function(e) {
- if (!mouseOver) {
- if (!e) e = event;
-
- if (_self.$notfromext && (e.srcElement || e.target) == this) - return;
-
- mouseOver = true;
- _self.$updateState(e, "mouseover");
- }
- };
-
- this.oExt.onmouseout = function(e) {
- if(!e) e = event;
-
- //Check if the mouse out is meant for us
- var tEl = e.explicitOriginalTarget || e.toElement;
- if (this == tEl || jpf.xmldb.isChildOf(this, tEl))
- return;
-
- mouseOver = false;
- refMouseDown = 0;
- mouseLeft = true;
- _self.$updateState (e || event, "mouseout");
- };
-
- if (jpf.hasClickFastBug)
- this.oExt.ondblclick = this.oExt.onmouseup;
- }
-
- this.$doBgSwitch = function(nr){
- if (this.bgswitch && (this.$background[2] >= nr || nr == 4)) {
- if (nr == 4)
- nr = this.$background[2] + 1;
-
- var strBG = this.$background[1] == "vertical"
- ? "0 -" + (parseInt(this.$background[3]) * (nr - 1)) + "px"
- : "-" + (parseInt(this.$background[3]) * (nr - 1)) + "px 0";
-
- this.$getLayoutNode("main", "background",
- this.oExt).style.backgroundPosition = strBG;
- }
- }
-
- /**** Focus Handling ****/
-
- this.$focus = function(){
- if (!this.oExt)
- return;
-
- this.$setStyleClass(this.oExt, this.baseCSSname + "Focus");
- }
-
- this.$blur = function(oBtn){
- if (!this.oExt)
- return; //FIREFOX BUG!
-
- this.$setStyleClass(this.oExt, "", [this.baseCSSname + "Focus"]);
- /*refKeyDown = 0;
- refMouseDown = 0;
- mouseLeft = true;*/
-
- /*if (this.submenu) {
- if (this.value) {
- this.$setState("Down", {}, "mousedown");
- this.$hideMenu();
- }
- }*/
-
- if (oBtn)
- this.$updateState(oBtn);//, "onblur"
- }
-
- /*** Clearing potential memory leaks ****/
-
- this.$destroy = function(skinChange){
- if (!skinChange) {
- this.oExt.onmousedown = this.oExt.onmouseup = this.oExt.onmouseover =
- this.oExt.onmouseout = this.oExt.onclick = this.oExt.ondblclick = null;
- }
- }
-}
-
- - -/*FILEHEAD(/var/lib/jpf/src/elements/_base/baselist.js)SIZE(-1077090856)TIME(1238950356)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * Baseclass of elements that allows the user to select one or more items
- * out of a list. (i.e. a {@link element.list} or {@link element.dropdown})
- *
- * @constructor
- * @baseclass
- *
- * @inherits jpf.MultiSelect
- * @inherits jpf.Cache
- * @inherits jpf.Presentation
- * @inherits jpf.DataBinding
- * @inherits jpf.Validation
- * @inherits jpf.XForms
- *
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.8
- *
- * @binding caption Determines the caption of a node.
- * @binding icon Determines the icon of a node.
- * @binding image Determines the image of a node.
- * Example:
- * In this example a node is bold when the folder contains unread messages:
- * <code>
- * <j:thumbnail>
- * <j:bindings>
- * <j:caption select="@caption" />
- * <j:image select="@thumbnail" />
- * <j:image value="no_image.png" />
- * <j:traverse select="images" />
- * </j:bindings>
- * </j:thumbnail>
- * </code>
- * @binding css Determines a css class for a node.
- * Example:
- * In this example a node is bold when the folder contains unread messages:
- * <code>
- * <j:list>
- * <j:bindings>
- * <j:caption select="@caption" />
- * <j:css select="message[@unread]" value="highlighUnread" />
- * <j:icon select="@icon" />
- * <j:icon select="self::folder" value="icoFolder.gif" />
- * <j:traverse select="folder" />
- * </j:bindings>
- * </j:list>
- * </code>
- * @binding tooltip Determines the tooltip of a node.
- * @event notunique Fires when the more attribute is set and an item is added that has a caption that already exists in the list.
- * object:
- * {String} value the value that was entered.
- */
-jpf.BaseList = function(){
- this.inherit(jpf.Validation);
-
- this.dynCssClasses = [];
-
- /**** Properties and Attributes ****/
-
- this.$focussable = true; // This object can get the focus
- this.multiselect = true; // Initially Disable MultiSelect
-
- /**
- * @attribute {String} fill the set of items that should be loaded into this - * element. A start and an end seperated by a -.
- * Example:
- * This example loads a list with items starting at 1980 and ending at 2050.
- * <code>
- * <j:dropdown fill="1980-2050" />
- * </code>
- */ - this.$propHandlers["fill"] = function(value){ - if (value) - this.loadFillData(this.$jml.getAttribute("fill")); - else - this.clear(); - }
-
- /**** Keyboard support ****/
-
-
- //Handler for a plane list
- /**
- * @todo something goes wrong when selecting using space, doing mode="check"
- */
- this.$keyHandler = function(e){
- var key = e.keyCode;
- var ctrlKey = e.ctrlKey;
- var shiftKey = e.shiftKey;
- var selHtml = this.$selected || this.$indicator;
-
- if (!selHtml || this.renaming) //@todo how about allowdeselect?
- return;
-
- var selXml = this.indicator || this.selected;
- var oExt = this.oExt;
-
- switch (key) {
- case 13:
- if (this.$tempsel)
- this.selectTemp();
-
- if (this.ctrlselect == "enter")
- this.select(this.indicator, true);
-
- this.choose(selHtml);
- break;
- case 32:
- //if (ctrlKey || this.mode)
- this.select(this.indicator, true);
- break;
- case 109:
- case 46:
- //DELETE
- if (this.disableremove)
- return;
-
- if (this.$tempsel)
- this.selectTemp();
-
- this.remove(this.mode != "normal" ? this.indicator : null); //this.mode != "check"
- break;
- case 36:
- //HOME
- this.select(this.getFirstTraverseNode(), false, shiftKey);
- this.oInt.scrollTop = 0;
- break;
- case 35:
- //END
- this.select(this.getLastTraverseNode(), false, shiftKey);
- this.oInt.scrollTop = this.oInt.scrollHeight;
- break;
- case 107:
- //+
- if (this.more)
- this.startMore();
- break;
- case 37:
- //LEFT
- if (!selXml && !this.$tempsel)
- return;
-
- var node = this.$tempsel
- ? jpf.xmldb.getNode(this.$tempsel)
- : selXml;
- var margin = jpf.getBox(jpf.getStyle(selHtml, "margin"));
- var items = Math.floor((oExt.offsetWidth
- - (hasScroll ? 15 : 0)) / (selHtml.offsetWidth
- + margin[1] + margin[3]));
-
- var margin = jpf.getBox(jpf.getStyle(selHtml, "margin"));
-
- node = this.getNextTraverseSelected(node, false);
- if (node)
- this.setTempSelected(node, ctrlKey, shiftKey);
- else return;
-
- selHtml = jpf.xmldb.findHTMLNode(node, this);
- if (selHtml.offsetTop < oExt.scrollTop) {
- oExt.scrollTop = Array.prototype.indexOf.call(this.getTraverseNodes(), node) < items
- ? 0
- : selHtml.offsetTop - margin[0];
- }
- break;
- case 38:
- //UP
- if (!selXml && !this.$tempsel)
- return;
-
- var node = this.$tempsel
- ? jpf.xmldb.getNode(this.$tempsel)
- : selXml;
-
- var margin = jpf.getBox(jpf.getStyle(selHtml, "margin"));
- var hasScroll = oExt.scrollHeight > oExt.offsetHeight;
- var items = Math.floor((oExt.offsetWidth
- - (hasScroll ? 15 : 0)) / (selHtml.offsetWidth
- + margin[1] + margin[3]));
-
- node = this.getNextTraverseSelected(node, false, items);
- if (node)
- this.setTempSelected(node, ctrlKey, shiftKey);
- else return;
-
- selHtml = jpf.xmldb.findHTMLNode(node, this);
- if (selHtml.offsetTop < oExt.scrollTop) {
- oExt.scrollTop = Array.prototype.indexOf.call(this.getTraverseNodes(), node) < items
- ? 0
- : selHtml.offsetTop - margin[0];
- }
- break;
- case 39:
- //RIGHT
- if (!selXml && !this.$tempsel)
- return;
-
- var node = this.$tempsel
- ? jpf.xmldb.getNode(this.$tempsel)
- : selXml;
-
- var margin = jpf.getBox(jpf.getStyle(selHtml, "margin"));
-
- node = this.getNextTraverseSelected(node, true);
- if (node)
- this.setTempSelected(node, ctrlKey, shiftKey);
- else return;
-
- selHtml = jpf.xmldb.findHTMLNode(node, this);
- if (selHtml.offsetTop + selHtml.offsetHeight
- > oExt.scrollTop + oExt.offsetHeight)
- oExt.scrollTop = selHtml.offsetTop
- - oExt.offsetHeight + selHtml.offsetHeight
- + margin[0];
-
- break;
- case 40:
- //DOWN
- if (!selXml && !this.$tempsel)
- return;
-
- var node = this.$tempsel
- ? jpf.xmldb.getNode(this.$tempsel)
- : selXml;
-
- var margin = jpf.getBox(jpf.getStyle(selHtml, "margin"));
- var hasScroll = oExt.scrollHeight > oExt.offsetHeight;
- var items = Math.floor((oExt.offsetWidth
- - (hasScroll ? 15 : 0)) / (selHtml.offsetWidth
- + margin[1] + margin[3]));
-
- node = this.getNextTraverseSelected(node, true, items);
- if (node)
- this.setTempSelected(node, ctrlKey, shiftKey);
- else return;
-
- selHtml = jpf.xmldb.findHTMLNode(node, this);
- if (selHtml.offsetTop + selHtml.offsetHeight
- > oExt.scrollTop + oExt.offsetHeight) // - (hasScroll ? 10 : 0)
- oExt.scrollTop = selHtml.offsetTop
- - oExt.offsetHeight + selHtml.offsetHeight
- + margin[0]; //+ (hasScroll ? 10 : 0)
-
- break;
- case 33:
- //PGUP
- if (!selXml && !this.$tempsel)
- return;
-
- var node = this.$tempsel
- ? jpf.xmldb.getNode(this.$tempsel)
- : selXml;
-
- var margin = jpf.getBox(jpf.getStyle(selHtml, "margin"));
- var hasScrollY = oExt.scrollHeight > oExt.offsetHeight;
- var hasScrollX = oExt.scrollWidth > oExt.offsetWidth;
- var items = Math.floor((oExt.offsetWidth
- - (hasScrollY ? 15 : 0)) / (selHtml.offsetWidth
- + margin[1] + margin[3]));
- var lines = Math.floor((oExt.offsetHeight
- - (hasScrollX ? 15 : 0)) / (selHtml.offsetHeight
- + margin[0] + margin[2]));
-
- node = this.getNextTraverseSelected(node, false, items * lines);
- if (!node)
- node = this.getFirstTraverseNode();
- if (node)
- this.setTempSelected(node, ctrlKey, shiftKey);
- else return;
-
- selHtml = jpf.xmldb.findHTMLNode(node, this);
- if (selHtml.offsetTop < oExt.scrollTop) {
- oExt.scrollTop = Array.prototype.indexOf.call(this.getTraverseNodes(), node) < items
- ? 0
- : selHtml.offsetTop - margin[0];
- }
- break;
- case 34:
- //PGDN
- if (!selXml && !this.$tempsel)
- return;
-
- var node = this.$tempsel
- ? jpf.xmldb.getNode(this.$tempsel)
- : selXml;
-
- var margin = jpf.getBox(jpf.getStyle(selHtml, "margin"));
- var hasScrollY = oExt.scrollHeight > oExt.offsetHeight;
- var hasScrollX = oExt.scrollWidth > oExt.offsetWidth;
- var items = Math.floor((oExt.offsetWidth - (hasScrollY ? 15 : 0))
- / (selHtml.offsetWidth + margin[1] + margin[3]));
- var lines = Math.floor((oExt.offsetHeight - (hasScrollX ? 15 : 0))
- / (selHtml.offsetHeight + margin[0] + margin[2]));
-
- node = this.getNextTraverseSelected(selXml, true, items * lines);
- if (!node)
- node = this.getLastTraverseNode();
- if (node)
- this.setTempSelected(node, ctrlKey, shiftKey);
- else return;
-
- selHtml = jpf.xmldb.findHTMLNode(node, this);
- if (selHtml.offsetTop + selHtml.offsetHeight
- > oExt.scrollTop + oExt.offsetHeight) // - (hasScrollY ? 10 : 0)
- oExt.scrollTop = selHtml.offsetTop
- - oExt.offsetHeight + selHtml.offsetHeight
- + margin[0]; //+ 10 + (hasScrollY ? 10 : 0)
- break;
-
- default:
- if (key == 65 && ctrlKey) {
- this.selectAll();
- } else if (this.caption || (this.bindingRules || {})["caption"]) {
- if (!this.xmlRoot || this.autorename) return;
-
- //this should move to a onkeypress based function
- if (!this.lookup || new Date().getTime()
- - this.lookup.date.getTime() > 300)
- this.lookup = {
- str : "",
- date : new Date()
- };
-
- this.lookup.str += String.fromCharCode(key);
-
- var nodes = this.getTraverseNodes(); //@todo start at current indicator
- for (var v, i = 0; i < nodes.length; i++) {
- v = this.applyRuleSetOnNode("caption", nodes[i]);
- if (v && v.substr(0, this.lookup.str.length)
- .toUpperCase() == this.lookup.str) {
-
- if (!this.isSelected(nodes[i])) {
- if (this.mode == "check")
- this.setIndicator(nodes[i]);
- else
- this.select(nodes[i]);
- }
-
- if (selHtml)
- this.oInt.scrollTop = selHtml.offsetTop
- - (this.oInt.offsetHeight
- - selHtml.offsetHeight) / 2;
- return;
- }
- }
- return;
- }
- break;
- };
-
- this.lookup = null;
- return false;
- };
-
-
- /**** Private databinding functions ****/
-
- this.$deInitNode = function(xmlNode, htmlNode){
- if (!htmlNode) return;
-
- //Remove htmlNodes from tree
- htmlNode.parentNode.removeChild(htmlNode);
- }
-
- this.$updateNode = function(xmlNode, htmlNode, noModifier){
- //Update Identity (Look)
- var elIcon = this.$getLayoutNode("item", "icon", htmlNode);
-
- if (elIcon) {
- if (elIcon.nodeType == 1)
- elIcon.style.backgroundImage = "url(" +
- jpf.getAbsolutePath(this.iconPath, this.applyRuleSetOnNode("icon", xmlNode)) + ")";
- else
- elIcon.nodeValue =jpf.getAbsolutePath(this.iconPath, this.applyRuleSetOnNode("icon", xmlNode));
- }
- else {
- var elImage = this.$getLayoutNode("item", "image", htmlNode);//.style.backgroundImage = "url(" + this.applyRuleSetOnNode("image", xmlNode) + ")";
- if (elImage) {
- if (elImage.nodeType == 1)
- elImage.style.backgroundImage = "url(" +
- jpf.getAbsolutePath(this.mediaPath, this.applyRuleSetOnNode("image", xmlNode)) + ")";
- else
- elImage.nodeValue =
- jpf.getAbsolutePath(this.mediaPath, this.applyRuleSetOnNode("image", xmlNode));
- }
- }
-
- //this.$getLayoutNode("item", "caption", htmlNode).nodeValue = this.applyRuleSetOnNode("Caption", xmlNode);
- var elCaption = this.$getLayoutNode("item", "caption", htmlNode);
- if (elCaption) {
- if (elCaption.nodeType == 1)
- elCaption.innerHTML = this.applyRuleSetOnNode("caption", xmlNode);
- else
- elCaption.nodeValue = this.applyRuleSetOnNode("caption", xmlNode);
- }
-
- htmlNode.title = this.applyRuleSetOnNode("title", xmlNode) || "";
-
- var cssClass = this.applyRuleSetOnNode("css", xmlNode);
-
- if (cssClass || this.dynCssClasses.length) {
- this.$setStyleClass(htmlNode, cssClass, this.dynCssClasses);
- if (cssClass && !this.dynCssClasses.contains(cssClass)) {
- this.dynCssClasses.push(cssClass);
- }
- }
-
- if (!noModifier && this.$updateModifier)
- this.$updateModifier(xmlNode, htmlNode);
- }
-
- this.$moveNode = function(xmlNode, htmlNode){
- if (!htmlNode) return;
-
- var oPHtmlNode = htmlNode.parentNode;
- var beforeNode = xmlNode.nextSibling
- ? jpf.xmldb.findHTMLNode(this.getNextTraverse(xmlNode), this)
- : null;
-
- oPHtmlNode.insertBefore(htmlNode, beforeNode);
-
- //if(this.emptyMessage && !oPHtmlNode.childNodes.length) this.setEmpty(oPHtmlNode);
- }
-
- var nodes = [];
-
- this.$add = function(xmlNode, Lid, xmlParentNode, htmlParentNode, beforeNode){
- //Build Row
- this.$getNewContext("item");
- var Item = this.$getLayoutNode("item");
- var elSelect = this.$getLayoutNode("item", "select");
- var elIcon = this.$getLayoutNode("item", "icon");
- var elImage = this.$getLayoutNode("item", "image");
- var elCheckbox = this.$getLayoutNode("item", "checkbox");
- var elCaption = this.$getLayoutNode("item", "caption");
-
- Item.setAttribute("id", Lid);
-
- //elSelect.setAttribute("oncontextmenu", 'jpf.lookup(' + this.uniqueId + ').dispatchEvent("contextmenu", event);');
- elSelect.setAttribute("onmouseover", 'jpf.setStyleClass(this, "hover");');
- elSelect.setAttribute("onmouseout", 'jpf.setStyleClass(this, "", ["hover"]);');
-
- if (this.hasFeature(__RENAME__)) {
- elSelect.setAttribute("ondblclick", 'var o = jpf.lookup(' + this.uniqueId + '); ' +
- 'o.stopRename();' +
- ' o.choose()');
- elSelect.setAttribute(this.itemSelectEvent || "onmousedown",
- 'var o = jpf.lookup(' + this.uniqueId
- + ');if(!o.renaming && o.hasFocus() \
- && jpf.xmldb.isChildOf(o.$selected, this, true) \
- && o.selected) this.dorename = true;\
- if (!o.hasFeature(__DRAGDROP__) || !event.ctrlKey)\
- o.select(this, event.ctrlKey, event.shiftKey)');
- elSelect.setAttribute("onmouseup", 'var o = jpf.lookup(' + this.uniqueId + ');\
- if(this.dorename && o.mode == "normal")' +
- 'o.startDelayedRename(event);' + - 'this.dorename = false;\
- if (o.hasFeature(__DRAGDROP__) && event.ctrlKey)\
- o.select(this, event.ctrlKey, event.shiftKey)');
- }
- else {
- elSelect.setAttribute("ondblclick", 'var o = jpf.lookup('
- + this.uniqueId + '); o.choose()');
- elSelect.setAttribute(this.itemSelectEvent
- || "onmousedown", 'var o = jpf.lookup(' + this.uniqueId
- + '); o.select(this, event.ctrlKey, event.shiftKey)');
- }
-
- //Setup Nodes Identity (Look)
- if (elIcon) {
- if (elIcon.nodeType == 1)
- elIcon.setAttribute("style", "background-image:url("
- + jpf.getAbsolutePath(this.iconPath, this.applyRuleSetOnNode("icon", xmlNode))
- + ")");
- else
- elIcon.nodeValue = jpf.getAbsolutePath(this.iconPath, this.applyRuleSetOnNode("icon", xmlNode));
- }
- else if (elImage) {
- if (elImage.nodeType == 1)
- elImage.setAttribute("style", "background-image:url("
- + jpf.getAbsolutePath(this.mediaPath, this.applyRuleSetOnNode("image", xmlNode))
- + ")");
- else {
- if (jpf.isSafariOld) { //HAAAAACCCCKKKKKK!!! this should be changed... blrgh..
- var p = elImage.ownerElement.parentNode;
- var img = p.appendChild(p.ownerDocument.createElement("img"));
- img.setAttribute("src",
- jpf.getAbsolutePath(this.mediaPath, this.applyRuleSetOnNode("image", xmlNode)));
- }
- else {
- elImage.nodeValue =
- jpf.getAbsolutePath(this.mediaPath, this.applyRuleSetOnNode("image", xmlNode));
- }
- }
- }
-
- if (elCaption) {
- jpf.xmldb.setNodeValue(elCaption,
- this.applyRuleSetOnNode("caption", xmlNode));
-
- if (this.lastRule && this.lastRule.getAttribute("parse") == "jml")
- this.doJmlParsing = true;
- }
- Item.setAttribute("title", this.applyRuleSetOnNode("tooltip", xmlNode) || "");
-
- var cssClass = this.applyRuleSetOnNode("css", xmlNode);
- if (cssClass) {
- this.$setStyleClass(Item, cssClass);
- if (cssClass)
- this.dynCssClasses.push(cssClass);
- }
-
- if (this.$addModifier)
- this.$addModifier(xmlNode, Item);
-
- if (htmlParentNode)
- jpf.xmldb.htmlImport(Item, htmlParentNode, beforeNode);
- else
- nodes.push(Item);
- }
-
- this.$fill = function(){
- if (this.more && !this.moreItem) {
- this.$getNewContext("item");
- var Item = this.$getLayoutNode("item");
- var elCaption = this.$getLayoutNode("item", "caption");
- var elSelect = this.$getLayoutNode("item", "select");
-
- Item.setAttribute("class", "more");
- elSelect.setAttribute("onmousedown", 'var o = jpf.lookup(' + this.uniqueId
- + ');o.clearSelection();o.$setStyleClass(this, "more_down");');
- elSelect.setAttribute("onmouseout", 'jpf.lookup(' + this.uniqueId
- + ').$setStyleClass(this, "", ["more_down"]);');
- elSelect.setAttribute("onmouseup", 'jpf.lookup(' + this.uniqueId
- + ').startMore(this)');
-
- if (elCaption)
- jpf.xmldb.setNodeValue(elCaption,
- this.more.match(/caption:(.*)(;|$)/i)[1]);
- nodes.push(Item);
- }
-
- jpf.xmldb.htmlImport(nodes, this.oInt);
- nodes.length = 0;
-
- if (this.doJmlParsing) {
- var x = document.createElement("div");
- while (this.oExt.childNodes.length)
- x.appendChild(this.oExt.childNodes[0]);
- Application.loadSubNode(x, this.oExt, null, null, true);
- }
-
- if (this.more && !this.moreItem)
- this.moreItem = this.oInt.lastChild;
- }
-
- var lastAddedMore;
-
- /**
- * Adds a new item to the list and lets the users type in the new name.
- * This functionality is especially useful in the interface when
- * {@link element.list.attribute.mode} is set to check or radio. For instance in a form.
- * @see element.list.attribute.more
- */
- this.startMore = function(o){
- this.$setStyleClass(o, "", ["more_down"]);
-
- var xmlNode;
- if (!this.actionRules || !this.actionRules["add"]) {
- if (this.traverse && !this.traverse.match(/[\/\[]/)) {
- xmlNode = "<" + this.traverse + (this.traverse.match(/^j:/)
- ? " xmlns:j='" + jpf.ns.jml + "'"
- : "") + " custom='1' />";
- }
- else {
- throw new Error(jpf.formatErrorString(0, this,
- "Could not start more",
- "No add action rule is defined for this component",
- this.$jml));
- return false;
- }
- }
-
- var addedNode = this.add(xmlNode);
- this.select(addedNode, null, null, null, null, true);
- this.oInt.appendChild(this.moreItem);
-
- var undoLastAction = function(){
- this.getActionTracker().undo(this.autoselect ? 2 : 1);
-
- this.removeEventListener("stoprename", undoLastAction);
- this.removeEventListener("beforerename", removeSetRenameEvent);
- this.removeEventListener("afterrename", afterRename);
- }
- var afterRename = function(){
- //this.select(addedNode);
- this.removeEventListener("afterrename", afterRename);
- };
- var removeSetRenameEvent = function(e){
- this.removeEventListener("stoprename", undoLastAction);
- this.removeEventListener("beforerename", removeSetRenameEvent);
-
- //There is already a choice with the same value
- var xmlNode = this.findXmlNodeByValue(e.args[1]);
- if (xmlNode || !e.args[1]) {
- if (e.args[1] && this.dispatchEvent("notunique", {
- value : e.args[1]
- }) === false) {
- this.startRename();
-
- this.addEventListener("stoprename", undoLastAction);
- this.addEventListener("beforerename", removeSetRenameEvent);
- }
- else {
- this.removeEventListener("afterrename", afterRename);
-
- this.getActionTracker().undo();//this.autoselect ? 2 : 1);
- if (!this.isSelected(xmlNode))
- this.select(xmlNode);
- }
-
- return false;
- }
- };
-
- this.addEventListener("stoprename", undoLastAction);
- this.addEventListener("beforerename", removeSetRenameEvent);
- this.addEventListener("afterrename", afterRename);
-
- /*if (this.mode == "radio") {
- this.moreItem.style.display = "none";
- if (lastAddedMore)
- this.removeEventListener("xmlupdate", lastAddedMore);
-
- lastAddedMore = function(){
- this.moreItem.style.display = addedNode.parentNode
- ? "none"
- : "block";
- };
- this.addEventListener("xmlupdate", lastAddedMore);
- }*/
-
- this.startDelayedRename({}, 1);
- }
-
- /**** Selection ****/
-
- this.$calcSelectRange = function(xmlStartNode, xmlEndNode){
- var r = [];
- var nodes = this.getTraverseNodes();
- for (var f = false, i = 0; i < nodes.length; i++) {
- if (nodes[i] == xmlStartNode)
- f = true;
- if (f)
- r.push(nodes[i]);
- if (nodes[i] == xmlEndNode)
- f = false;
- }
-
- if (!r.length || f) {
- r = [];
- for (var f = false, i = nodes.length - 1; i >= 0; i--) {
- if (nodes[i] == xmlStartNode)
- f = true;
- if (f)
- r.push(nodes[i]);
- if (nodes[i] == xmlEndNode)
- f = false;
- }
- }
-
- return r;
- }
-
- this.$selectDefault = function(XMLRoot){
- this.select(this.getTraverseNodes()[0]);
- }
-
- this.inherit(jpf.MultiSelect,
- jpf.Cache,
- jpf.Presentation,
- jpf.DataBinding);
-
- /**
- * Generates a list of items based on a string.
- * @param {String} str the description of the items. A start and an end seperated by a -.
- * Example:
- * This example loads a list with items starting at 1980 and ending at 2050.
- * <code>
- * lst.loadFillData("1980-2050");
- * </code>
- */
- this.loadFillData = function(str){
- var parts = str.split("-");
- var start = parseInt(parts[0]);
- var end = parseInt(parts[1]);
-
- var strData = [];
- for (var i = start; i < end + 1; i++) {
- strData.push("<item>" + (i + "")
- .pad(Math.max(parts[0].length, parts[1].length), "0")
- + "</item>");
- }
-
- if (strData.length) {
- var sNode = new jpf.smartbinding(null,
- jpf.getXmlDom("<smartbindings xmlns='"
- + jpf.ns.jml
- + "'><bindings><caption select='text()' /><value select='text()'/><traverse select='item' /></bindings><model><items>"
- + strData.join("") + "</items></model></smartbindings>")
- .documentElement);
- jpf.JmlParser.addToSbStack(this.uniqueId, sNode);
- }
- }
-}
-
- - -/*FILEHEAD(/var/lib/jpf/src/elements/_base/basesimple.js)SIZE(-1077090856)TIME(1238950356)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-/**
- * Baseclass of a simple element. This are usually displaying elements
- * (i.e. {@link element.label}, {@link element.picture})
- *
- * @constructor
- * @baseclass
- *
- * @inherits jpf.Presentation
- * @inherits jpf.DataBinding
- *
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.8
- */
-jpf.BaseSimple = function(){
- this.inherit(jpf.Presentation);
- this.inherit(jpf.DataBinding);
-
- this.getValue = function(){
- return this.value;
- }
-
- /**** Drag & Drop ****/
-
-
- this.$showDragIndicator = function(sel, e){
- var x = e.offsetX + 22;
- var y = e.offsetY;
-
- this.oDrag.startX = x;
- this.oDrag.startY = y;
-
-
- document.body.appendChild(this.oDrag);
- //this.oDrag.getElementsByTagName("DIV")[0].innerHTML = this.selected.innerHTML;
- //this.oDrag.getElementsByTagName("IMG")[0].src = this.selected.parentNode.parentNode.childNodes[1].firstChild.src;
- var oInt = this.$getLayoutNode("main", "caption", this.oDrag);
- if (oInt.nodeType != 1)
- oInt = oInt.parentNode;
-
- oInt.innerHTML = this.applyRuleSetOnNode("caption", this.xmlRoot) || "";
-
- return this.oDrag;
- }
-
- this.$hideDragIndicator = function(){
- this.oDrag.style.display = "none";
- }
-
- this.$moveDragIndicator = function(e){
- this.oDrag.style.left = (e.clientX - this.oDrag.startX
- + document.documentElement.scrollLeft) + "px";
- this.oDrag.style.top = (e.clientY - this.oDrag.startY
- + document.documentElement.scrollTop) + "px";
- }
-
- this.$initDragDrop = function(){
- this.oDrag = document.body.appendChild(this.oExt.cloneNode(true));
-
- this.oDrag.style.zIndex = 1000000;
- this.oDrag.style.position = "absolute";
- this.oDrag.style.cursor = "default";
- this.oDrag.style.filter = "progid:DXImageTransform.Microsoft.Alpha(opacity=50)";
- this.oDrag.style.MozOpacity = 0.5;
- this.oDrag.style.opacity = 0.5;
- this.oDrag.style.display = "none";
- }
-
- this.$dragout = this.$dragover = this.$dragdrop = function(){};
-
- this.inherit(jpf.DragDrop); /** @inherits jpf.DragDrop */
-}
-
- - -/*FILEHEAD(/var/lib/jpf/src/elements/tab.js)SIZE(-1077090856)TIME(1238944817)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -/** - * Element displaying a page and several buttons allowing a - * user to switch between the pages. Each page can contain - * arbitrary jml. Each page can render it's content during - * startup of the application or when the page is activated. - * Example: - * <code> - * <j:tab id="tab"> - * <j:page caption="General"> - * <j:checkbox>Example</j:checkbox> - * <j:button>Example</j:button> - * </j:page> - * <j:page caption="Advanced"> - * <j:checkbox>Test checkbox</j:checkbox> - * <j:checkbox>Test checkbox</j:checkbox> - * <j:checkbox>Test checkbox</j:checkbox> - * </j:page> - * <j:page caption="Javeline"> - * <j:checkbox>This ok?</j:checkbox> - * <j:checkbox>This better?</j:checkbox> - * </j:page> - * </j:tab> - * </code> - * - * @constructor - * @define tab, pages, switch - * @allowchild page - * @addnode elements - * - * @author Ruben Daniels - * @version %I%, %G% - * @since 0.1 - * - * @inherits jpf.BaseTab - */ - -jpf["switch"] = -jpf.pages = -jpf.tab = jpf.component(jpf.NODE_VISIBLE, function(){ - this.$hasButtons = this.tagName == "tab"; - this.$focussable = jpf.KEYBOARD; // This object can get the focus from the keyboard - - /**** Init ****/ - - this.$draw = function(bSkinChange){ - //Build Main Skin - this.oExt = this.$getExternal(); - - if (!bSkinChange) - jpf.layout.setRules(this.oExt, this.uniqueId + "_tabscroller", - "jpf.all[" + this.uniqueId + "].correctScrollState()"); - }; - - this.$loadJml = function(x){ - this.switchType = x.getAttribute("switchtype") || "incremental"; - this.$loadChildren(); - }; - - this.$destroy = function() { - jpf.layout.removeRule(this.oExt, this.uniqueId + "_tabscroller"); - }; -}).implement(jpf.BaseTab); - - - -/*FILEHEAD(/var/lib/jpf/src/elements/divider.js)SIZE(-1077090856)TIME(1228080374)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-/**
- * Element displaying a divider. For use in toolbars, menu's and such.
- * @define divider
- * @constructor
- */
-jpf.divider = jpf.subnode(jpf.NODE_HIDDEN, function() {
- this.$domHandlers["reparent"].push(function(beforeNode, pNode, withinParent){
- if (!this.$jmlLoaded)
- return;
-
- if (!withinParent && this.skinName != pNode.skinName) {
- //@todo for now, assuming dom garbage collection doesn't leak
- this.loadJml();
- }
- });
-
- /**
- * @ref jmlNode#show
- */
- this.show = function(){ - this.oExt.style.display = "block"; - } -
- /**
- * @ref jmlNode#hide
- */ - this.hide = function(){ - this.oExt.style.display = "none"; - }
-
- /** - * @private - */
- this.loadJml = function(x, parentNode) {
- this.$jml = x;
- if (parentNode)
- this.$setParent(parentNode);
-
- this.skinName = this.parentNode.skinName;
- this.oExt = jpf.xmldb.htmlImport(
- this.parentNode.$getLayoutNode("divider"), this.pHtmlNode);
- }
-});
-
- -/*FILEHEAD(/var/lib/jpf/src/elements/dropdown.js)SIZE(-1077090856)TIME(1239027647)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -/** - * Element allowing a user to select a value from a list, which is - * displayed when the user clicks a button. - * Example: - * A simple dropdown with inline items. - * <code> - * <j:dropdown> - * <j:item>The Netherlands</j:item> - * <j:item>United States of America</j:item> - * <j:item>United Kingdom</j:item> - * ... - * </j:dropdown> - * </code> - * Example: - * A databound dropdown with items loaded from an xml file. - * <code> - * <j:dropdown model="url:friends.xml" traverse="friend" caption="@name" /> - * </code> - * Example: - * A databound list using the j:bindings element - * <code> - * <j:list model="url:friends.xml"> - * <j:bindings> - * <j:caption select="@name" /> - * <j:css select="self::node()[@type='best']" value="bestfriend" /> - * <j:traverse select="friend" /> - * </j:bindings> - * </j:list> - * </code> - * Example: - * A small form. - * <code> - * <j:model id="mdlForm" submission="url:save_form.asp" /> - * - * <j:bar model="mdlForm"> - * <j:label>Name</j:label> - * <j:textbox ref="name" /> - * - * <j:label>City</j:label> - * <j:dropdown ref="city" model="url:cities.xml"> - * <j:bindings> - * <j:caption select="text()" /> - * <j:value select="@value" /> - * <j:traverse select="city" /> - * </j:bindings> - * </j:dropdown> - * - * <j:button default="true" action="submit">Submit</j:button> - * </j:bar> - * </code> - * - * @event slidedown Fires when the calendar slides open. - * cancellable: Prevents the calendar from sliding open - * @event slideup Fires when the calendar slides up. - * cancellable: Prevents the calendar from sliding up - * - * @constructor - * @define dropdown - * @allowchild item, {smartbinding} - * @addnode elements - * - * @inherits jpf.BaseList - * @inherits jpf.JmlElement - * - * @author Ruben Daniels - * @version %I%, %G% - * @since 0.4 - */ -jpf.dropdown = jpf.component(jpf.NODE_VISIBLE, function(){ - this.$animType = 1; - this.$animSteps = 5; - this.$animSpeed = 20; - this.$itemSelectEvent = "onmouseup"; - - /**** Properties and Attributes ****/ - - this.dragdrop = false; - this.reselectable = true; - this.$focussable = true; - this.autoselect = false; - this.multiselect = false; - this.disableremove = true; - this.maxitems = 5; - - this.$booleanProperties["disableremove"] = true; - this.$supportedProperties.push("maxitems", "disableremove", - "initial-message", "fill"); - - /** - * @attribute {Number} maxitems the number of items that are shown at the - * same time in the container. - */ - this.$propHandlers["maxitems"] = function(value){ - this.sliderHeight = value - ? (Math.min(this.maxitems || 100, value) * this.itemHeight) - : 10; - this.containerHeight = value - ? (Math.min(this.maxitems || 100, value) * this.itemHeight) - : 10; - if (this.containerHeight > 20) - this.containerHeight = Math.ceil(this.containerHeight * 0.9); - }; - - /** - * @attribute {String} initial-message the message displayed by this element - * when it doesn't have a value set. This property is inherited from parent - * nodes. When none is found it is looked for on the appsettings element. - */ - this.$propHandlers["initial-message"] = function(value){ - this.initialMsg = value - || jpf.xmldb.getInheritedAttribute(this.$jml, "intial-message"); - }; - - /**** Public methods ****/ - - /** - * Toggles the visibility of the container with the list elements. It opens - * or closes it using a slide effect. - */ - this.slideToggle = function(e){ - if (!e) e = event; - - if (this.isOpen) - this.slideUp(); - else - this.slideDown(e); - }; - - /** - * Shows the container with the list elements using a slide effect. - */ - this.slideDown = function(e){ - if (this.dispatchEvent("slidedown") === false) - return false; - - this.isOpen = true; - - this.$propHandlers["maxitems"].call(this, this.xmlRoot ? this.getTraverseNodes().length : 0); - - this.oSlider.style.display = "block"; - this.oSlider.style[jpf.supportOverflowComponent - ? "overflowY" - : "overflow"] = "hidden"; - - this.oSlider.style.display = ""; - this.$setStyleClass(this.oExt, this.baseCSSname + "Down"); - - //var pos = jpf.getAbsolutePosition(this.oExt); - this.oSlider.style.height = (this.sliderHeight - 1) + "px"; - this.oSlider.style.width = (this.oExt.offsetWidth - 2 - this.widthdiff) + "px"; - - jpf.popup.show(this.uniqueId, { - x : 0, - y : this.oExt.offsetHeight, - animate : true, - ref : this.oExt, - width : this.oExt.offsetWidth - this.widthdiff, - height : this.containerHeight, - callback: function(container){ - container.style[jpf.supportOverflowComponent - ? "overflowY" - : "overflow"] = "auto"; - } - }); - }; - - /** - * Hides the container with the list elements using a slide effect. - */ - this.slideUp = function(){ - if (this.isOpen == 2) return false; - if (this.dispatchEvent("slideup") === false) return false; - - this.isOpen = false; - if (this.selected) { - var htmlNode = jpf.xmldb.findHTMLNode(this.selected, this); - if(htmlNode) this.$setStyleClass(htmlNode, '', ["hover"]); - } - - this.$setStyleClass(this.oExt, '', [this.baseCSSname + "Down"]); - jpf.popup.hide(); - return false; - }; - - /**** Private methods and event handlers ****/ - - this.$setLabel = function(value){ - this.oLabel.innerHTML = value || this.initialMsg || ""; - - this.$setStyleClass(this.oExt, value ? "" : this.baseCSSname + "Initial", - [!value ? "" : this.baseCSSname + "Initial"]); - }; - - this.addEventListener("afterselect", function(e){ - if (!e) e = event; - - this.slideUp(); - if (!this.isOpen) - this.$setStyleClass(this.oExt, "", [this.baseCSSname + "Over"]); - - this.$setLabel(this.applyRuleSetOnNode("caption", this.selected)) - //return selBindClass.applyRuleSetOnNode(selBindClass.mainBind, selBindClass.xmlRoot, null, true); - - this.$updateOtherBindings(); - - if (this.hasFeature(__VALIDATION__) && this.form) { - this.validate(true); - } - }); - - this.addEventListener("afterdeselect", function(){ - this.$setLabel(""); - }); - - function setMaxCount() { - if (this.isOpen == 2) - this.slideDown(); - } - - this.addEventListener("afterload", setMaxCount); - this.addEventListener("xmlupdate", function(){ - setMaxCount.call(this); - this.$setLabel(this.applyRuleSetOnNode("caption", this.selected)); - }); - - /*this.addEventListener("initselbind", function(bindclass){ - var jmlNode = this; - bindclass.addEventListener("xmlupdate", function(){ - debugger; - jmlNode.$showSelection(); - }); - });*/ - - //For MultiBinding - this.$showSelection = function(value){ - //Set value in Label - var bc = this.$getMultiBind(); - - //Only display caption when a value is set - if (value === undefined) { - var sValue2, sValue = bc.applyRuleSetOnNode("value", bc.xmlRoot, - null, true); - if (sValue) - sValue2 = bc.applyRuleSetOnNode("caption", bc.xmlRoot, null, true); - - if (!sValue2 && this.xmlRoot && sValue) { - var rule = this.getBindRule(this.mainBind).getAttribute("select"); - - xpath = this.traverse + "[" + rule + "='" - + sValue.replace(/'/g, "\\'") + "']"; - - var xmlNode = this.xmlRoot.selectSingleNode(xpath);// + "/" + this.getBindRule("caption").getAttribute("select") - value = this.applyRuleSetOnNode("caption", xmlNode); - } else { - value = sValue2 || sValue; - } - } - - this.$setLabel(value || ""); - }; - - //I might want to move this method to the MultiLevelBinding baseclass - this.$updateOtherBindings = function(){ - if (!this.multiselect) { - // Set Caption bind - var bc = this.$getMultiBind(), caption; - if (bc && bc.xmlRoot && (caption = bc.bindingRules["caption"])) { - var xmlNode = jpf.xmldb.createNodeFromXpath(bc.xmlRoot, - bc.bindingRules["caption"][0].getAttribute("select")); - if (!xmlNode) - return; - - jpf.xmldb.setNodeValue(xmlNode, - this.applyRuleSetOnNode("caption", this.selected)); - } - } - }; - - // Private functions - this.$blur = function(){ - this.slideUp(); - //this.oExt.dispatchEvent("mouseout") - if (!this.isOpen) - this.$setStyleClass(this.oExt, "", [this.baseCSSname + "Over"]) - //if(this.oExt.onmouseout) this.oExt.onmouseout(); - - this.$setStyleClass(this.oExt, "", [this.baseCSSname + "Focus"]); - }; - - /*this.$focus = function(){ - jpf.popup.forceHide(); - this.$setStyleClass(this.oFocus || this.oExt, this.baseCSSname + "Focus"); - }*/ - - this.$setClearMessage = function(msg){ - this.$setLabel(msg); - }; - - this.$removeClearMessage = function(){ - this.$setLabel(""); - }; - - this.addEventListener("slidedown", function(){ - //THIS SHOULD BE UPDATED TO NEW SMARTBINDINGS - if (!this.form || !this.form.xmlActions || this.xmlRoot) - return; - var loadlist = this.form.xmlActions - .selectSingleNode("LoadList[@element='" + this.name + "']"); - if (!loadlist) return; - - this.isOpen = 2; - this.form.processLoadRule(loadlist, true, [loadlist]); - - return false; - }); - - this.addEventListener("popuphide", this.slideUp); - - /**** Keyboard Support ****/ - - this.addEventListener("keydown", function(e){ - var key = e.keyCode; - var ctrlKey = e.ctrlKey; - var shiftKey = e.shiftKey; - - if (!this.xmlRoot) return; - - var node; - - switch (key) { - case 38: - //UP - if (e.altKey) { - this.slideToggle(e.htmlEvent); - return; - } - - if (!this.selected) - return; - - node = this.getNextTraverseSelected(this.indicator - || this.selected, false); - - if (node) { - this.select(node); - } - - break; - case 40: - //DOWN - if (e.altKey) { - this.slideToggle(e.htmlEvent); - return; - } - - if (!this.selected) { - node = this.getFirstTraverseNode(); - if (!node) - return; - } - else { - node = this.getNextTraverseSelected(this.selected, true); - } - - if (node) - this.select(node); - - break; - default: - if (key == 9) return; - - //if(key > 64 && key < - if (!this.lookup || new Date().getTime() - this.lookup.date.getTime() > 1000) - this.lookup = { - str : "", - date : new Date() - }; - - this.lookup.str += String.fromCharCode(key); - - var caption, nodes = this.getTraverseNodes(); - for (var i = 0; i < nodes.length; i++) { - caption = this.applyRuleSetOnNode("caption", nodes[i]); - if (caption && caption.indexOf(this.lookup.str) > -1) { - this.select(nodes[i]); - return; - } - } - return; - } - - return false; - }, true); - - /**** Init ****/ - - this.$draw = function(){ - this.$getNewContext("main"); - this.$getNewContext("container"); - - this.$animType = this.$getOption("main", "animtype") || 1; - this.clickOpen = this.$getOption("main", "clickopen") || "button"; - - //Build Main Skin - this.oExt = this.$getExternal(null, null, function(oExt){ - oExt.setAttribute("onmouseover", 'var o = jpf.lookup(' + this.uniqueId - + ');o.$setStyleClass(o.oExt, o.baseCSSname + "Over");'); - oExt.setAttribute("onmouseout", 'var o = jpf.lookup(' + this.uniqueId - + ');if(o.isOpen) return;o.$setStyleClass(o.oExt, "", [o.baseCSSname + "Over"]);'); - - //Button - var oButton = this.$getLayoutNode("main", "button", oExt); - if (oButton) { - oButton.setAttribute("onmousedown", 'jpf.lookup(' - + this.uniqueId + ').slideToggle(event);'); - } - - //Label - var oLabel = this.$getLayoutNode("main", "label", oExt); - if (this.clickOpen == "both") { - oLabel.parentNode.setAttribute("onmousedown", 'jpf.lookup(' - + this.uniqueId + ').slideToggle(event);'); - } - }); - this.oLabel = this.$getLayoutNode("main", "label", this.oExt); - - if (this.oLabel.nodeType == 3) - this.oLabel = this.oLabel.parentNode; - - this.oIcon = this.$getLayoutNode("main", "icon", this.oExt); - if (this.oButton) - this.oButton = this.$getLayoutNode("main", "button", this.oExt); - - this.oSlider = jpf.xmldb.htmlImport(this.$getLayoutNode("container"), - document.body); - this.oInt = this.$getLayoutNode("container", "contents", this.oSlider); - - //Set up the popup - this.pHtmlDoc = jpf.popup.setContent(this.uniqueId, this.oSlider, - jpf.skins.getCssString(this.skinName)); - - //Get Options form skin - //Types: 1=One dimensional List, 2=Two dimensional List - this.listtype = parseInt(this.$getLayoutNode("main", "type")) || 1; - - this.itemHeight = this.$getOption("main", "item-height") || 18.5; - this.widthdiff = this.$getOption("main", "width-diff") || 0; - - if (this.$jml.childNodes.length) - this.$loadInlineData(this.$jml); - }; - - this.$loadJml = function(x){ - if (!this.selected && this.initialMsg) - this.$setLabel(); - }; - - this.$destroy = function(){ - jpf.popup.removeContent(this.uniqueId); - jpf.removeNode(this.oSlider); - this.oSlider = null; - }; -}).implement( - jpf.BaseList -); - - - -/*FILEHEAD(/var/lib/jpf/src/elements/slideshow.js)SIZE(-1077090856)TIME(1239018216)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - -/** - * This element is used to browsing images. It's possible to add thumbnail and - * description to each of them. We could choose displayed image in a few ways. - * With mouse buttons, mousewheel or keyboard arrows. Thumbnails allows to - * very quick choosing an image. - * - * Example: - * Slideshow component with 3 pictures. Each of images have its own thumbnail - * and description which compose with picture number and description added by - * creator. Switching speed is 5 seconds. - * - * <j:model id="mdlImages" save-original="true" > - * <slideshow> - * <picture src="img1.jpg" thumb="thumb1.jpg" title="First Picture"></picture> - * <picture src="img2.jpg" thumb="thumb2.jpg" title="Second Picture"></picture> - * <picture src="img3.jpg" thumb="thumb3.jpg" title="Third Picture"></picture> - * </slideshow> - * </j:model> - * - * <j:slideshow title="number+text" delay="5" model="mdlImages"> - * <j:bindings> - * <j:src select="@src"></j:src> - * <j:title select="@title"></j:title> - * <j:thumb select="@thumb"></j:thumb> - * <j:traverse select="picture"></j:traverse> - * </j:bindings> - * </j:slideshow> - * - * @attribute {String} title describes picture on slide, default is "number" - * Possible values: - * number description contains only slide number on a list - * text description contains only text added by creator - * number+text description contains slide number on a list and text added by creator - * @attribute {Number} delay switching speed between slides, default is 5 seconds - * @attribute {Number} thumbheight vertical size of thumbnails bar, default is 50px - * @attribute {String} defaultthumb it will be showing in thumbnails bar if some slide haven't thumbnail - * @attribute {String} defaultimage it will be showing if some slide haven't path to image - * @attribute {String} defaulttitle this text will be showing for each picture without description - * @attribute {String} loadmsg this text will be displayd when picture is loading - * @attribute {String} scalewidth thumbnails width is scaled relatively to its height - * Possible values: - * true is scaled - * false is not scaled, width and height of thumbnail is the same - * - * @inherits jpf.Presentation - * @inherits jpf.DataBinding - * @inherits jpf.Cache - * @inherits jpf.MultiselectBinding - * - * @author Lukasz Lipinski - * @version %I%, %G% - * - * @define slideshow - * @addnode elements - * - * @define bindings - * @allowchild src, title, thumb - * - * @binding src path to image file - * @binding title image description - * @binding thumb path to thumbnail file - */ -jpf.slideshow = jpf.component(jpf.NODE_VISIBLE, function() { - this.pHtmlNode = document.body; - this.title = "number"; - this.thumbheight = 50; - this.loadmsg = "Loading..."; - this.defaultthumb = null; - this.defaultimage = null; - this.defaulttitle = "No description"; - this.delay = 5; - this.scalewidth = false; - - this.$supportedProperties.push("model", "thumbheight", "title", "loadmsg", - "defaultthumb", "defaulttitle", - "defaultimage", "scalewidth"); - var _self = this; - - var previous, next, current, last; - - var lastIHeight = 0, - lastIWidth = 0, - onuse = false, - play = false, - thumbnails = true, - titleHeight = 30, - vSpace = 210, - hSpace = 150; - var lastChoose = []; - - /* this.$hide and this.$show function are not overwritten */ - this.$positioning = "basic"; - - this.$booleanProperties["scalewidth"] = true; - - this.$propHandlers["thumbheight"] = function(value) { - if (parseInt(value)) - this.thumbheight = parseInt(value); - } - - this.$propHandlers["delay"] = function(value) { - if (parseInt(value)) - this.delay = parseInt(value); - } - - var timer5; - var onmousescroll_; - var onkeydown_ = function(e) { - e = (e || event); - /* - * 39 - Right Arrow - * 37 - Left Arrow - */ - - var key = e.keyCode, - temp = current, - temp_n = _self.getNextTraverse(current), - temp_p = _self.getNextTraverse(current, true); - - next = temp_n ? temp_n : _self.getFirstTraverseNode(); - previous = temp_p ? temp_p : _self.getLastTraverseNode(); - current = key == 39 ? next : (key == 37 ? previous : current); - - _self.addSelection(key == 39 ? -1 : (key == 37 ? 1 : 0)); - - if (current !== temp) { - clearInterval(timer5); - timer5 = setInterval(function() { - _self.$refresh(); - clearInterval(timer5); - }, 550); - }; - return false; - } - - this.addEventListener("onkeydown", onkeydown_); - - /** - * Prepare previous and next xml representation of slide element dependent - * of actual slide - */ - function setSiblings() { - var temp_n = _self.getNextTraverse(current), - temp_p = _self.getNextTraverse(current, true); - - next = temp_n ? temp_n : _self.getFirstTraverseNode(); - previous = temp_p ? temp_p : _self.getLastTraverseNode(); - } - - /** - * Selects image by its xml representation - * - * @param {Number|XMLElement} badge xml representation of image - */ - this.select = function(badge) { - current = badge; - } - - /** - * Draw slideshow component and repaint every single picture when - * its choosen - */ - this.$paint = function() { - current = _self.getFirstTraverseNode(); - - this.oInt.style.display = "block"; - this.oBody.style.display = ""; - this.oImage.style.display = ""; - this.oImage.src = "about:blank"; - this.oBody.style.height = this.oBody.style.width = "100px"; - this.oBody.style.marginTop = this.oBody.style.marginLeft = "-50px"; - this.oLoading.innerHTML = this.loadmsg; - - /* Removes window scrollbars */ - this.lastOverflow = document.documentElement.style.overflow; - document.documentElement.style.overflow = "hidden"; - - if (current) { - this.addSelection(); - } - else { - this.oConsole.style.display = "none"; - this.otPrevious.style.visibility = "hidden"; - this.otNext.style.visibility = "hidden"; - } - - jpf.tween.single(this.oCurtain, { - steps : 3, - type : "fade", - from : 0, - to : 0.7, - onfinish : function() { - _self.oImage.onload = function() { - last = current; - _self.oBody.style.display = "block"; - this.style.display = "block"; - var imgWidth = this.offsetWidth || this.width; - var imgHeight = this.offsetHeight || this.height; - var b = _self.oBody; - var im = _self.oImage; - this.style.display = "none"; - _self.oThumbnails.style.height = _self.thumbheight + "px"; - - if (current) - _self.addSelection(); - - clearTimeout(_self.timer); - - var ww = jpf.isIE - ? document.documentElement.offsetWidth - : window.innerWidth; - var wh = jpf.isIE - ? document.documentElement.offsetHeight - : window.innerHeight; - - _self.otBody.style.height = _self.thumbheight + "px"; - - var bottomPanel = thumbnails - ? Math.max(_self.oBeam.offsetHeight / 2, - _self.thumbheight / 2 + titleHeight / 2 - + _self.oConsole.offsetHeight / 2) - : Math.max(_self.oBeam.offsetHeight / 2, - titleHeight / 2 - + _self.oConsole.offsetHeight / 2); - - var diff = jpf.getDiff(b); - var checkWH = [false, false]; - - jpf.tween.single(b, { - steps : jpf.isGecko - ? 20 - : (Math.abs(imgWidth - b.offsetWidth) > 40 - ? 10 - : 3), - anim : jpf.tween.EASEIN, - type : "mwidth", - from : b.offsetWidth - diff[0], - to : Math.min(imgWidth, ww - hSpace), - onfinish : function() { - checkWH[0] = true; - } - }); - - jpf.tween.single(b, { - steps : jpf.isGecko - ? 20 - : (Math.abs(imgHeight - b.offsetHeight) > 40 - ? 10 - : 3), - anim : jpf.tween.EASEIN, - type : "mheight", - margin : -1*(bottomPanel - 10), - from : b.offsetHeight - diff[1], - to : Math.min(imgHeight, - wh - vSpace - bottomPanel), - onfinish : function() { - checkWH[1] = true; - } - }); - - var timer2; - timer2 = setInterval(function() { - if (checkWH[0] && checkWH[1]) { - if (current) - setSiblings(); - - _self.oTitle.style.visibility = "visible"; - _self.oConsole.style.visibility = "visible"; - - _self.$checkThumbSize(); - - if (thumbnails) { - _self.oThumbnails.style.visibility = "visible"; - } - - _self.oMove.style.display = imgWidth < ww - hSpace - && imgHeight < wh - vSpace - bottomPanel - ? "none" - : "block"; - _self.oImage.style.cursor = imgWidth < ww - hSpace - && imgHeight < wh - vSpace - bottomPanel - ? "default" - : "move"; - - im.style.display = "block"; - jpf.tween.single(im, { - steps : 5, - type : "fade", - from : 0, - to : 1 - }); - - jpf.tween.single(_self.oTitle, { - steps : 10, - type : "fade", - from : 0, - to : 1 - }); - clearInterval(timer2); - - onuse = false; - _self.addSelection(); - - if (play) { - _self.$play(); - } - } - }, 30); - }; - - _self.oImage.onerror = function() { - onuse = false; - } - - _self.oImage.onabort = function() { - onuse = false; - } - - _self.oImage.src = (_self.applyRuleSetOnNode("src", current) - || _self.defaultimage || "about:blank"); - - /* When image is unavailable and defaultImage is set, but not exist */ - /*if(_self.oImage && _self.oImage.readyState) { - if(_self.oImage.readyState == "loading") { - _self.oTitle.style.visibility = "visible"; - _self.oConsole.style.visibility = "visible"; - - if (thumbnails) { - _self.oThumbnails.style.height = _self.thumbheight + "px"; - _self.oThumbnails.style.visibility = "visible"; - } - - _self.oImage.style.display = "block"; - - jpf.tween.single(_self.oImage, { - steps : 5, - type : "fade", - from : 0, - to : 1 - }); - - jpf.tween.single(_self.oTitle, { - steps : 10, - type : "fade", - from : 0, - to : 1 - }); - - onuse = false; - } - }*/ - - _self.oContent.innerHTML = _self.title == "text" - ? _self.applyRuleSetOnNode("title", current) - : (_self.title == "number+text" - ? "<b>Image " + (_self.getPos() + 1) + " of " - + _self.getTraverseNodes().length - + "</b><br />" - + (_self.applyRuleSetOnNode("title", current) - || _self.defaulttitle) - : "Image " + (_self.getPos() + 1) - + " of " + _self.getTraverseNodes().length); - } - }); - }; - - /** - * Return image position on imagelist - * - * @return {Number} image position - */ - this.getPos = function() { - return Array.prototype.indexOf.call(_self.getTraverseNodes(), current); - } - - /** - * Adds selection to thumbnail of actual selected image and removes it from - * previous. When the "move" param is set, selected thumbnail - * is always in displayed area. - * - * @param {Number} thumbnail bar scrolling direction - * Possible values: - * 1 when thumbnails are scrolling in right - * -1 when thumbnails are scrolling in left - */ - this.addSelection = function(move) { - var htmlElement = jpf.xmldb.findHTMLNode(current, this), - ww = jpf.isIE - ? document.documentElement.offsetWidth - : window.innerWidth, - diffp = jpf.getDiff(_self.otPrevious), - diffn = jpf.getDiff(_self.otNext), - bp = parseInt(jpf.getStyle(_self.otPrevious, "width")), - bn = parseInt(jpf.getStyle(_self.otNext, "width")), - ew = parseInt(jpf.getStyle(htmlElement, "width")); - - /* checking visiblity */ - if (htmlElement.offsetLeft + ew + 5 > - ww - bp - bn - diffp[0] - diffn[0]) { - if (move) { - if (move > 0) - this.$tPrevious(); - else if (move < 0) - this.$tNext(); - this.addSelection(move); - } - } - if (this.$selected) - this.$selected.className = "sspictureBox"; - if (htmlElement) - htmlElement.className = "sspictureBox ssselected"; - - this.$selected = htmlElement; - }; - - /**** Init ****/ - - /** - * Display next image from imagelist - */ - this.$Next = function() { - current = next; - this.addSelection(-1); - this.$refresh(); - }; - - /** - * Display previous image from imagelist - */ - this.$Previous = function() { - current = previous; - this.addSelection(1); - this.$refresh(); - }; - - /** - * Move first thumbnail on the left to end of imagebar elementlist. - * It's possible to scroll imagebar to infinity. - */ - this.$tNext = function() { - _self.otBody.appendChild(_self.otBody.childNodes[0]); - }; - - /** - * Move last thumbnail to begining of imagebar elementlist. - * It's possible to scroll imagebar to infinity. - */ - this.$tPrevious = function() { - _self.otBody.insertBefore( - _self.otBody.childNodes[_self.otBody.childNodes.length - 1], - _self.otBody.firstChild); - }; - - this.$showLast = function() { - var timer8; - clearInterval(timer8); - timer8 = setInterval(function() { - if (!onuse) { - if (lastChoose.length) { - current = lastChoose.pop(); - lastChoose = []; - _self.$refresh(); - } - clearInterval(timer8); - } - }, 100); - } - - /** - * When xml representation of new image is set, function initiate redrawing - */ - this.$refresh = function() { - /* Fix for situation when image not exist */ - /*if(_self.oImage && _self.oImage.readyState) { - if(_self.oImage.readyState == "loading") { - onuse = false; - } - }*/ - - if (onuse) { - lastChoose.push(current); - this.$showLast(); - return; - } - - if (play) - clearInterval(timer7); - - var img = _self.oImage; - setSiblings(); - - onuse = true; - - jpf.tween.single(img, { - steps : 3, - type : "fade", - from : 1, - to : 0 - }); - - jpf.tween.single(_self.oTitle, { - steps : 3, - type : "fade", - from : 1, - to : 0, - onfinish : function() { - _self.oTitle.style.visibility = "hidden"; - img.style.left = "0px"; - img.style.top = "0px"; - var _src = (_self.applyRuleSetOnNode("src", current) || _self.defaultimage || _self.defaultthumb); - var _src_temp = img.src; - - img.src = _src; - - /* Safari and Chrome fix for reloading current image */ - if (img.src == _src_temp && (jpf.isChrome || jpf.isSafari)) { - onuse = false; - jpf.tween.single(img, { - steps : 3, - type : "fade", - from : 0, - to : 1 - }); - jpf.tween.single(_self.oTitle, { - steps : 3, - type : "fade", - from : 0, - to : 1 - }); - _self.oTitle.style.visibility = "visible"; - } - - _self.oContent.innerHTML = _self.title == "text" - ? _self.applyRuleSetOnNode("title", current) - : (_self.title == "number+text" - ? "<b>Image " + (_self.getPos() + 1) + " of " - + _self.getTraverseNodes().length - + "</b><br />" - + (_self.applyRuleSetOnNode("title", current) - || _self.defaulttitle) - : "Image " + (_self.getPos() + 1) + " of " - + _self.getTraverseNodes().length); - } - }); - clearTimeout(_self.timer); - }; - - var timer7; - this.$play = function() { - timer7 = setInterval(function() { - play = true; - if (onuse) { - return; - } - _self.$Next(); - }, _self.delay * 1000); - }; - - this.$stop = function() { - clearInterval(timer7); - timer7 = null; - play = false; - }; - - /** - * Creates html representation of slideshow elements based on skin file - * and adds events to each one. - */ - this.$draw = function() { - //Build Main Skin - this.oExt = this.$getExternal(); - this.oInt = this.$getLayoutNode("main", "container", this.oExt); - this.oCurtain = this.$getLayoutNode("main", "curtain", this.oExt); - this.oMove = this.$getLayoutNode("main", "move", this.oExt); - this.oBody = this.$getLayoutNode("main", "body", this.oExt); - this.oContent = this.$getLayoutNode("main", "content", this.oExt); - this.oImage = this.$getLayoutNode("main", "image", this.oExt); - this.oClose = this.$getLayoutNode("main", "close", this.oExt); - this.oBeam = this.$getLayoutNode("main", "beam", this.oExt); - this.oTitle = this.$getLayoutNode("main", "title", this.oExt); - this.oThumbnails = this.$getLayoutNode("main", "thumbnails", this.oExt); - this.otBody = this.$getLayoutNode("main", "tbody", this.oExt); - this.otPrevious = this.$getLayoutNode("main", "tprevious", this.oExt); - this.otNext = this.$getLayoutNode("main", "tnext", this.oExt); - this.oLoading = this.$getLayoutNode("main", "loading", this.oExt); - this.oEmpty = this.$getLayoutNode("main", "empty", this.oExt); - this.oConsole = this.$getLayoutNode("main", "console", this.oExt); - this.oPrevious = this.$getLayoutNode("main", "previous", this.oExt); - this.oPlay = this.$getLayoutNode("main", "play", this.oExt); - this.oNext = this.$getLayoutNode("main", "next", this.oExt); - - var rules = "jpf.lookup(" + this.uniqueId + ").$resize()"; - jpf.layout.setRules(this.pHtmlNode, this.uniqueId + "_scaling", - rules, true); - - this.oPrevious.onclick = - this.oNext.onclick = function(e) { - if ((this.className || "").indexOf("ssprevious") != -1) - _self.$Previous(); - else if ((this.className || "").indexOf("ssnext") != -1) - _self.$Next(); - }; - - var timer3; - this.otPrevious.onmousedown = function(e) { - timer3 = setInterval(function() { - _self.$tPrevious(); - }, 50); - }; - - this.otNext.onmousedown = function(e) { - timer3 = setInterval(function() { - _self.$tNext(); - }, 50); - }; - - this.otNext.onmouseover = function(e) { - _self.$setStyleClass(_self.otNext, "ssnhover"); - }; - - this.otPrevious.onmouseover = function(e) { - _self.$setStyleClass(_self.otPrevious, "ssphover"); - } - - this.otNext.onmouseout = function(e) { - _self.$setStyleClass(_self.otNext, "", ["ssnhover"]); - }; - - this.otPrevious.onmouseout = function(e) { - _self.$setStyleClass(_self.otPrevious, "", ["ssphover"]); - }; - - this.oPlay.onclick = function(e) { - if (timer7) { - _self.$stop(); - _self.$setStyleClass(_self.oPlay, "", ["ssstop"]); - _self.$setStyleClass(_self.oPlay, "ssplay"); - _self.oNext.style.visibility = "visible"; - _self.oPrevious.style.visibility = "visible"; - _self.oThumbnails.style.display = "block"; - } - else { - _self.$play(); - _self.$setStyleClass(_self.oPlay, "", ["ssplay"]); - _self.$setStyleClass(_self.oPlay, "ssstop"); - _self.oNext.style.visibility = "hidden"; - _self.oPrevious.style.visibility = "hidden"; - _self.oThumbnails.style.display = "none"; - } - }; - - document.onmouseup = function(e) { - /* otNex, otPrevious buttons */ - clearInterval(timer3); - - /* from onmove */ - clearInterval(timer); - document.onmousemove = null; - - return false; - }; - - /* mouse wheel */ - var timer4, SafariChromeFix = false; - onmousescroll_ = function(e) { - if (!_self.xmlRoot || _self.oExt.style.display == "none") - return; - - e = e || event; - if (jpf.isChrome || jpf.isSafari) { - SafariChromeFix = SafariChromeFix ? false : true; - if (!SafariChromeFix) - return; - } - - var delta = e.delta; - var temp = current; - var temp_n = _self.getNextTraverse(current); - var temp_p = _self.getNextTraverse(current, true); - - next = temp_n ? temp_n : _self.getFirstTraverseNode(); - previous = temp_p ? temp_p : _self.getLastTraverseNode(); - - current = delta < 0 ? next : previous; - - _self.addSelection(delta); - - if (current !== temp) { - clearInterval(timer4); - timer4 = setInterval(function() { - _self.$refresh(); - clearInterval(timer4); - }, 400); - }; - return false; - }; - - jpf.addEventListener("mousescroll", onmousescroll_); - /* end of mouse wheel */ - - this.oClose.onclick = function() { - _self.hide(); - }; - - /* image move */ - var timer; - this.oImage.onmousedown = function(e) { - e = e || event; - var ww = jpf.isIE - ? document.documentElement.offsetWidth - : window.innerWidth, - wh = jpf.isIE - ? document.documentElement.offsetHeight - : window.innerHeight, - b = _self.oBody, - diff = jpf.getDiff(b), - dx = b.offsetWidth - diff[0] - _self.oImage.offsetWidth, - dy = b.offsetHeight - diff[1] - _self.oImage.offsetHeight; - var t = parseInt(_self.oImage.style.top), - l = parseInt(_self.oImage.style.left); - - var cy = e.clientY, cx = e.clientX; - - if (e.preventDefault) { - e.preventDefault(); - } - - document.onmousemove = function(e) { - e = e || event; - - if (dx < 0) { - if (l + e.clientX - cx >= dx && l + e.clientX - cx <= 0) { - _self.oImage.style.left = (l + e.clientX - cx) + "px"; - } - } - if (dy < 0) { - if (t + e.clientY - cy >= dy && t + e.clientY - cy <= 0) { - _self.oImage.style.top = (t + e.clientY - cy) + "px"; - } - } - - return false; - }; - }; - /* end of image move */ - - this.oImage.onmouseover = function(e) { - onuse = true; - }; - - this.oImage.onmouseout = function(e) { - onuse = false; - }; - }; - - this.$xmlUpdate = function() { - }; - - /** - * It's called when browser window is resizing. Keeps proportion of each - * element, depends on browser window size. - */ - this.$resize = function() { - var ww = jpf.isIE - ? document.documentElement.offsetWidth - : window.innerWidth, - wh = jpf.isIE - ? document.documentElement.offsetHeight - : window.innerHeight, - b = _self.oBody, - img = _self.oImage, - imgWidth = img.offsetWidth, - imgHeight = img.offsetHeight, - diff = jpf.getDiff(b), - wt = Math.min(imgWidth, ww - hSpace); - - if (wt > -1) { - b.style.width = wt + "px"; - b.style.marginLeft = -1 * (wt / 2 - + (parseInt(jpf.getStyle(b, "borderLeftWidth")) || diff[0] / 2)) - + "px"; - } - - var bottomPanel = thumbnails - ? Math.max(_self.oBeam.offsetHeight / 2, - _self.thumbheight / 2 + titleHeight / 2) - : Math.max(_self.oBeam.offsetHeight / 2, - titleHeight / 2); - var ht = Math.min(imgHeight, wh - vSpace - bottomPanel); - if (ht > -1) { - b.style.height = ht + "px"; - b.style.marginTop = -1 * (ht / 2 - + (parseInt(jpf.getStyle(b, "borderTopWidth")) || diff[1] / 2) - + bottomPanel) - + "px"; - } - - /* refreshing cursor and move icon */ - _self.oMove.style.display = - imgWidth < ww - hSpace && imgHeight < wh - vSpace - ? "none" - : "block"; - img.style.cursor = - imgWidth < ww - hSpace && imgHeight < wh - vSpace - ? "default" - : "move"; - - /* reset image position */ - img.style.left = "0px"; - img.style.top = "0px"; - } - - /** - * It's called when thumbnail has been clicked. - * Adds selection to thumbnail and shows new image. - * - * @param {HTMLElement} oThumb html representation of thumbnail element - */ - this.$clickThumb = function(oThumb) { - current = jpf.xmldb.getNode(oThumb); - this.addSelection(); - this.$refresh(); - } - - this.$checkThumbSize = function() { - /*if(parseInt(this.otBody.childNodes[0].style.width) > 0) { - return; - }*/ - - var nodes = this.getTraverseNodes(), length = nodes.length; - var widthSum = 0; - - for (var i = 0, diff, thumb, pictureBox, h, w, bh; i < length; i++) { - pictureBox = this.otBody.childNodes[i]; - thumb = this.applyRuleSetOnNode("thumb", nodes[i]); - - diff = jpf.getDiff(pictureBox); - - bh = this.thumbheight - 10 - diff[1]; - - img = new Image(); - document.body.appendChild(img); - img.src = thumb ? thumb : this.defaultthumb; - - if (this.scalewidth) { - h = bh; - if (img.height < bh) { - w = img.width; - } - else { - img.setAttribute("height", bh); - w = img.width; - } - } - else { - h = w = bh; - } - - widthSum += w + diff[0] - + (parseInt(jpf.getStyle(pictureBox, "margin-left") - || jpf.getStyle(pictureBox, "marginLeft"))) - + (parseInt(jpf.getStyle(pictureBox, "margin-right") - || jpf.getStyle(pictureBox, "marginRight"))); - document.body.removeChild(img); - pictureBox.style.width = w + "px"; - } - - var thumbDiff = jpf.getDiff(this.otBody); - - this.otPrevious.style.visibility = this.otNext.style.visibility = - widthSum < this.oThumbnails.offsetWidth - thumbDiff[0] - ? "hidden" - : "visible"; - } - - this.$load = function(xmlRoot) { - jpf.xmldb.addNodeListener(xmlRoot, this); - var nodes = this.getTraverseNodes(), - length = nodes.length; - - for (var i = 0, diff, thumb, pictureBox, h, w, bh; i < length; i++) { - pictureBox = this.otBody.appendChild(document.createElement("div")); - thumb = this.applyRuleSetOnNode("thumb", nodes[i]); - pictureBox.style.backgroundImage = 'url(' + (thumb ? thumb : this.defaultthumb) + ')'; - - this.$setStyleClass(pictureBox, "sspictureBox"); - diff = jpf.getDiff(pictureBox); - - bh = this.thumbheight - 10 - diff[1]; - - img = new Image(); - document.body.appendChild(img); - img.src = thumb ? thumb : this.defaultthumb; - - if (this.scalewidth) { - h = bh; - if (img.height < bh) { - w = img.width; - } - else { - img.setAttribute("height", bh); - w = img.width; - } - } - else { - h = w = bh; - } - - document.body.removeChild(img); - - pictureBox.style.height = h + "px"; - pictureBox.style.width = w + "px"; - pictureBox.style.marginTop = pictureBox.style.marginBottom = "5px"; - - jpf.xmldb.nodeConnect(this.documentId, nodes[i], pictureBox, this); - - pictureBox.onclick = function(e) { - _self.$clickThumb(this); - } - } - - if (length != this.length) - this.setProperty("length", length); - - this.$paint(); - } - - this.$show = function() { - /* Removes window scrollbars */ - this.lastOverflow = document.documentElement.style.overflow == "hidden" - ? "auto" - : document.documentElement.style.overflow; - - document.documentElement.style.overflow = "hidden"; - - _self.oExt.style.display = "block"; - _self.oInt.style.display = "block"; - _self.oBody.style.display = "block"; - - jpf.tween.single(_self.oCurtain, { - steps : 10, - type : "fade", - from : 0, - to : 0.7, - onfinish : function() { - } - }); - this.$refresh(); - } - - this.$hide = function () { - /* Restores window scrollbars */ - document.documentElement.style.overflow = this.lastOverflow; - _self.oExt.style.display = "block"; - _self.oBody.style.display = "none"; - - jpf.tween.single(_self.oCurtain, { - steps : 10, - type : "fade", - from : 0.7, - to : 0, - onfinish : function() { - _self.oInt.style.display = "none"; - _self.oExt.style.display = "none"; - _self.oBody.style.display = "none"; - } - }); - } - - this.$destroy = function() { - this.otNext.onmouseover = - this.otPrevious.onmouseover = - this.otNext.onmouseout = - this.otPrevious.onmouseout = - this.oExt.onresize = - this.oImage.onmousedown = - this.otNext.onmousedown = - this.otPrevious.onmousedown = - this.oNext.onclick = - this.oPrevious.onclick = null; - - this.removeEventListener("onkeydown", onkeydown_); - this.removeEventListener("mousescroll", onmousescroll_); - - this.x = null; - } - - this.$loadJml = function(x) { - var nodes = x.childNodes; - jpf.JmlParser.parseChildren(x, null, this); - }; - - var oEmpty; - this.$setClearMessage = function(msg, className) { - var ww = jpf.isIE - ? document.documentElement.offsetWidth - : window.innerWidth; - var bp = parseInt(jpf.getStyle(_self.otPrevious, "width")); - var bn = parseInt(jpf.getStyle(_self.otNext, "width")); - var ew = parseInt(jpf.getStyle(_self.oEmpty, "width")); - - oEmpty = this.oCurtain.appendChild(this.oEmpty.cloneNode(true)); - - jpf.xmldb.setNodeValue(oEmpty, msg || ""); - - oEmpty.setAttribute("id", "empty" + this.uniqueId); - oEmpty.style.display = "block"; - oEmpty.style.left = ((ww - ew) / 2 - bp - bn) + "px"; - jpf.setStyleClass(oEmpty, className, ["ssloading", "ssempty", "offline"]); - }; - - this.$removeClearMessage = function() { - if (!oEmpty) - oEmpty = document.getElementById("empty" + this.uniqueId); - if (oEmpty && oEmpty.parentNode) - oEmpty.parentNode.removeChild(oEmpty); - }; - - this.$setCurrentFragment = function(fragment) { - this.otBody.appendChild(fragment); - - this.dataset = fragment.dataset; - - if (!jpf.window.hasFocus(this)) - this.blur(); - }; - - this.$getCurrentFragment = function() { - var fragment = document.createDocumentFragment(); - - while (this.otBody.childNodes.length) { - fragment.appendChild(this.otBody.childNodes[0]); - } - fragment.dataset = this.dataset; - - return fragment; - }; -}).implement(jpf.Presentation, jpf.DataBinding, jpf.Cache, - jpf.MultiselectBinding); - - - -/*FILEHEAD(/var/lib/jpf/src/elements/submitform.js)SIZE(-1077090856)TIME(1238933683)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -/** - * Element allowing special form functionality to a set of JML - * elements. This element is an alias for j:xforms offering - * xform compatible strategies with relation to submitting the form's data. - * This element also offers form paging, including validation between - * and over pages. Buttons placed inside this element can contain an action - * attribute specifying whether they behave as next, previous or finish(submit) - * buttons. This element is <u>not</u> necesary for simple forms. like the - * normal html webforms (see {@link baseclass.validation}). - * - * @constructor - * @define submitform, xforms - * @allowchild page, {elements}, {anyjml} - * @addnode elements - * - * @inherits jpf.DataBinding - * @inherits jpf.BaseTab - * @inherits jpf.ValidationGroup - * - * @author Ruben Daniels - * @version %I%, %G% - * @since 0.9 - * - * @todo please refactor. This element should be cleared of most its 'features' its all bollocks. - */ - -jpf.xforms = -jpf.submitform = jpf.component(jpf.NODE_VISIBLE, function(){ - this.canHaveChildren = true; - this.$focussable = false; - - this.elements = {}; - var buttons = { - "next" : [], - "previous" : [], - "submit" : [], - "follow" : [] - }; - - this.$focussable = false; - //this.allowMultipleErrors = true; - - this.inputs = []; - this.errorEl = {}; - this.cq = {}; - this.reqs = []; - this.conditionDeps = {}; - this.depends = {}; - - this.loadValueDeps = {}; - this.loadValues = {}; - - this.listsHeldBack = {}; - this.nextHeldBack = {}; - - this.activepagenr = 0; - this.zCount = 1000000; - - this.clear = function(){}; - - /* ******************************************************************** - PUBLIC METHODS - *********************************************************************/ - - this.showLoader = function(checked, nr){ - if (checked) { - var page = nr ? this.getPage(nr) : this.getNextPage(); - if (!page || page.isRendered) return; - } - - if (this.loadState) { - this.loadState.style.display = "block"; - - var message = this.getPage().$jml.getAttribute("loadmessage"); - if (message) - (jpf.xmldb.selectSingleNode("div[@class='msg']", this.loadState) - || this.loadState).innerHTML = message; - } - }; - - this.hideLoader = function(){ - if (this.loadState) - this.loadState.style.display = "none"; - }; - - var nextpagenr; - this.getNextPage = function(){ - var nextpage, pageNr = this.activepagenr; - do { - nextpage = this.getPage(++pageNr); - } - while(nextpage && !this.testCondition(nextpage.condition)); - - nextpagenr = pageNr; - return nextpage; - }; - - this.next = function(no_error){ - if (!this.testing && !this.isValid(null, null, this.getPage())) { - this.hideLoader(); - return;//checkRequired - } - - //var nextpage = nextpagenr ? this.getPage(nextpagenr) : this.getNextPage(); - //if(this.dispatchEvent("beforeswitch", nextpagenr) === false)return false; - - //this.getPage().hide(); - this.set(this.activepagenr + 1);//nextpagenr - //this.activepagenr = nextpagenr; - - //if(!no_error && !nextpage) throw new Error(jpf.formatErrorString(1006, this, "Form", "End of pages reached.")); - - //nextpage.show(); - //if(nextpage.isRendered) this.hideLoader(); - //else nextpage.addEventListener("afterrender", function(){this.parentNode.hideLoader()}); - - for (var prop in buttons) { - if (!prop.match(/next|previous|submit/)) continue; - this.updateButtons(prop); - } - - nextpagenr = null; - - /*var jmlNode = this; - setTimeout(function(){ - jmlNode.dispatchEvent("afterswitch", jmlNode.activepagenr, nextpage); - }, 1);*/ - }; - - this.previous = function(){ - //var active = this.activepagenr; - //do{var prevpage = this.getPage(--active);} - //while(prevpage && !this.testCondition(prevpage.condition)); - - //if(this.dispatchEvent("beforeswitch", active) === false) return false; - - this.set(this.activepagenr - 1); - //this.getPage().hide(); - //this.activepagenr = active; - - //if(!prevpage) throw new Error(jpf.formatErrorString(1006, this, "Form", "End of pages reached.")); - - //prevpage.show(); - - //if(prevpage.isRendered) this.hideLoader(); - //else prevpage.addEventListener("afterrender", function(){this.parentNode.hideLoader()}); - - for (var prop in buttons) { - if (!prop.match(/next|previous|submit/)) continue; - this.updateButtons(prop); - } - - //this.dispatchEvent("afterswitch", this.activepagenr); - }; - - this.$enable = function(){ - forbuttons('enable'); - }; - - this.$disable = function(){ - forbuttons('disable'); - }; - - function forbuttons(feat){ - var arr = ["next", "previous", "submit", "follow"]; - for (var k = 0; k < arr.length; k++) { - for (var i = 0; i < buttons[arr[k]].length; i++) { - buttons[arr[k]][i][feat](); - } - } - } - - this.processValueChange = function(oFormEl){ - if (this.conditionDeps[oFormEl.name]) { - var c = this.conditionDeps[oFormEl.name]; - for (var i = 0; i < c.length; i++) { - if (this.testCondition(c[i].condition)) - c[i].setActive(); - else - c[i].setInactive(); - } - } - - for (var prop in buttons) { - if (!prop.match(/next|previous|submit/)) continue; - this.updateButtons(prop); - } - - this.setLoadValues(oFormEl.name); - }; - - /* *********************** - Actions - ************************/ - - /* ******************************************************************** - PRIVATE METHODS - *********************************************************************/ - this.addInput = function(objEl){ - var name = objEl.name; - objEl.$validgroup = this; - - if (this.elements[name] && !this.elements[name].length) { - this.elements[name] = [this.elements[name]]; - this.elements[name].getValue = new Function( - "for (var i = 0; i < this.length; i++)\ - if (this[i].oInt.checked)\ - return this[i].getValue();"); - } - - if (this.elements[name]) - this.elements[name].push(objEl); - else - this.elements[name] = objEl; - - if (this.cq[name]) { - for (var i = 0; i < this.cq[name].length; i++) { - this.cq[name][i][1].call(this.cq[name][i][0], objEl); - objEl.labelEl = this.cq[name][i][0]; - } - } - - if (objEl.$jml.getAttribute("dependson")) { - var o = self[objEl.$jml.getAttribute("dependson")]; - if (!this.depends[o.name]) - this.depends[o.name] = []; - this.depends[o.name].push(objEl); - objEl.setInactive(); - } - - if (objEl.nodeFunc == jpf.NODE_VISIBLE) - objEl.setZIndex(--this.zCount); - - if (this.listsHeldBack[name]) { - var ld = this.listsHeldBack[name]; - this.loadLists(ld[0], ld[1], ld[2]); - this.listsHeldBack[name] = null; - } - - if (this.nQuest && objEl.$jml.getAttribute("checknext") == "true") { - if (this.lastEl) { - this.lastEl.nextEl = objEl; - objEl.prevEl = this.lastEl; - } - this.lastEl = objEl; - - if (objEl.prevEl && objEl.$jml.getAttribute("show") != "true" - && !this.nextHeldBack[name] && !objHasValue(objEl)) - objEl.setInactive(true); - else if (this.condActiveCheck[objEl.name]) - this.condActiveCheck[objEl.name].setActive(); - - //terrible code, but what the heck - if (this.condActiveCheck[objEl.name]) { - objEl.container = this.condActiveCheck[objEl.name]; - - function activateHandler(){ - if (this.form.hasActiveElement(this.container)) - this.container.setActive(); - else - this.container.setInactive(); - } - - objEl.addEventListener("activate", activateHandler); - objEl.addEventListener("deactivate", activateHandler); - } - } - }; - - this.hasActiveElement = function(objEl){ - var nodes = objEl.$jml.getElementsByTagName("*"); - for (var i = 0; i < nodes.length; i++) { - if (!nodes[i].getAttribute("id")) continue; - var comp = this.elements[nodes[i].getAttribute("id")]; - if (comp && comp.form == this && comp.isActive) - return true; - } - - return false; - }; - - this.condActiveCheck = {}; - - this.getButtons = function(action){ - return buttons[action]; - }; - - this.registerButton = function(action, oBtn){ - buttons[action].push(oBtn); - - if (oBtn.condition) - this.parseCondition(oBtn, oBtn.condition); - this.updateButtons(action, oBtn); - - if (action == "follow") return; - - var jmlNode = this; - oBtn.onclick = function(){ - jmlNode.showLoader(true); - setTimeout(function(){ jmlNode[action](); }, 10); - }; - - /* - new Function( - "jpf.lookup(" + this.uniqueId + ").showLoader(true);setTimeout("jpf.lookup(" + this.uniqueId + ")." + action + "()", 10)" - ); - - action == "previous" ? - "jpf.lookup(" + this.uniqueId + ")." + action + "()" : - "jpf.lookup(" + this.uniqueId + ").showLoader();setTimeout("jpf.lookup(" + this.uniqueId + ")." + action + "()", 10)" - ); - */ - }; - - //refactor to give buttons classes, so they can decide what to do when inactive - this.updateButtons = function(action, singleBtn){ - return false;// - - if (!buttons[action]) return false; - - var result = true; - if (action == "previous" && this.activepagenr == 0) - result = false; - else if (!this.testing && action == "next" && !this.isValid()) - result = false; - else if (action == "next") { - var cp = this.activepagenr; - do { - var nextpage = this.getPage(++cp); - } - while(nextpage && !this.testCondition(nextpage.condition)); - - if (!nextpage) - result = false; - } - - if (this.testing) - return true; - - var buttons = singleBtn ? [singleBtn] : buttons[action]; - for (var i = 0; i < buttons.length; i++) { - if (result && (!buttons[i].condition || this.testCondition(buttons[i].condition))) - buttons[i].setActive(); - else - buttons[i].setInactive(); - } - - return true; - }; - - this.setLoadValues = function(item, clearElements, noload){ - var lvDep = this.loadValueDeps[item]; - if (!lvDep) return; - //alert(item); - for (var i = 0; i < lvDep.length; i++) { - try{ - if (!eval(lvDep[i][1])) - throw new Error(); - } - catch (e) { - if (clearElements) { - var oEl = self[lvDep[i][0].getAttribute("element")]; - if (oEl) - this.clearNextQuestionDepencies(oEl, true);//might be less optimized... - - if (lvDep[i][0].tagName == "LoadValue") - this.dispatchEvent("clearloadvalue", lvDep[i][0]); - - /*else if(lvDep[i][0].getAttribute("lid")){ - var lid = lvDep[i][0].getAttribute("lid"); - var nodes = this.xmlRoot.selectSingleNode("node()[@lid='" + lid + "']"); - - for(var i=0;i<nodes.length;i++){ - jpf.xmldb.removeNode(nodes[i]); - } - }*/ - } - continue; - } - - if (noload) continue; - - if (lvDep[i][0].getAttribute("runonrequest") != "true") { - this.processLoadRule(lvDep[i][0], lvDep[i][2], lvDep[i]); - } - else - if (self[lvDep[i][0].getAttribute("element")]) { - //This should be different :'( - self[lvDep[i][0].getAttribute("element")].clear(); - } - } - }; - - this.processLoadRule = function(xmlCommNode, isList, data){ - //Extend with Method etc - if (!jpf.teleport.hasLoadRule(xmlCommNode)) return; - - this.dispatchEvent(isList ? "beforeloadlist" : "beforeloadvalue"); - - //Process basedon arguments - var nodes = xmlCommNode.childNodes;//selectNodes("node()[@arg-type | @arg-nr]"); //Safari bugs on this XPath... hack! - if (nodes.length) { - var arr, arg = xmlCommNode.getAttribute(jpf.teleport.lastRuleFound.args); - arg = arg ? arg.split(";") : []; - - if (xmlCommNode.getAttribute("argarray")) - arr = []; - for (var j = 0; j < nodes.length; j++) { - if (nodes[j].nodeType != 1) continue; //for safari - if (nodes[j].getAttribute("argtype").match(/fixed|param|nocheck/)) { //Where does item come from??? || item == nodes[j].getAttribute("element") - var el = self[nodes[j].getAttribute("element")]; - var xpath = el.getMainBindXpath(); - var xNode = jpf.xmldb.createNodeFromXpath(this.xmlRoot, xpath); - var nType = xNode.nodeType; - (arr || arg)[nodes[j].getAttribute("argnr") || j] = - "xpath:" + xpath + (nType == 1 ? "/text()" : ""); - } - else - if(nodes[j].getAttribute("argtype") == "xpath") { - (arr || arg)[nodes[j].getAttribute("argnr") || j] = - "xpath:" + nodes[j].getAttribute("select");//jpf.getXmlValue(this.xmlRoot, ); - } - } - - if (xmlCommNode.getAttribute("argarray")) { - arg[xmlCommNode.getAttribute("argarray")] = "(" + arr.join(",") + ")"; - } - - xmlCommNode.setAttribute(jpf.teleport.lastRuleFound.args, arg.join(";")); - } - - //this.xmlRoot.firstChild - //if(confirm("do you want to debug?")) throw new Error(); - - var jNode = self[xmlCommNode.getAttribute("element")]; - if (jNode && jNode.nodeFunc == jpf.NODE_VISIBLE) - jNode.$setStyleClass(jNode.oExt, "loading", ["loaded"]); - - //if(!isList && !data[0].getAttribute("lid")) data[0].setAttribute("lid", jpf.getUniqueId()); - jpf.teleport.callMethodFromNode(xmlCommNode, this.xmlRoot, - Function('data', 'state', 'extra', 'jpf.lookup(' + this.uniqueId - + ').' + (isList ? 'loadLists' : 'loadValues') - + '(data, state, extra)'), null, data); - }; - - this.registerCondition = function(objEl, strCondition, no_parse){ - if (!no_parse) - this.parseCondition(objEl, strCondition); - - var forceActive = false; - if (objEl.onlyWhenActive) { - var nodes = objEl.$jml.getElementsByTagName("*"); - for (var i = 0; i < nodes.length; i++) { - if (!nodes[i].getAttribute("id")) continue; - - if (this.nextHeldBack[nodes[i].getAttribute("id")]) - forceActive = true; - else - if (nodes[i].getAttribute("ref") && this.xmlRoot - && jpf.xmldb.getNodeValue(this.xmlRoot - .selectSingleNode(nodes[i].getAttribute("ref"))) != "") { - forceActive = true; - nodes[i].setAttribute("show", "true"); - } - - this.condActiveCheck[nodes[i].getAttribute("id")] = objEl; - } - } - - if (forceActive || this.testCondition(objEl.condition) - && (!objEl.onlyWhenActive || this.hasActiveElement(objEl, true))) - objEl.setActive(); - else - objEl.setInactive(); - - var matches = !no_parse - ? strCondition.match(/(\W|^)(\w+)(?:\=|\!\=)/g) - : strCondition.match(/(\b|^)([\w\.]+)/g); - if (!matches) return; - - for (var i = 0; i < matches.length; i++) { - if (!no_parse) { - var m = matches[i].replace(/(?:\=|\!\=)$/, "").replace(/(^\s+|\s+$)/g, ""); - } - else { - var m = matches[i].split("."); - if (m.length < 2) continue; - m = m[0]; - } - - if (!this.conditionDeps[m]) - this.conditionDeps[m] = Array(); - this.conditionDeps[m].push(objEl); - } - }; - - this.testCondition = function(strCondition){ - //somename='somestr' and (sothername='que' or iets='niets') and test=15 - - try { - return eval(strCondition); - } - catch(e) { - return false; - //throw new Error(jpf.formatErrorString(1009, this, "Form", "Invalid conditional statement [" + strCondition + "] : " + e.message)); - } - }; - - this.loadValues = function(data, state, extra){ - if (state != jpf.SUCCESS) { - if (extra.retries < jpf.maxHttpRetries) - return extra.tpModule.retry(extra.id); - else - throw new Error(jpf.formatErrorString(1010, this, "LoadVaLue", "Could not load values with LoadValue query :\n\n" + extra.message)); - } - - if (extra.userdata[0].getAttribute("returntype") == "array") { - //integrate array - for (var i = 0; i < data.length; i++) { - var pnode = this.xmlRoot.selectSingleNode("//" + data[i][0]); - jpf.xmldb.setTextNode(pnode, data[i][1] || ""); - } - } - else { - //integrate xml - if (typeof data != "object") - data = jpf.getXmlDom(data).documentElement; - var nodes = data.childNodes; - var strUnique = extra.userdata[0].getAttribute("unique"); - - for (var i = nodes.length - 1; i >= 0; i--) { - var xmlNode = nodes[i]; - var unique = strUnique ? xmlNode.selectSingleNode(strUnique) : false; - - var node = unique - ? this.xmlRoot.selectSingleNode("node()[" + strUnique - + " = '" + unique.nodeValue + "']") - : null; - if (node) { - //Move all this into the xmldb - jpf.xmldb.copyConnections(node, xmlNode); - jpf.xmldb.notifyListeners(xmlNode); - - //node.setAttribute("lid", data.getAttribute("lid")); - - //hack!! - should be recursive - var valueNode = xmlNode.selectSingleNode("value"); - if (valueNode) { - jpf.xmldb.copyConnections(node - .selectSingleNode("value"), valueNode); - jpf.xmldb.notifyListeners(valueNode); - } - } - - this.xmlRoot.insertBefore(xmlNode, node); //consider using replaceChild here - if (node) - this.xmlRoot.removeChild(node); - jpf.xmldb.applyChanges("attribute", xmlNode); - } - } - - this.dispatchEvent("afterloadvalue"); - }; - - this.loadLists = function(data, state, extra){ - if (state != jpf.SUCCESS){ - if (extra.retries < jpf.maxHttpRetries) - return extra.tpModule.retry(extra.id); - else - throw new Error(jpf.formatErrorString(1011, this, "Load List", "Could not load data with LoadList query :\n\n" + extra.message)); - } - - if (!self[extra.userdata[0].getAttribute("element")]) - return this.listsHeldBack[extra.userdata[0].getAttribute("element")] = - [data, state, extra]; - - //set style - var jNode = self[extra.userdata[0].getAttribute("element")]; - if (jNode && jNode.nodeFunc == jpf.NODE_VISIBLE) { - jNode.$setStyleClass(jNode.oExt, "loaded", ["loading"]); - setTimeout("var jNode = jpf.lookup(" + jNode.uniqueId + ");\ - jNode.$setStyleClass(jNode.oExt, '', ['loading', 'loaded']);", 500); - } - - if (extra.userdata[0].getAttribute("clearonload") == "true") { - jNode.clearSelection(); - //this.setLoadValues(jNode.name, true); - this.clearNextQuestionDepencies(jNode, true); - } - - //load xml in element - jNode.load(data); - //if(!jNode.value){ - //this.clearNextQuestionDepencies(jNode, true); - //} - - this.dispatchEvent("afterloadlist"); - }; - - /*this.isValid = function(checkReq, setError, page){ - if(!page) page = this.getPage() || this; - var found = checkValidChildren(page, checkReq, setError); - - //Global Rules - // - - return !found; - } - - this.validate = function(){ - if(!this.isValid()){ - - } - }*/ - - //HACK! - this.reset = function(){ - //Clear all error states - for (name in this.elements) { - var el = this.elements[name]; - - //Hack!!! maybe traverse - if (el.length) { - throw new Error(jpf.formatErrorString(this, "clearing form", "Found controls without a name or with a name that isn't unique. Please give all elements of your submitform an id: '" + name + "'")); - } - - el.clearError(); - if (this.errorEl[name]) - this.errorEl[name].hide(); - - if (el.hasFeature(__MULTIBINDING__)) - el.$getMultiBind().clear(); - else - el.clear(); - } - }; - - /* *********************** - Databinding - ************************/ - - this.$xmlUpdate = function(action, xmlNode, listenNode, UndoObj){ - //this.setConnections(this.xmlRoot, "select"); - //if(confirm("debug? " + this.toString())) debugger; - this.dispatchEvent("xmlupdate"); - }; - - this.smartBinding = {}; - - this.$load = function(XMLRoot, id){ - jpf.xmldb.addNodeListener(XMLRoot, this); - //this.setConnections(jpf.xmldb.getElement(XMLRoot, 0), "select"); - //this.setConnections(XMLRoot, "select"); - }; - - function objHasValue(objEl){ - var oCheck = objEl.hasFeature(__MULTISELECT__) - ? objEl.$getMultiBind() - : objEl; - if (!oCheck) - return false; - return oCheck.applyRuleSetOnNode(oCheck.mainBind, - oCheck.xmlRoot, null, true); - } - - //Reset form - function onafterload(){ - //Clear all error states - for (name in this.elements) { - if (jpf.isSafari && (!this.elements[name] - || !this.elements[name].$jmlLoaders)) - continue; - - //Hack!!! maybe traverse - if (this.elements[name].length) { - throw new Error(jpf.formatErrorString(1012, this, "clearing form", "Found controls without a name or with a name that isn't unique("+name+"). Please give all elements of your submitform an id: '" + name + "'")); - } - - this.elements[name].clearError(); - if(this.errorEl[name]) - this.errorEl[name].hide(); - } - - if (this.nQuest) { - //Show all controls and labels which are in the nquest stack - for (name in this.elements) { - - var objEl = this.elements[name]; - - if (objEl.$jml.getAttribute("checknext") == "true") { - if (objHasValue(objEl)) {//oCheck.value || - objEl.setActive(); - if (this.condActiveCheck[name]) - this.condActiveCheck[name].setActive(); - } - else { - objEl.setInactive(true); - } - } - else { - //que ??? - if (objEl.tagName == "Radiogroup" && objEl.current) - objEl.current.uncheck(); - } - } - } - - if (this.nQuest && this.xmlRoot.childNodes.length > 0) { - var element = this.nQuest.getAttribute("final"); - var jmlNode = self[element].$jml;//jpf.xmldb.selectSingleNode(".//node()[@id='" + element + "']", this.$jml); - - if (jmlNode && !jpf.xmldb.getBoundValue(jmlNode, this.xmlRoot)) { - var fNextQNode = jpf.xmldb - .selectSingleNode(".//node()[@checknext='true']", this.$jml); - if (!fNextQNode) return; - self[fNextQNode.getAttribute("id")].dispatchEvent("afterchange"); - } - } - } - this.addEventListener("afterload", onafterload); - this.addEventListener("afterinsert", onafterload); - - this.addEventListener("beforeload", function(){ - if (!this.smartBinding || !this.smartBinding.actions) return; - var nodes = this.smartBinding.actions.LoadList; - if (nodes) { - for (var objEl, i = 0; i < nodes.length; i++) { - if (!nodes[i].getAttribute("element") - || !(objEl = this.elements[nodes[i].getAttribute("element")])) - continue; - objEl.clear(); - } - } - - var nodes = this.smartBinding.actions.NextQuestion; - if (nodes) { - for (var objEl, i = 0; i < nodes.length; i++) { - if (!nodes[i].getAttribute("final") - || !(objEl = this.elements[nodes[i].getAttribute("element")])) - continue; - objEl.clear(); - } - } - }); - - /* ********* - INIT - **********/ - this.inherit(jpf.JmlElement); /** @inherits jpf.JmlElement */ - - this.addOther = function(tagName, oJml){ - if (tagName == "loadstate") { - var htmlNode = jpf.getFirstElement(oJml); - this.loadState = jpf.xmldb.htmlImport(htmlNode, this.oInt); - this.loadState.style.display = "none"; - } - }; - - this.$draw = function(){ - //Build Main Skin - this.oPages = this.oExt = this.$getExternal(); - this.oInt = this.$getLayoutNode("main", "container", this.oExt); - this.oExt.host = this; - }; - - /** - * Submit this form - * Example: - * <j:submitform - * [action="url" method="get|post|urlencoded-post" [ref="/"] ] - * [submit="<save_data>"] - * [submittype="json|xml|native"] - * [useelements="boolean"] - * [model="id"] - * > - * <j:Button action="submit" [submission="@id"] [model=""] /> - * </j:submitform> - */ - this.submit = function(submissionId){ - if(!this.isValid()) return; - if(!this.$model) return; //error? - - var type = this.method == "urlencoded-post" - ? "native" - : (this.type || "xml"); - var instruction = submissionId || this.action - ? ((this.method.match(/post/) ? "url.post:" : "url:") + this.action) - : ""; - - this.$model.submit(instruction, type, this.useComponents, this.ref); - }; - - this.setModel = function(model, xpath){ - this.$model = model; - }; - - this.$loadJml = function(x){ - this.testing = x.getAttribute("testing") == "true"; - - this.action = this.$jml.getAttribute("action"); - this.ref = this.$jml.getAttribute("ref"); - this.type = this.$jml.getAttribute("submittype") || "native"; - this.method = (this.$jml.getAttribute("method") || "get").toLowerCase(); - this.useComponents = this.$jml.getAttribute("usecomponents") || true; - - jpf.setModel(x.getAttribute("model"), this); - - this.$loadChildren(function(xmlPage) { - this.validation = xmlPage.getAttribute("validation") || "true"; - this.invalidmsg = xmlPage.getAttribute("invalidmsg"); - }); - }; -}).implement( - jpf.DataBinding, - jpf.BaseTab, - jpf.ValidationGroup -); - - - -/*FILEHEAD(/var/lib/jpf/src/elements/markupedit.js)SIZE(-1077090856)TIME(1238933683)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-var HAS_CHILD = 1 << 1;
-var IS_CLOSED = 1 << 2;
-var IS_LAST = 1 << 3;
-var IS_ROOT = 1 << 4;
-
-/**
- * Element for editing markup in the same way firebug provides.
- *
- * @experimental
- * @todo see if it's possible to create a tree baseclass
- * @constructor
- * @allowchild {smartbinding}
- * @addnode elements:markupedit
- *
- * @inherits jpf.Validation
- * @inherits jpf.XForms
- * @inherits jpf.MultiSelect
- * @inherits jpf.Cache
- * @inherits jpf.Presentation
- * @inherits jpf.DataBinding
- * @inherits jpf.JmlElement
- *
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.98.3
- *
- * @binding css Determines a css class for a node.
- * @binding empty Determines the empty message of a node.
- */
-jpf.markupedit = jpf.component(jpf.NODE_VISIBLE, function(){
- this.isTreeArch = true; // Tree Architecture for loading Data
- this.$focussable = true; // This object can get the focus
-
- this.clearMessage = "There are no items";
- this.startClosed = true;
- this.animType = 0;
- this.animSteps = 3;
- this.animSpeed = 20;
-
- this.dynCssClasses = [];
-
- var _self = this;
-
- /* ********************************************************************
- PUBLIC METHODS
- *********************************************************************/
-
- /**
- * Sets an attribute to an xml node
- *
- * @action
- */
- this.setAttributeValue = function(xmlNode, name, value){
- if (!xmlNode)
- xmlNode = this.indicator || this.selected;
-
- if (!xmlNode || xmlNode.getAttribute(name) == value)
- return;
-
- this.executeAction("setAttribute", [xmlNode, name, value],
- "setAttributeValue", xmlNode);
- };
-
- /**
- * Renames an attribute of an xml node
- *
- * @action
- */
- this.renameAttribute = function(xmlNode, name, newName){
- if (!xmlNode)
- xmlNode = this.indicator || this.selected;
-
- if (!xmlNode || name == newName)
- return;
-
- this.executeAction("multicall", [
- {func: "removeAttribute", args: [xmlNode, name]},
- {func: "setAttribute", args: [xmlNode, newName, xmlNode.getAttribute(name)]}
- ], "renameAttribute", xmlNode);
- };
-
- /**
- * Sets a text node to an xml node
- *
- * @action
- */
- this.setTextNode = function(xmlNode, value){
- if (!xmlNode)
- xmlNode = this.indicator || this.selected;
-
- if (!xmlNode || jpf.getXmlValue(xmlNode, "text()") == value)
- return;
-
- this.executeAction("setTextNode", [xmlNode, value], "setTextNode", xmlNode);
- };
-
-
- /**
- * @private
- */
- this.slideToggle = function(htmlNode, force){
- if(this.noCollapse)
- return;
-
- if (!htmlNode)
- htmlNode = this.$selected;
-
- var id = htmlNode.getAttribute(jpf.xmldb.htmlIdTag);
- while (!id && htmlNode.parentNode)
- var id = (htmlNode = htmlNode.parentNode)
- .getAttribute(jpf.xmldb.htmlIdTag);
-
- var elClass, container = this.$getLayoutNode("item", "container", htmlNode);
- if (jpf.getStyle(container, "display") == "block") {
- if (force == 1) return;
- elClass = this.$getLayoutNode("item", "openclose", htmlNode);
- elClass.className = elClass.className.replace(/min/, "plus");
- this.slideClose(container, jpf.xmldb.getNode(htmlNode));
- }
- else {
- if (force == 2) return;
- elClass = this.$getLayoutNode("item", "openclose", htmlNode);
- elClass.className = elClass.className.replace(/plus/, "min");
- this.slideOpen(container, jpf.xmldb.getNode(htmlNode));
- }
- };
-
- var lastOpened = {};
- /**
- * @private
- */
- this.slideOpen = function(container, xmlNode, immediate){
- if (!xmlNode)
- xmlNode = this.selected;
-
- var htmlNode = jpf.xmldb.findHTMLNode(xmlNode, this);
- if (!container)
- container = this.$findContainer(htmlNode);
-
- if (this.singleopen) {
- var pNode = this.getTraverseParent(xmlNode)
- var p = (pNode || this.xmlRoot).getAttribute(jpf.xmldb.xmlIdTag);
- if (lastOpened[p] && lastOpened[p][1] != xmlNode
- && this.getTraverseParent(lastOpened[p][1]) == pNode)
- this.slideToggle(lastOpened[p][0], 2);//lastOpened[p][1]);
- lastOpened[p] = [htmlNode, xmlNode];
- }
-
- container.style.display = "block";
-
- if (immediate) {
- container.style.height = "auto";
- return;
- }
-
- jpf.tween.single(container, {
- type : 'scrollheight',
- from : 0,
- to : container.scrollHeight,
- anim : this.animType,
- steps : this.animOpenStep,
- interval: this.animSpeed,
- onfinish: function(container){
- if (xmlNode && _self.hasLoadStatus(xmlNode, "potential")) {
- setTimeout(function(){
- _self.$extend(xmlNode, container);
- });
- container.style.height = "auto";
- }
- else {
- //container.style.overflow = "visible";
- container.style.height = "auto";
- }
- }
- });
- };
-
- /**
- * @private
- */
- this.slideClose = function(container, xmlNode){
- if (this.noCollapse)
- return;
-
- if (!xmlNode)
- xmlNode = this.selected;
-
- if (this.singleopen) {
- var p = (this.getTraverseParent(xmlNode) || this.xmlRoot)
- .getAttribute(jpf.xmldb.xmlIdTag);
- lastOpened[p] = null;
- }
-
- container.style.height = container.offsetHeight;
- container.style.overflow = "hidden";
-
- jpf.tween.single(container, {
- type : 'scrollheight',
- from : container.scrollHeight,
- to : 0,
- anim : this.animType,
- steps : this.animCloseStep,
- interval: this.animSpeed,
- onfinish: function(container, data){
- container.style.display = "none";
- }
- });
- };
-
- //check databinding for how this is normally implemented
- //PROCINSTR
- this.doUpdate = function(xmlNode, container){
- var rule = this.getNodeFromRule("insert", xmlNode, null, true);
- var xmlContext = rule
- ? xmlNode.selectSingleNode(rule.getAttribute("select") || ".")
- : null;
-
- if (rule && xmlContext) {
- this.setLoadStatus(xmlNode, "loading");
-
- if (rule.getAttribute("get")) {
- this.getModel().insertFrom(rule.getAttribute("get"), xmlContext, {
- insertPoint : xmlContext,
- jmlNode : this
- });
- }
- else {
- var data = this.applyRuleSetOnNode("Insert", xmlNode);
- if (data)
- this.insert(data, xmlContext);
- }
- }
- else
- if (!this.prerender) {
- this.setLoadStatus(xmlNode, "loading");
- var result = this.$addNodes(xmlNode, container, true); //checkChildren ???
- xmlUpdateHandler.call(this, "insert", xmlNode, result);
- }
- };
-
- /* ***********************
- Skin
- ************************/
-
- var treeState = {};
- treeState[0] = "";
- treeState[HAS_CHILD] = "min";
- treeState[HAS_CHILD | IS_CLOSED] = "plus";
- treeState[IS_LAST] = "last";
- treeState[IS_LAST | HAS_CHILD] = "minlast";
- treeState[IS_LAST | HAS_CHILD | IS_CLOSED] = "pluslast";
- treeState[IS_ROOT] = "root";
-
- this.fixItem = function(xmlNode, htmlNode, isDeleting, oneLeft, noChildren){
- if (!htmlNode) return;
-
- if (isDeleting) {
- //if isLast fix previousSibling
- var prevSib;
- if (prevSib = this.getNextTraverse(xmlNode, true))
- this.fixItem(prevSib, this.getNodeFromCache(
- prevSib.getAttribute(jpf.xmldb.xmlIdTag) + "|"
- + this.uniqueId), null, true);
-
- //if no sibling fix parent
- if (!this.emptyMessage
- && xmlNode.parentNode.selectNodes(this.traverse).length == 1)
- this.fixItem(xmlNode.parentNode, this.getNodeFromCache(
- xmlNode.parentNode.getAttribute(jpf.xmldb.xmlIdTag)
- + "|" + this.uniqueId), null, false, true);
- }
- else {
- var hasChildren, container = this.$getLayoutNode("item", "container", htmlNode);
-
- if (noChildren)
- hasChildren = false;
- else
- if (xmlNode.selectNodes(this.traverse).length > 0)
- hasChildren = true;
- else
- if (this.bindingRules["insert"] && this.getNodeFromRule("insert", xmlNode))
- hasChildren = true;
- else
- hasChildren = false;
-
- var isClosed = hasChildren && container.style.display != "block";
- var isLast = this.getNextTraverse(xmlNode, null, oneLeft ? 2 : 1)
- ? false
- : true;
-
- var state = (hasChildren ? HAS_CHILD : 0) | (isClosed ? IS_CLOSED : 0)
- | (isLast ? IS_LAST : 0);
- this.$setStyleClass(this.$getLayoutNode("item", "openclose",
- htmlNode), treeState[state], ["min", "plus", "last", "minlast",
- "pluslast"]);
- this.$setStyleClass(this.$getLayoutNode("item", "container",
- htmlNode), treeState[state], ["min", "plus", "last", "minlast",
- "pluslast"]);
-
- if (!hasChildren)
- container.style.display = "none";
-
- if (state & HAS_CHILD) {
- //this.$getLayoutNode("item", "openclose", htmlNode).onmousedown = new Function('e', 'if(!e) e = event; if(e.button == 2) return;var o = jpf.lookup(' + this.uniqueId + ');o.slideToggle(this);if(o.onmousedown) o.onmousedown(e, this);jpf.cancelBubble(e, o);');
- //this.$getLayoutNode("item", "icon", htmlNode)[this.opencloseaction || "ondblclick"] = new Function('var o = jpf.lookup(' + this.uniqueId + '); o.slideToggle(this);o.choose();');
- //this.$getLayoutNode("item", "select", htmlNode)[this.opencloseaction || "ondblclick"] = new Function('e', 'var o = jpf.lookup(' + this.uniqueId + '); o.slideToggle(this, true);o.choose();(e||event).cancelBubble=true;');
- }
- /*else{
- //Experimental
- this.$getLayoutNode("item", "openclose", htmlNode).onmousedown = null;
- this.$getLayoutNode("item", "icon", htmlNode)[this.opencloseaction || "ondblclick"] = null;
- this.$getLayoutNode("item", "select", htmlNode)[this.opencloseaction || "ondblclick"] = null;
- }*/
- }
- };
-
- /**
- * @todo Make it xmlNode locked
- * @todo Use escape(27) key to cancel change (see rename)
- */
- function addAttribute(pNode, name, value, htmlNode){
- _self.$getNewContext("attribute");
- var elName = _self.$getLayoutNode("attribute", "name");
- var elValue = _self.$getLayoutNode("attribute", "value");
- jpf.xmldb.setNodeValue(elName, name);
- jpf.xmldb.setNodeValue(elValue, (value.length > 50 ? "..." : value));
- if (value.length > 50)
- elValue.setAttribute("title", value);
-
- elName.setAttribute("onmousedown", "this.contentEditable=true;\
- jpf.selectTextHtml(this);\
- this.className='textedit';\
- event.cancelBubble=true;");
- elName.setAttribute("onmouseup", "jpf.selectTextHtml(this);\
- event.cancelBubble=true;\
- return false;");
- elName.setAttribute("onkeydown", "if (event.keyCode==13) {\
- this.blur();\
- return false;\
- };\
- event.cancelBubble=true;");
- elName.setAttribute("onselectstart", "event.cancelBubble = true;");
- elName.setAttribute("ondblclick", "event.cancelBubble = true;");
- elName.setAttribute("onblur", "var o = jpf.lookup(" + _self.uniqueId + ");\
- var xmlNode = o.selected;\
- o.renameAttribute(xmlNode, '" + name + "', this.innerHTML);\
- this.contentEditable=false;this.className=''");
-
- elValue.setAttribute("onmousedown", "this.contentEditable=true;\
- jpf.selectTextHtml(this);\
- this.className='textedit';\
- event.cancelBubble=true;");
- elValue.setAttribute("onmouseup", "jpf.selectTextHtml(this);\
- event.cancelBubble=true;\
- return false;");
- elValue.setAttribute("onkeydown", "if (event.keyCode==13) {\
- this.blur();\
- return false;\
- };\
- event.cancelBubble=true;");
- elValue.setAttribute("onselectstart", "event.cancelBubble = true;");
- elValue.setAttribute("ondblclick", "event.cancelBubble = true;");
- elValue.setAttribute("onblur", "var o = jpf.lookup(" + _self.uniqueId + ");\
- var xmlNode = o.selected;\
- o.setAttributeValue(xmlNode, '" + name + "', this.innerHTML);\
- this.contentEditable=false;this.className=''");
-
- if (pNode.style) {
- htmlNode = jpf.xmldb.htmlImport(
- _self.$getLayoutNode("attribute"),
- pNode,
- _self.$getLayoutNode("item", "begintag", htmlNode).nextSibling);
-
- animHighlight(htmlNode);
- animHighlight(_self.$getLayoutNode("attribute", "name", htmlNode));
- animHighlight(_self.$getLayoutNode("attribute", "value", htmlNode));
- }
- else
- pNode.appendChild(_self.$getLayoutNode("attribute"));
- }
-
- function addTextnode(pNode, value){
- _self.$getNewContext("textnode");
- var elTextNode = _self.$getLayoutNode("textnode", "text");
- var elTag = _self.$getLayoutNode("textnode", "tag");
- jpf.xmldb.setNodeValue(elTextNode, (value.length > 50 ? "..." : value));
- if (value.length > 50)
- elTextNode.setAttribute("title", value);
-
- elTextNode.setAttribute("onmousedown", "this.contentEditable=true;\
- jpf.selectTextHtml(this);\
- this.className='textedit'");
- elTextNode.setAttribute("onmouseup", "jpf.selectTextHtml(this);\
- event.cancelBubble=true;\
- return false;");
- elTextNode.setAttribute("onkeydown", "if (event.keyCode==13) {\
- this.blur();\
- return false;\
- };\
- event.cancelBubble=true;");
- elTextNode.setAttribute("onselectstart", "event.cancelBubble = true;");
- elTextNode.setAttribute("ondblclick", "event.cancelBubble = true;");
- elTextNode.setAttribute("onblur", "var o = jpf.lookup(" + _self.uniqueId + ");\
- var xmlNode = o.selected;\
- o.setTextNode(xmlNode, this.innerHTML);\
- this.contentEditable=false;this.className=''");
-
- jpf.xmldb.setNodeValue(elTag, ">");
-
- if (pNode.style) {
- var htmlNode = jpf.xmldb.htmlImport(
- _self.$getLayoutNode("textnode"), pNode, pNode.lastChild);
- animHighlight(_self.$getLayoutNode("textnode", "text", htmlNode));
- }
- else
- pNode.appendChild(_self.$getLayoutNode("textnode"));
- }
-
- //This can be optimized by NOT using getLayoutNode all the time
- this.initNode = function(xmlNode, state, Lid){
- //Setup Nodes Interaction
- this.$getNewContext("item");
-
- var hasChildren = (state & HAS_CHILD || this.emptyMessage
- && this.applyRuleSetOnNode("empty", xmlNode));
-
- //should be restructured and combined events set per element
- var elItem = this.$getLayoutNode("item");
- elItem.setAttribute("onmouseover", 'var o = jpf.lookup(' + this.uniqueId + ');\
- if (o.onmouseover) \
- o.onmouseover(event, this);');
- elItem.setAttribute("onmouseout", 'var o = jpf.lookup(' + this.uniqueId + ');\
- if(o.onmouseout) \
- o.onmouseout(event, this)');
- elItem.setAttribute("onmousedown", 'var o = jpf.lookup(' + this.uniqueId + ');\
- if (o.onmousedown) \
- o.onmousedown(event, this);');
- elItem.setAttribute(jpf.xmldb.htmlIdTag, Lid);
-
- //Set open/close skin class & interaction
- this.$setStyleClass(this.$getLayoutNode("item", "openclose"),
- treeState[state]);
- this.$setStyleClass(this.$getLayoutNode("item", "container"),
- treeState[state])
- var elOpenClose = this.$getLayoutNode("item", "openclose");
- if (hasChildren)
- elOpenClose.setAttribute(this.opencloseaction || "onmousedown",
- "var o = jpf.lookup(" + this.uniqueId + ");\
- o.slideToggle(this);\
- if (o.onmousedown) \
- o.onmousedown(event, this);\
- jpf.cancelBubble(event,o);");
-
- //Select interaction
- var elSelect = this.$getLayoutNode("item", "select");
- if (hasChildren) {
- var strFunc2 = "var o = jpf.lookup(" + this.uniqueId + ");\
- o.slideToggle(this, true);";
- //if(this.opencloseaction != "onmousedown") elSelect.setAttribute(this.opencloseaction || "ondblclick", strFunc2);
- }
- //if(event.button != 1) return;
- //jpf.xmldb.isChildOf(o.$selected, this) && o.selected [REMOVED THIS LINE... dunno what the repurcusions are exactly]
- elSelect.setAttribute("onmousedown", "var o = jpf.lookup(" + this.uniqueId + ");\
- jpf.cancelBubble(event, o);\
- if (o.hasFocus()) \
- o.select(this);\
- if (o.onmousedown) \
- o.onmousedown(event, this);"
- + (strFunc2 && this.opencloseaction == "onmousedown" ? strFunc2 : ""));
- //if(!elSelect.getAttribute("ondblclick")) elSelect.setAttribute("ondblclick", 'var o = jpf.lookup(' + this.uniqueId + ');o.choose();');
-
- //elItem.setAttribute("contextmenu", 'alert(1);var o = jpf.lookup(' + this.uniqueId + ');o.dispatchEvent("contextMenu", o.selected);');
-
- var elBegin = this.$getLayoutNode("item", "begintag");
- jpf.xmldb.setNodeValue(elBegin, "<" + xmlNode.tagName);
-
- //attributes
- var elAttributes = this.$getLayoutNode("item", "attributes");
- var len = xmlNode.attributes.length;
- if (typeof len == "function")
- len = xmlNode.attributes.length();
- for (var i = 0; i < len; i++) {
- var attr = xmlNode.attributes.item(i);
- if (attr.nodeName.match(/j_id|j_listen|j_doc|j_loaded/))
- continue;
-
- addAttribute(elAttributes, attr.nodeName,
- attr.nodeValue);
- }
-
- var elBeginTail = this.$getLayoutNode("item", "begintail");
- var elEnd = this.$getLayoutNode("item", "endtag");
- if (!(state&HAS_CHILD)) {
- elEnd.setAttribute("style", "display:none");
-
- if (xmlNode.childNodes.length) {
- addTextnode(elAttributes, xmlNode.childNodes[0].nodeValue);
- jpf.xmldb.setNodeValue(elBeginTail, "</" + xmlNode.tagName + ">");
- }
- else
- jpf.xmldb.setNodeValue(elBeginTail, " />");
- }
- else {
- jpf.xmldb.setNodeValue(elEnd, "</" + xmlNode.tagName + ">");
- jpf.xmldb.setNodeValue(elBeginTail, ">");
- }
- elBeginTail.parentNode.appendChild(elBeginTail);
-
- elEnd.setAttribute("onmousedown", 'var o = jpf.lookup(' + this.uniqueId + ');jpf.cancelBubble(event, o);');
-
- var cssClass = this.applyRuleSetOnNode("css", xmlNode);
- if (cssClass) {
- this.$setStyleClass(this.$getLayoutNode("item", null,
- this.$getLayoutNode("item")), cssClass);
- if (cssClass)
- this.dynCssClasses.push(cssClass);
- }
-
- return this.$getLayoutNode("item");
- };
-
- this.$deInitNode = function(xmlNode, htmlNode){
- //Lookup container
- var containerNode = this.$getLayoutNode("item", "container", htmlNode);
- var pContainer = htmlNode.parentNode;
-
- //Remove htmlNodes from tree
- containerNode.parentNode.removeChild(containerNode);
- pContainer.removeChild(htmlNode);
-
- //Fix Images (+, - and lines)
- if (xmlNode.parentNode != this.xmlRoot)
- this.fixItem(xmlNode, htmlNode, true);
-
- if (this.emptyMessage && !pContainer.childNodes.length)
- this.setEmpty(pContainer);
-
- //Fix look (tree thing)
- this.fixItem(xmlNode, htmlNode, true);
-
- if (xmlNode == this.selected)
- this.clearSelection();
-
- //this.fixItem(xmlNode.parentNode, jpf.xmldb.findHTMLNode(xmlNode.parentNode, this));
- /*throw new Error();
- if(xmlNode.previousSibling) //should use traverse here
- this.fixItem(xmlNode.previousSibling, jpf.xmldb.findHTMLNode(xmlNode.previousSibling, this));*/
- };
-
- function animHighlight(oHtml){
- if (!oHtml.offsetHeight) return;
-
- jpf.setStyleClass(oHtml, "highlight");
- setTimeout(function(){
- jpf.tween.css(oHtml, "highlight", {
- anim : 0,
- steps : 20,
- interval: 30}, true);
- }, 400);
- }
-
- this.$updateNode = function(xmlNode, htmlNode){
- //Attributes
- var len, i, aLookup = {};
- var elAttributes = this.$getLayoutNode("item", "attributes", htmlNode);
- var elEnd = this.$getLayoutNode("item", "endtag", htmlNode);
- var elBeginTail = this.$getLayoutNode("item", "begintail", htmlNode);
-
- if (typeof len == "function")
- len = xmlNode.attributes.length;
- for (var i = 0; i < len; i++) {
- var attr = xmlNode.attributes.item(i);
- if (attr.nodeName.match(/j_id|j_listen|j_doc|j_loaded/))
- continue;
- aLookup[attr.nodeName] = attr.nodeValue;
- }
-
- var doneFirstChild = false;
- var nodes = [], cnodes = elAttributes.childNodes;
- for (i = 0; i < cnodes.length; i++)
- nodes.push(cnodes[i]);
-
- for (i = 0; i < nodes.length; i++) {
- if (nodes[i].nodeType != 1)
- continue;
-
- if (nodes[i].className.indexOf("textnode") > -1) {
- if (xmlNode.childNodes.length == 1
- && xmlNode.childNodes[0].nodeType == 3) {
- var elText = this.$getLayoutNode("textnode", "text", nodes[i]);
- if (xmlNode.firstChild.nodeValue != elText.innerHTML) {
- elText.innerHTML = xmlNode.firstChild.nodeValue;
- //Animate change here
- animHighlight(elText);
- }
- }
- else {
- nodes[i].parentNode.removeChild(nodes[i]);//jpf.removeChild here??
- jpf.xmldb.setNodeValue(elBeginTail, " />");
- }
-
- doneFirstChild = true;
- }
-
- if (nodes[i].className.indexOf("attribute") == -1)
- continue;
-
- var elName = this.$getLayoutNode("attribute", "name", nodes[i]);
- var elValue = this.$getLayoutNode("attribute", "value", nodes[i]);
-
- //Remove attribute if it no longer exists
- var name = elName.innerHTML;
- if (!aLookup[name])
- nodes[i].parentNode.removeChild(nodes[i]);//jpf.removeChild here??
- //Change it
- else
- if(aLookup[name] != elValue.innerHTML) {
- elValue.innerHTML = aLookup[name];
- animHighlight(elValue);
- //Animate change here...
- delete aLookup[name];
- }
- else
- if(aLookup[name])
- delete aLookup[name];
- }
-
- //Add the remaining attributes
- for (var attr in aLookup) {
- addAttribute(elAttributes, attr, aLookup[attr], htmlNode);
- }
-
- //Add textnode if its not there yet
- if (!doneFirstChild && xmlNode.childNodes.length == 1
- && xmlNode.childNodes[0].nodeType == 3) {
- addTextnode(elAttributes, xmlNode.childNodes[0].nodeValue);
- jpf.xmldb.setNodeValue(elBeginTail, "</" + xmlNode.tagName + ">");
- }
-
- var cssClass = this.applyRuleSetOnNode("css", xmlNode);
- if (cssClass || this.dynCssClasses.length) {
- this.$setStyleClass(htmlNode, cssClass, this.dynCssClasses);
- if (cssClass && !this.dynCssClasses.contains(cssClass))
- this.dynCssClasses.push(cssClass);
- }
- };
-
- this.clearEmpty = function(container){
- container.innerHTML = "";
- };
-
- this.setEmpty = function(container){
- this.$getNewContext("empty");
- var oItem = this.$getLayoutNode("empty");
- this.$getLayoutNode("empty", "caption").nodeValue = this.emptyMessage;
- jpf.xmldb.htmlImport(oItem, container);
-
- if (!this.startClosed) {
- if (container.style) {
- //container.style.display = "block";
- //container.style.height = "auto";
- }
- //else container.setAttribute("style", "display:block;height:auto;");
- }
- };
-
- this.$setLoading = function(xmlNode, container){
- this.$getNewContext("Loading");
- this.setLoadStatus(xmlNode, "potential");
- jpf.xmldb.htmlImport(this.$getLayoutNode("loading"), container);
- };
-
- this.$removeLoading = function(htmlNode){
- if (!htmlNode) return;
- this.$getLayoutNode("item", "container", htmlNode).innerHTML = "";
- };
-
- function xmlUpdateHandler(e){
- /*
- Display the animation if the item added is
- * Not in the cache
- - Being insterted using xmlUpdate
- - there is at least 1 child inserted
- */
-
- if (e.action == "move-away")
- this.fixItem(e.xmlNode, jpf.xmldb.findHTMLNode(e.xmlNode, this), true);
-
- if (e.action != "insert") return;
-
- var htmlNode = this.getNodeFromCache(e.xmlNode.getAttribute(jpf.xmldb.xmlIdTag)+"|"+this.uniqueId);
- if (!htmlNode) return;
- if (this.hasLoadStatus(e.xmlNode, "loading") && e.result.length > 0) {
- var container = this.$getLayoutNode("item", "container", htmlNode);
- this.slideOpen(container, e.xmlNode);
- }
- else
- this.fixItem(e.xmlNode, htmlNode);
-
- //Can this be removed?? (because it was added in the insert function)
- if (this.hasLoadStatus(e.xmlNode, "loading"))
- this.setLoadStatus(e.xmlNode, "loaded");
- }
-
- this.addEventListener("xmlupdate", xmlUpdateHandler);
-
- /* ***********************
- Keyboard Support
- ************************/
-
- this.addEventListener("keydown", function(e){
- var key = e.keyCode;
- var ctrlKey = e.ctrlKey;
- var shiftKey = e.shiftKey;
- var selHtml = this.$indicator || this.$selected;
-
- if (!selHtml || this.renaming)
- return;
-
- var selXml = this.indicator || this.selected;
- var oExt = this.oExt;
-
- switch (key) {
- case 13:
- if (this.$tempsel)
- this.selectTemp();
-
- if (this.ctrlselect == "enter")
- this.select(this.indicator, true);
-
- this.choose(selHtml);
- break;
- case 32:
- //if (ctrlKey)
- this.select(this.indicator, true);
- break;
- case 46:
- if (this.$tempsel)
- this.selectTemp();
-
- //DELETE
- //this.remove();
- this.remove(this.mode ? this.indicator : null); //this.mode != "check"
- break;
- case 109:
- case 37:
- //LEFT
- if (this.$tempsel)
- this.selectTemp();
-
- if (this.indicator.selectSingleNode(this.traverse))
- this.slideToggle(this.$indicator || this.$selected, 2)
- break;
- case 107:
- case 39:
- //RIGHT
- if (this.$tempsel)
- this.selectTemp();
-
- if (this.indicator.selectSingleNode(this.traverse))
- this.slideToggle(this.$indicator || this.$selected, 1)
- break;
- case 187:
- //+
- if (shiftKey)
- arguments.callee(39);
- break;
- case 189:
- //-
- if (!shiftKey)
- arguments.callee(37);
- break;
- case 38:
- //UP
- if (!selXml && !this.$tempsel)
- return;
-
- var node = this.$tempsel
- ? jpf.xmldb.getNode(this.$tempsel)
- : selXml;
-
- var sNode = this.getNextTraverse(node, true);
- if (sNode) {
- var nodes = this.getTraverseNodes(sNode);
-
- do {
- var container = this.$getLayoutNode("item", "container",
- this.getNodeFromCache(jpf.xmldb.getID(sNode, this)));
- if (container && jpf.getStyle(container, "display") == "block"
- && nodes.length) {
- sNode = nodes[nodes.length-1];
- }
- else
- break;
- }
- while (sNode && (nodes = this.getTraverseNodes(sNode)).length);
- }
- else if (this.getTraverseParent(node) == this.xmlRoot) {
- this.dispatchEvent("selecttop");
- return;
- }
- else
- sNode = this.getTraverseParent(node);
-
- if (sNode && sNode.nodeType == 1)
- this.setTempSelected(sNode, ctrlKey, shiftKey);
-
- if (this.$tempsel && this.$tempsel.offsetTop < oExt.scrollTop)
- oExt.scrollTop = this.$tempsel.offsetTop;
-
- return false;
-
- break;
- case 40:
- //DOWN
- if (!selXml && !this.$tempsel)
- return;
-
- var node = this.$tempsel
- ? jpf.xmldb.getNode(this.$tempsel)
- : selXml;
-
- var sNode = this.getFirstTraverseNode(node);
- if (sNode) {
- var container = this.$getLayoutNode("item", "container",
- this.getNodeFromCache(jpf.xmldb.getID(node, this)));
- if (container && jpf.getStyle(container, "display") != "block")
- sNode = null;
- }
-
- while (!sNode) {
- var pNode = this.getTraverseParent(node);
- if (!pNode) break;
-
- var i = 0;
- var nodes = this.getTraverseNodes(pNode);
- while (nodes[i] && nodes[i] != node)
- i++;
- sNode = nodes[i+1];
- node = pNode;
- }
-
- if (sNode && sNode.nodeType == 1)
- this.setTempSelected(sNode, ctrlKey, shiftKey);
-
- if (this.$tempsel && this.$tempsel.offsetTop + this.$tempsel.offsetHeight
- > oExt.scrollTop + oExt.offsetHeight)
- oExt.scrollTop = this.$tempsel.offsetTop
- - oExt.offsetHeight + this.$tempsel.offsetHeight + 10;
-
- return false;
- break;
- case 33: //@todo
- //PGUP
- break;
- case 34: //@todo
- //PGDN
- break;
- case 36: //@todo
- //HOME
- break;
- case 35: //@todo
- //END
- break;
- }
- }, true);
-
- /* ***********************
- DATABINDING
- ************************/
-
- var nodes = [];
-
- this.$add = function(xmlNode, Lid, xmlParentNode, htmlParentNode, beforeNode, isLast){
- //Why is this function called 3 times when adding one node? (hack/should)
- var loadChildren = this.bindingRules["insert"]
- ? this.getNodeFromRule("insert", xmlNode)
- : false;
- var hasChildren = (loadChildren
- || xmlNode.selectSingleNode(this.traverse)) ? true : false;
-
- var startClosed = this.startClosed;// || this.applyRuleSetOnNode("collapse", xmlNode, ".") !== false;
- var state = (hasChildren ? HAS_CHILD : 0)
- | (startClosed && hasChildren || loadChildren ? IS_CLOSED : 0)
- | (isLast ? IS_LAST : 0);
-
- var htmlNode = this.initNode(xmlNode, state, Lid);
- var container = this.$getLayoutNode("item", "container");
- if (!startClosed && !this.noCollapse)
- container.setAttribute("style", "overflow:visible;height:auto;display:block;");
-
- //TEMP on for dynamic subloading
- if (!hasChildren || loadChildren)
- container.setAttribute("style", "display:none;");
-
- //Dynamic SubLoading (Insertion) of SubTree
- if (loadChildren && !this.hasLoadStatus(xmlNode))
- this.$setLoading(xmlNode, container);
- else if(!this.getTraverseNodes(xmlNode).length
- && this.applyRuleSetOnNode("empty", xmlNode))
- this.setEmpty(container);
-
- if (!htmlParentNode && (xmlParentNode == this.xmlRoot
- || xmlNode == this.xmlRoot)) {
- nodes.push(htmlNode);
- if (!jpf.xmldb.isChildOf(htmlNode, container, true))
- nodes.push(container);
-
- this.$setStyleClass(htmlNode, "root");
- this.$setStyleClass(container, "root");
-
- //if(xmlNode == xmlParentNode) return container;
- }
- else {
- if (!htmlParentNode) {
- htmlParentNode = jpf.xmldb.findHTMLNode(xmlNode.parentNode, this);
- htmlParentNode = htmlParentNode
- ? this.$getLayoutNode("item", "container", htmlParentNode)
- : this.oInt;
- }
-
- if (htmlParentNode == this.oInt) {
- this.$setStyleClass(htmlNode, "root");
- this.$setStyleClass(container, "root");
-
- if (this.renderRoot) {
- var realParent = jpf.xmldb.findHTMLNode(this.xmlRoot, this);
- htmlParentNode = this.$getLayoutNode("item", "container", realParent);
- }
- }
-
- if (!beforeNode && this.getNextTraverse(xmlNode))
- beforeNode = jpf.xmldb.findHTMLNode(this.getNextTraverse(xmlNode), this);
- if (beforeNode && beforeNode.parentNode != htmlParentNode)
- beforeNode = null;
-
- if (htmlParentNode.style && this.getTraverseNodes(xmlNode.parentNode).length == 1)
- this.clearEmpty(htmlParentNode);
-
- //alert("|" + htmlNode.nodeType + "-" + htmlParentNode.nodeType + "-" + beforeNode + ":" + container.nodeType);
- //Insert Node into Tree
- if (htmlParentNode.style) {
- var q = jpf.xmldb.htmlImport(htmlNode, htmlParentNode, beforeNode);
- animHighlight(this.$getLayoutNode("item", "select", q));
-
- if (!jpf.xmldb.isChildOf(htmlNode, container, true))
- var container = jpf.xmldb.htmlImport(container, htmlParentNode, beforeNode);
- }
- else {
- htmlParentNode.insertBefore(htmlNode, beforeNode);
- if (!jpf.xmldb.isChildOf(htmlParentNode, container, true))
- htmlParentNode.insertBefore(container, beforeNode);
- }
-
- //Fix parent if child is added to drawn parentNode
- if (htmlParentNode.style) {
- if(!startClosed && this.openOnAdd
- && htmlParentNode != this.oInt
- && htmlParentNode.style.display != "block")
- this.slideOpen(htmlParentNode, xmlParentNode);
-
- //this.fixItem(xmlNode, htmlNode); this one shouldn't be called, because it should be set right at init
- this.fixItem(xmlParentNode, jpf.xmldb.findHTMLNode(xmlParentNode, this));
- if (this.getNextTraverse(xmlNode, true)) { //should use traverse here
- this.fixItem(this.getNextTraverse(xmlNode, true),
- jpf.xmldb.findHTMLNode(this.getNextTraverse(xmlNode, true), this));
- }
- }
- }
-
- if (this.prerender)
- this.$addNodes(xmlNode, container, true); //checkChildren (optimization) ???
- else
- this.setLoadStatus(xmlNode, "potential");
-
- return container;
- };
-
- this.$fill = function(){
- var container;
-
- //Please please consider moving this to jpf.databinding and make it generic.. this is a mess
- /*if(this.renderRoot){
- var htmlNode = jpf.xmldb.findHTMLNode(this.xmlRoot, this);
- if(!htmlNode || htmlNode.parentNode != this.oInt){
- var nodes = nodes;
- nodes = [];
-
- var Lid = jpf.xmldb.nodeConnect(this.documentId, this.xmlRoot, null, this);
- var p = this.$add(this.xmlRoot, Lid, this.xmlRoot, null, null, true);
- for(var i=0;i<nodes.length;i++) p.appendChild(nodes[i]);
- }
- else{
- container = this.$getLayoutNode("item", "container", htmlNode);
- }
- }*/
-
- jpf.xmldb.htmlImport(nodes, container || this.oInt);
- nodes.length = 0;
- };
-
- this.$getParentNode = function(htmlNode){
- return htmlNode
- ? this.$getLayoutNode("item", "container", htmlNode)
- : this.oInt;
- };
-
- /* ***********************
- SELECT
- ************************/
-
- this.$calcSelectRange = function(xmlStartNode, xmlEndNode){
- //should be implemented :)
- return [xmlStartNode, xmlEndNode];
- };
-
- this.$findContainer = function(htmlNode){
- return this.$getLayoutNode("item", "container", htmlNode);
- };
-
- this.multiselect = false; // Initially Disable MultiSelect
-
- this.$selectDefault = function(xmlNode){
- if(this.select(this.getFirstTraverseNode(xmlNode))) return true;
- else{
- var nodes = this.getTraverseNodes(xmlNode);
- for(var i=0;i<nodes.length;i++){
- if(this.$selectDefault(nodes[i])) return true;
- }
- }
- };
-
- this.$select = function(o){
- if(!o || !o.style) return;
- this.$setStyleClass(this.$getLayoutNode("item", "class", o), "selected");
- return o;
- };
-
- this.$deselect = function(o){
- if(!o) return;
- this.$setStyleClass(this.$getLayoutNode("item", "class", o), "", ["selected", "indicate"]);
- return o;
- };
-
- this.$indicate = function(o){
- if(!o) return;
- this.$setStyleClass(this.$getLayoutNode("item", "class", o), "indicate");
- return o;
- };
-
- this.$deindicate = function(o){
- if(!o) return;
- this.$setStyleClass(this.$getLayoutNode("item", "class", o), "", ["indicate"]);
- return o;
- };
-
- /* *********
- INIT
- **********/
- //render the outer framework of this object
- this.$draw = function(){
- //Build Main Skin
- this.oExt = this.$getExternal();
- this.oInt = this.$getLayoutNode("main", "container", this.oExt);
- this.opencloseaction = this.$getOption("Main", "openclose");
-
- //Need fix...
- //this.oExt.style.MozUserSelect = "none";
-
- this.oExt.onclick = function(e){
- this.host.dispatchEvent("click", {htmlEvent : e || event});
- }
- };
-
- this.$loadJml = function(x){
- this.openOnAdd = !jpf.isFalse(x.getAttribute("openonadd"));
- this.startClosed = !jpf.isFalse(this.$jml.getAttribute("startclosed")
- || this.$getOption("Main", "startclosed"));
- this.noCollapse = jpf.isTrue(this.$jml.getAttribute("nocollapse"));
- if (this.noCollapse)
- this.startClosed = false;
- this.singleopen = jpf.isTrue(this.$jml.getAttribute("singleopen"));
- this.prerender = !jpf.isFalse(this.$jml.getAttribute("prerender"));
-
- jpf.JmlParser.parseChildren(this.$jml, null, this);
- };
-
- this.$destroy = function(){
- this.oExt.onclick = null;
- jpf.removeNode(this.oDrag);
- this.oDrag = null;
- };
-}).implement(
- //jpf.Validation,
- jpf.MultiSelect,
- jpf.Cache,
- jpf.Presentation,
- jpf.DataBinding
-);
-
- - -/*FILEHEAD(/var/lib/jpf/src/elements/template.js)SIZE(-1077090856)TIME(1238933683)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * Defines a template for jml elements.
- *
- * @constructor
- * @allowchild {elements}, {anyjml}
- *
- * @define template
- * @addnode elements
- *
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.4
- */
-
-jpf.template = jpf.component(jpf.NODE_HIDDEN, function(){
- this.canHaveChildren = true;
- this.$focussable = false;
-
- var instances = [];
-
- this.render = function(pHtmlNode, forceNewInstance){
- if (!instances.length || forceNewInstance) {
- //var p = jpf.document.createDocumentFragment();
- //p.oExt = p.oInt = pHtmlNode;
- instances.push(this.childNodes = []);
- }
- else {
- var nodes = this.childNodes = instances[0];
- for (var i = 0, l = nodes.length; i < l; i++) {
- pHtmlNode.appendChild(nodes[i].oExt);
- }
-
- return nodes;
- }
-
- jpf.JmlParser.parseMoreJml(this.$jml, pHtmlNode, this, true);
-
- return this.childNodes;
- }
-
- this.detach = function(){
- var nodes = this.childNodes;
- var p = nodes[0].oExt.parentNode;
- if (!p || p.nodeType != 1)
- return;
-
- for (var i = 0, l = nodes.length; i < l; i++) {
- p.removeChild(nodes[i].oExt);
- }
- }
-
- //this.$draw = function(pHtmlNode){};
- this.$loadJml = function(x){
- if (this.autoinit) {
- jpf.JmlParser.parseChildren(this.$jml, document.body, this);
- this.detach();
-
- instances.push(this.childNodes);
- }
- };
-});
-
- - -/*FILEHEAD(/var/lib/jpf/src/elements/colorpicker.js)SIZE(-1077090856)TIME(1239018216)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * Element giving the user a visual choice of several colors presented in a
- * grid.
- *
- * @constructor
- * @define colorpicker
- * @addnode elements
- *
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.4
- *
- * @inherits jpf.Presentation
- * @inherits jpf.DataBinding
- * @inherits jpf.Validation
- * @inherits jpf.XForms
- *
- * @attribute {String} color the color that is selected in the color picker.
- *
- * @binding value Determines the way the value for the element is retrieved
- * from the bound data.
- * Example:
- * Sets the color based on data loaded into this component.
- * <code>
- * <j:colorpicker>
- * <j:bindings>
- * <j:value select="@color" />
- * </j:bindings>
- * </j:colorpicker>
- * </code>
- * Example:
- * A shorter way to write this is:
- * <code>
- * <j:colorpicker ref="@color" />
- * </code>
- */
-jpf.colorpicker = jpf.component(jpf.NODE_VISIBLE, function(){
- //Options
- this.$focussable = true; // This object can get the focus
-
- // PUBLIC METHODS
- this.setValue = function(value, type){
- //this.value = value;
- if (!type) type = "RGBHEX";
- switch (type) {
- case "HSL":
- this.fill(value[0], value[1], value[2]);
- break;
- case "RGB":
- var a = this.RGBtoHLS(value[0], value[1], value[2]);
- this.fill(a[0], a[1], a[2]);
- break;
- case "RGBHEX":
- var RGB = arguments[0].match(/(..)(..)(..)/);
- var a = this.RGBtoHLS(Math.hexToDec(RGB[0]),
- Math.hexToDec(RGB[1]), Math.hexToDec(RGB[2]));
- this.fill(a[0], a[1], a[2]);
- break;
- }
- };
-
- this.getValue = function(type){
- return this.HSLRangeToRGB(this.cH, this.cS, this.cL);
- };
-
- // PRIVATE METHODS
- this.cL = 120;
- this.cS = 239;
- this.cH = 0;
- this.cHex = "#FF0000";
- this.HSLRange = 240;
-
- this.HSLRangeToRGB = function(H, S, L){
- return this.HSLtoRGB (H / (this.HSLRange-1), S / this.HSLRange,
- Math.min(L / this.HSLRange, 1))
- };
-
- this.RGBtoHLS = function(R,G,B){
- var RGBMAX = 255;
- var HLSMAX = this.HSLRange;
- var UNDEF = (HLSMAX*2/3);
-
- /* calculate lightness */
- cMax = Math.max(Math.max(R,G), B);
- cMin = Math.min(Math.min(R,G), B);
- L = (((cMax + cMin) * HLSMAX) + RGBMAX) / (2 * RGBMAX);
-
- if (cMax == cMin) { /* r=g=b --> achromatic case */
- S = 0; /* saturation */
- H = UNDEF; /* hue */
- }
- /* chromatic case */
- else {
- /* saturation */
- if (L <= (HLSMAX/2))
- S = (((cMax - cMin) * HLSMAX) + ((cMax + cMin) / 2)) / (cMax + cMin);
- else
- S = (((cMax - cMin) * HLSMAX) + ((2 * RGBMAX - cMax - cMin) / 2))
- / (2 * RGBMAX - cMax - cMin);
-
- /* hue */
- Rdelta = (((cMax - R) * (HLSMAX / 6)) + ((cMax - cMin) / 2)) / (cMax - cMin);
- Gdelta = (((cMax - G) * (HLSMAX / 6)) + ((cMax - cMin) / 2)) / (cMax - cMin);
- Bdelta = (((cMax - B) * (HLSMAX / 6)) + ((cMax - cMin) / 2)) / (cMax - cMin);
-
- if (R == cMax)
- H = Bdelta - Gdelta;
- else if (G == cMax)
- H = (HLSMAX / 3) + Rdelta - Bdelta;
- else
- H = ((2 * HLSMAX) / 3) + Gdelta - Rdelta;
-
- if (H < 0)
- H += HLSMAX;
- if (H > HLSMAX)
- H -= HLSMAX;
- }
-
- return [H, S, L];
- };
-
- this.HueToColorValue = function(Hue){
- var V;
-
- if (Hue < 0)
- Hue = Hue + 1
- else if (Hue > 1)
- Hue = Hue - 1;
-
- if (6 * Hue < 1)
- V = M1 + (M2 - M1) * Hue * 6
- else if (2 * Hue < 1)
- V = M2
- else if (3 * Hue < 2)
- V = M1 + (M2 - M1) * (2 / 3 - Hue) * 6
- else
- V = M1;
-
- return Math.max(Math.floor(255 * V), 0);
- };
-
- this.HSLtoRGB = function(H, S, L){
- var R, G, B;
-
- if (S == 0)
- G = B = R = Math.round (255 * L);
- else{
- M2 = (L <= 0.5) ? (L * (1 + S)) : (L + S - L * S);
-
- M1 = 2 * L - M2;
- R = this.HueToColorValue(H + 1 / 3);
- G = this.HueToColorValue(H);
- B = this.HueToColorValue(H - 1 / 3);
- }
-
- return Math.decToHex(R) + "" + Math.decToHex(G) + "" + Math.decToHex(B);
- };
-
- this.fill = function(H, S, L){
- var Hex = this.HSLRangeToRGB(H,S,L);
- this.value = Hex;
-
- //RGB
- var RGB = Hex.match(/(..)(..)(..)/);
- this.tbRed.value = Math.hexToDec(RGB[1]);
- this.tbGreen.value = Math.hexToDec(RGB[2]);
- this.tbBlue.value = Math.hexToDec(RGB[3]);
-
- //HSL
- this.tbHue.value = Math.round(H);
- this.tbSatern.value = Math.round(S);
- this.tbLuminance.value = Math.round(L);
-
- //HexRGB
- this.tbHexColor.value = Hex;
-
- //Shower
- this.shower.style.backgroundColor = Hex;
-
- //Luminance
- var HSL120 = this.HSLRangeToRGB(H, S, 120);
- this.bar1.style.backgroundColor = HSL120;
- this.bgBar1.style.backgroundColor = this.HSLRangeToRGB(H, S, 240);
- this.bar2.style.backgroundColor = this.HSLRangeToRGB(H, S, 0);
- this.bgBar2.style.backgroundColor = HSL120;
- };
-
- this.movePointer = function(e){
- e = e || window.event;
- var cs = colorPicker;
-
- var ty = cs.pHolder.ty;
- if ((e.clientY - ty >= 0) && (e.clientY - ty
- <= cs.pHolder.offsetHeight - cs.pointer.offsetHeight + 22))
- cs.pointer.style.top = e.clientY - ty;
- if (e.clientY - ty < 21)
- cs.pointer.style.top = 21;
- if (e.clientY - ty
- > cs.pHolder.offsetHeight - cs.pointer.offsetHeight + 19)
- cs.pointer.style.top = cs.pHolder.offsetHeight
- - cs.pointer.offsetHeight + 19;
-
- var y = cs.pointer.offsetTop - 22;
- cs.cL = (255-y) / 2.56 * 2.4;
- cs.fill(cs.cH, cs.cS, cs.cL);
-
- e.returnValue = false;
- e.cancelBubble = true;
- };
-
- this.setLogic = function(){
- this.pHolder.host = this;
- this.pHolder.style.zIndex = 10;
- this.pHolder.onmousedown = function(){
- var colorPicker = this.host;
-
- this.ty = jpf.getAbsolutePosition(this)[1] - 20;
-
- this.host.movePointer();
- document.onmousemove = this.host.movePointer
- document.onmouseup = function(){ this.onmousemove = function(){}; };
- }
-
- this.container.host = this;
- this.container.onmousedown = function(e){
- e = e || window.event;
- var colorPicker = this.host;
-
- this.active = true;
- if (e.srcElement == this) {
- if (e.offsetX >= 0 && e.offsetX <= 256
- && e.offsetY >= 0 && e.offsetY <= 256) {
- this.host.cS = (256 - e.offsetY) / 2.56 * 2.4
- this.host.cH = e.offsetX / 2.56 * 2.39
- }
- this.host.fill(this.host.cH, this.host.cS, this.host.cL);
- this.host.shower.style.backgroundColor = this.host.currentColor;
- }
- this.host.point.style.display = "none";
-
- e.cancelBubble = true;
- }
-
- this.container.onmouseup = function(e){
- this.active = false;
- this.host.point.style.top = event.offsetY - this.host.point.offsetHeight - 2;
- this.host.point.style.left = event.offsetX - this.host.point.offsetWidth - 2;
- this.host.point.style.display = "block";
-
- this.host.change(this.host.tbHexColor.value);
- }
-
- this.container.onmousemove = function(e){
- e = e || window.event;
- if (this.active) {
- if (e.offsetX >= 0 && e.offsetX <= 256
- && e.offsetY >= 0 && e.offsetY <= 256) {
- this.host.cS = (256 - e.offsetY) / 2.56 * 2.4
- this.host.cH = e.offsetX / 2.56 * 2.39
- }
- this.host.fill(this.host.cH, this.host.cS, this.host.cL);
- this.host.shower.style.backgroundColor = this.host.currentColor;
- }
- }
-
- /*this.tbHexColor.host =
- this.tbRed.host =
- this.tbGreen.host =
- this.tbBlue.host = this;
- this.tbHexColor.onblur = function(){this.host.setValue("RGBHEX", this.value);}
- this.tbRed.onblur = function(){this.host.setValue("RGB", this.value, this.host.tbGreen.value, this.host.tbBlue.value);}
- this.tbGreen.onblur = function(){this.host.setValue("RGB", this.host.tbRed.value, this.value, this.host.tbBlue.value);}
- this.tbBlue.onblur = function(){this.host.setValue("RGB", this.host.tbRed.value, this.host.tbGreen.value, this.value);}
- */
- }
-
- // Databinding
- this.mainBind = "color";
-
- this.$draw = function(parentNode, clear){
- //Build Main Skin
- this.oExt = this.$getExternal();
-
- this.tbRed = this.$getLayoutNode("main", "red", this.oExt);
- this.tbGreen = this.$getLayoutNode("main", "green", this.oExt);
- this.tbBlue = this.$getLayoutNode("main", "blue", this.oExt);
-
- this.tbHue = this.$getLayoutNode("main", "hue", this.oExt);
- this.tbSatern = this.$getLayoutNode("main", "satern", this.oExt);
- this.tbLuminance = this.$getLayoutNode("main", "luminance", this.oExt);
-
- this.tbHexColor = this.$getLayoutNode("main", "hex", this.oExt);
- this.tbHexColor.host = this;
- this.tbHexColor.onchange = function(){
- this.host.setValue(this.value, "RGBHEX");
- }
-
- this.shower = this.$getLayoutNode("main", "shower", this.oExt);
-
- this.bar1 = this.$getLayoutNode("main", "bar1", this.oExt);
- this.bgBar1 = this.$getLayoutNode("main", "bgbar1", this.oExt);
- this.bar2 = this.$getLayoutNode("main", "bar2", this.oExt);
- this.bgBar2 = this.$getLayoutNode("main", "bgbar2", this.oExt);
-
- this.pHolder = this.$getLayoutNode("main", "pholder", this.oExt);
- this.pointer = this.$getLayoutNode("main", "pointer", this.oExt);
- this.container = this.$getLayoutNode("main", "container", this.oExt);
- this.point = this.$getLayoutNode("main", "point", this.oExt);
-
- var nodes = this.oExt.getElementsByTagName("input");
- for (var i = 0; i < nodes.length; i++) {
- nodes[i].onselectstart = function(e){
- e = e || window.event;
- e.cancelBubble = true;
- };
- }
-
- this.setLogic();
-
- this.setValue("ffffff");
- //this.fill(this.cH, this.cS, this.cL);
- }
-
- this.$loadJml = function(x){
- if (x.getAttribute("color"))
- this.setValue(x.getAttribute("color"));
- }
-
- this.$destroy = function(){
- this.container.host =
- this.tbRed.host =
- this.tbGreen.host =
- this.tbBlue.host =
- this.tbHexColor.host =
- this.pHolder.host = null;
- }
-}).implement(
- jpf.Presentation
- ,jpf.DataBinding
- ,jpf.Validation
-);
-
- - -/*FILEHEAD(/var/lib/jpf/src/elements/notifier.js)SIZE(-1077090856)TIME(1238944817)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - -/** - * Notification element, which shows popups when events occur. Similar - * to growl on the OSX platform. - * Example: - * <code> - * <j:notifier position="bottom-right" margin="10 10"> - * <j:event - * when = "{offline.onLine}" - * message = "You are currently working offline" - * icon = "icoOffline.gif" /> - * <j:event - * when = "{!offline.onLine}" - * message = "You are online" - * icon = "icoOnline.gif" /> - * <j:event - * when = "{offline.syncing}" - * message = "Your changes are being synced" - * icon = "icoSyncing.gif" /> - * <j:event - * when = "{!offline.syncing}" - * message = "Syncing done" - * icon = "icoDone.gif" /> - * </j:notifier> - * </code> - * Example: - * Notifier with 4 notifications which will be appears and stays over the 3 seconds - * begins to the top right corner and goes to the left. First notification will - * be displayed when value in textbox will be bigger than 4. In next two cases - * notification will be shown when notifier's position or arrange attribute will - * be changed. In the last case notification will be shown when date 2008-12-24 - * will be selected on calendar. - * <code> - * <j:notifier id="notiTest" position="top-right" margin="20" timeout="3" arrange="horizontal" columnsize="200"> - * <j:event when="{txtNumber.value > 4}" message="Incorrect value, please enter a number not bigger than 4." icon="evil.png"></j:event> - * <j:event when="{notiTest.position}" message="Notifier display position has been changed"></j:event> - * <j:event when="{notiTest.arrange}" message="Notifier display arrange has been changed"></j:event> - * <j:event when="{txtDrop.value == '2008-12-24'}" message="Marry christmas !" icon="Reindeer.png" ></j:event> - * </j:notifier> - * </code> - * - * @define notifier - * @attribute {String} position Vertical and horizontal element's start position, it can be changed in any time, default is 'top-right' - * Possible values: - * top-right element is placed in top-right corner of browser window - * top-left element is placed in top-left corner of browser window - * bottom-right element is placed in bottom-right corner of browser window - * bottom-left element is placed in bottom-left corner of browser window - * center-center element is placed in the middle of browser window - * right-top element is placed in top-right corner of browser window - * left-top element is placed in top-left corner of browser window - * right-bottom element is placed in bottom-right corner of browser window - * left-bottom element is placed in bottom-left corner of browser window - * center-center element is placed in the middle of browser window - * @attribute {String} margin It's a free space around popup element, default is '10 10 10 10' pixels - * @attribute {String} columnsize Specify element width and col width where element will be displayed, default is 300 pixels - * @attribute {String} arrange popup elements can be displayed in rows or columns, default is 'vertical' - * Possible values: - * vertical element will be displayed in rows - * horizontal element will be displayed in columns - * @attribute {String} timeout After the timeout has passed the popup will dissapear automatically. When the mouse hovers over the popup it doesn't dissapear, default is 2 seconds - * $attribute {String} onclick It's an action executed after user click on notifier cloud - * - * @constructor - * - * @inherits jpf.Presentation - * - * @author - * @version %I%, %G% - * - * @allowchild event - */ -jpf.notifier = jpf.component(jpf.NODE_VISIBLE, function() { - this.pHtmlNode = document.body; - this.timeout = 2000; - this.position = "top-right"; - this.columnsize = 300; - this.arrange = "vertical"; - this.margin = "10 10 10 10"; - - var lastPos = null; - var showing = 0; - var _self = this; - var sign = 1; - - - this.$supportedProperties.push("margin", "position", "timeout", - "columnsize", "arrange"); - - this.$propHandlers["position"] = function(value) { - lastPos = null; - } - - this.$propHandlers["timeout"] = function(value) { - this.timeout = parseInt(value) * 1000; - } - - function getStartPosition(x, wh, ww, nh, nw) { - var margin = jpf.getBox(document.body.style.margin || "10"); - - var ver = (x[0] == "top" - ? margin[0] - : (x[0] == "bottom" - ? wh - nh - margin[2] - : wh/2 - nh/2)); - var hor = (x[1] == "left" - ? margin[3] - : (x[1] == "right" - ? ww - nw - margin[1] - : ww/2 - nw/2)); - sign = 1; - - return lastPos = [ver, hor]; - } - - /** - * Function creates new notifie popup element - * - * @param {String} message Message content displaing in popup element, default is [No message] - * @param {String} icon Path to icon file relative to "icon-path" which is set in skin declaration - * @param {Object} ev object representation of event - * - */ - this.popup = function(message, icon, ev) { - if (!this.oExt) - return; - - this.oExt.style.width = this.columnsize + "px"; - var oNoti = this.pHtmlNode.appendChild(this.oExt.cloneNode(true)); - var ww = jpf.isIE - ? document.documentElement.offsetWidth - : window.innerWidth; - var wh = jpf.isIE - ? document.documentElement.offsetHeight - : window.innerHeight; - var removed = false; - - var oIcon = this.$getLayoutNode("notification", "icon", oNoti); - var oBody = this.$getLayoutNode("notification", "body", oNoti); - - showing++; - - if (oIcon && icon) { - if (oIcon.nodeType == 1) - oIcon.style.backgroundImage = "url(" - + this.iconPath + icon + ")"; - else - oIcon.nodeValue = this.iconPath + icon; - - this.$setStyleClass(oNoti, this.baseCSSname + "ShowIcon"); - } - - oBody.insertAdjacentHTML("beforeend", message || "[No message]"); - oNoti.style.display = "block"; - - var margin = jpf.getBox(this.margin || "0"); - var nh = oNoti.offsetHeight; - var nw = oNoti.offsetWidth; - - /* It's possible to set for example: position: top-right or right-top */ - var x = this.position.split("-"); - if(x[1] == "top" || x[1] == "bottom" || - x[0] == "left" || x[0] == "right") { - var tmp = x[1]; - x[1] = x[0]; - x[0] = tmp; - } - /* center-X and X-center are disabled */ - if((x[0] == "center" && x[1] !== "center") || - (x[0] !== "center" && x[1] == "center")) { - x = ["top", "right"]; - } - - var _reset = false; - /* start positions */ - if (!lastPos) { - lastPos = getStartPosition(x, wh, ww, nh, nw); - _reset = true; - } - - if ((!_reset && x[0] == "bottom" && sign == 1) || - (x[0] == "top" && sign == -1)) { - if (this.arrange == "vertical") { - lastPos[0] += x[1] == "center" - ? 0 - : sign*(x[0] == "top" - ? margin[0] + nh - : (x[0] == "bottom" - ? - margin[2] - nh - : 0)); - } - else { - lastPos[1] += x[0] == "center" - ? 0 - : sign*(x[1] == "left" - ? margin[3] + nw - : (x[1] == "right" - ? - margin[1] - nw - : 0)); - } - } - - /* reset to next line, first for vertical, second horizontal */ - if (lastPos[0] > wh - nh || lastPos[0] < 0) { - lastPos[1] += (x[1] == "left" - ? nw + margin[3] - : (x[1] == "right" - ? - nw - margin[3] - : 0)); - sign *= -1; - lastPos[0] += sign*(x[0] == "top" - ? margin[0] + nh - : (x[0] == "bottom" - ? - margin[2] - nh - : 0)); - } - else if (lastPos[1] > ww - nw || lastPos[1] < 0) { - lastPos[0] += (x[0] == "top" - ? nh + margin[0] - : (x[0] == "bottom" - ? - nh - margin[0] - : 0)); - sign *= -1; - lastPos[1] += x[0] == "center" - ? 0 - : sign*(x[1] == "left" - ? margin[3] + nw - : (x[1] == "right" - ? - margin[1] - nw - : 0)); - } - - /* Start from begining if entire screen is filled */ - if (lastPos) { - if ((lastPos[0] > wh -nh || lastPos[0] < 0) && - this.arrange == "horizontal") { - lastPos = getStartPosition(x, wh, ww, nh, nw); - } - if ((lastPos[1] > ww -nw || lastPos[1] < 0) && - this.arrange == "vertical") { - lastPos = getStartPosition(x, wh, ww, nh, nw); - } - } - - oNoti.style.left = lastPos[1] + "px"; - oNoti.style.top = lastPos[0] + "px"; - - if ((x[0] == "top" && sign == 1) || (x[0] == "bottom" && sign == -1)) { - if (this.arrange == "vertical") { - lastPos[0] += x[1] == "center" - ? 0 - : sign*(x[0] == "top" - ? margin[0] + nh - : (x[0] == "bottom" - ? - margin[2] - nh - : 0)); - } - else { - lastPos[1] += x[0] == "center" - ? 0 - : sign*(x[1] == "left" - ? margin[3] + nw - : (x[1] == "right" - ? - margin[1] - nw - : 0)); - } - }; - - var isMouseOver = false; - - jpf.tween.css(oNoti, "notifier_shown", { - anim : jpf.tween.NORMAL, - steps : 10, - interval : 10, - onfinish : function(container) { - setTimeout(hideWindow, _self.timeout) - } - }); - - function hideWindow() { - if (isMouseOver) - return; - - jpf.tween.css(oNoti, "notifier_hidden", { - anim : jpf.tween.NORMAL, - steps : 10, - interval: 20, - onfinish: function(container) { - _self.$setStyleClass(oNoti, "", ["notifier_hover"]); - if (isMouseOver) - return; - if (oNoti.parentNode) { - if(oNoti.parentNode.removeChild(oNoti) && !removed) { - showing--; - removed = true; - } - } - if (!showing) { - lastPos = null; - } - } - }); - } - - /* Events */ - oNoti.onmouseover = function(e) { - e = (e || event); - var tEl = e.explicitOriginalTarget || e.toElement; - if (isMouseOver) - return; - if (tEl == oNoti || jpf.xmldb.isChildOf(oNoti, tEl)) { - jpf.tween.css(oNoti, "notifier_hover", { - anim : jpf.tween.NORMAL, - steps : 10, - interval: 20, - onfinish: function(container) { - _self.$setStyleClass(oNoti, "", ["notifier_shown"]); - } - }); - isMouseOver = true; - } - }; - - oNoti.onmouseout = function(e) { - e = (e || event); - var tEl = e.explicitOriginalTarget || e.toElement; - - if (!isMouseOver) - return; - - if (jpf.xmldb.isChildOf(tEl, oNoti) || - (!jpf.xmldb.isChildOf(oNoti, tEl) && oNoti !== tEl )) { - isMouseOver = false; - hideWindow(); - } - }; - - if (ev) { - oNoti.onclick = function() { - ev.dispatchEvent("click"); - } - } - }; - - /**** Init ****/ - - this.$draw = function() { - //Build Main Skin - this.oExt = this.$getExternal("notification"); - this.oExt.style.display = "none"; - this.oExt.style.position = "absolute"; - this.oExt.style.zIndex = 100000; - }; - - this.$loadJml = function(x) { - var ev, node, nodes = x.childNodes; - - for (var l = nodes.length-1, i = 0; i < l; i++) { - node = nodes[i]; - if (node.nodeType != 1) - continue; - - if (node[jpf.TAGNAME] == "event") - ev = new jpf.event(this.pHtmlNode, "event").loadJml(node, this) - } - }; -}).implement(jpf.Presentation); - -/** - * Displays a popup element with a message with optionally an icon at the - * position specified by the position attribute. After the timeout has passed - * the popup will dissapear automatically. When the mouse hovers over the popup - * it doesn't dissapear. - * - * @event click Fires when the user clicks on the representation of this event. - */ -jpf.event = jpf.component(jpf.NODE_HIDDEN, function() { - var _self = this; - var hasInitedWhen = false; - - this.$booleanProperties["repeat"] = true; - this.$supportedProperties.push("when", "message", "icon", "repeat"); - - this.$propHandlers["when"] = function(value) { - if (hasInitedWhen && value && this.parentNode && this.parentNode.popup) { - setTimeout(function() { - _self.parentNode.popup(_self.message, _self.icon, _self); - }); - } - hasInitedWhen = true; - - if (this.repeat) - delete this.when; - }; - - this.$loadJml = function(x) { - }; -}); - - - -/*FILEHEAD(/var/lib/jpf/src/elements/actiontracker.js)SIZE(-1077090856)TIME(1238933683)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -/** - * Element keeping track of all user actions that are triggered in GUI - * elements. This element maintains a stack of actions and knows how to - * undo & redo them. It is aware of how to synchronize the changes to the - * backend data store. With offline support enabled the actiontracker can - * serialize both its undo stack and its execution stack such that these can - * be kept in between application sessions. This means that a user will be able - * to close the application and start it at a later date whilst keeping his or - * her entire undo/redo stack. Furthermore all changes done whilst being offline - * will be synchronized to the data store when the application comes online. - * - * @constructor - * - * @define actiontracker - * @addnode smartbinding, global - * @event afterchange Fires after a change to the action stack occurs - * object: - * {String} action the name of the action that was execution - * @event beforechange Fires before a change to the action stack will occur - * cancellable: Prevents the execution of the action. - * object: - * {String} action the action to be executed - * {Array} args the arguments for the action - * {XmlNode} [xmlActionNode] the rules to synchronize the changes to the server for both execution and undo. (See action rules) - * {JmlNode} [jmlNode] the GUI element that triggered the action - * {XmlNode} [selNode] the relevant data node to which the action node works on - * {Number} [timestamp] the start of the action that is now executed. - * @event actionfail Fires when an action fails to be sent to the server. - * bubles: true - * object: - * {Error} error the error object that is thrown when the event callback doesn't return false. - * {Number} state the state of the call - * Possible values: - * jpf.SUCCESS the request was successfull - * jpf.TIMEOUT the request has timed out. - * jpf.ERROR an error has occurred while making the request. - * jpf.OFFLINE the request was made while the application was offline. - * {mixed} userdata data that the caller wanted to be available in the callback of the http request. - * {XMLHttpRequest} http the object that executed the actual http request. - * {String} url the url that was requested. - * {Http} tpModule the teleport module that is making the request. - * {Number} id the id of the request. - * {String} message the error message. - * @event actionsuccess Fires when an action fails to be sent to the server. - * bubles: true - * object: - * {Number} state the state of the call - * Possible values: - * jpf.SUCCESS the request was successfull - * jpf.TIMEOUT the request has timed out. - * jpf.ERROR an error has occurred while making the request. - * jpf.OFFLINE the request was made while the application was offline. - * {mixed} userdata data that the caller wanted to be available in the callback of the http request. - * {XMLHttpRequest} http the object that executed the actual http request. - * {String} url the url that was requested. - * {Http} tpModule the teleport module that is making the request. - * {Number} id the id of the request. - * - * @author Ruben Daniels - * @version %I%, %G% - * @since 0.8 - */ -jpf.actiontracker = function(parentNode){ - jpf.makeClass(this); - - var _self = this; - var stackDone = []; - var stackUndone = []; - var execStack = []; - var lastExecStackItem; - - this.realtime = true; - this.undolength = 0; - this.redolength = 0; - - this.tagName = "actiontracker"; - if (parentNode) - this.parentNode = parentNode; - this.inherit(jpf.JmlDom); /** @inherits jpf.JmlDom */ - - /** - * @attribute {Number} !undolength the length of the undo stack. - * @attribute {Number} !redolength the length of the redo stack. - * @attribute {Boolean} realtime whether changes are immediately send to - * the datastore, or held back until purge() is called. - */ - this.$booleanProperties = {}; - this.$booleanProperties["realtime"] = true; - this.$supportedProperties = ["realtime", "undolength", "redolength", "alias"]; - this.$handlePropSet = function(prop, value, force){ - //Read only properties - switch (prop) { - case "undolength": - this.undolength = stackDone.length; - break; - case "redolength": - this.redolength = stackUndone.length; - break; - default: - this[prop] = value; - } - }; - - - this.loadJml = function(x){ - this.$jml = x; - - //Events - var value, a, i, attr = x.attributes; - for (i = 0; i < attr.length; i++) { - a = attr[i]; - if (a.nodeName.indexOf("on") == 0) { - this.addEventListener(a.nodeName, new Function(a.nodeValue)); - } - else { - value = this.$booleanProperties[a.nodeName] - ? jpf.isTrue(a.nodeValue) - : a.nodeValue; - this.setProperty(a.nodeName, value); - } - } - } - - /** - * Adds a new action handler which can be used by any actiontracker. - * @param {String} action Specifies the name of the action - * @param {Function} func Specifies the function that is executed when - * Executing or undoing the action. - */ - this.define = function(action, func){ - jpf.actiontracker.actions[action] = func; - }; - - /** - * Searches for the actiontracker that functions as a parent for this one. - * @return {ActionTracker} Returns the parent actiontracker - */ - this.getParent = function(){ - return this.parentNode && this.parentNode.getActionTracker - ? this.parentNode.getActionTracker(true) - : (jpf.window.$at != this - ? jpf.window.$at - : null); - }; - - /** - * Executes an action, which later can be undone and of which the execution - * can be synchronized to the data store. - * @param {Object} options the details of the execution. - * Properties: - * {String} action the action to be executed - * {Array} args the arguments for the action - * {XmlNode} [xmlActionNode] the rules to synchronize the changes to the server for both execution and undo. (See action rules) - * {JmlNode} [jmlNode] the GUI element that triggered the action - * {XmlNode} [selNode] the relevant data node to which the action node works on - * {Number} [timestamp] the start of the action that is now executed. - */ - this.execute = function(options){ - if (this.dispatchEvent("beforechange", options) === false) - return; - - //Execute action - var UndoObj = new jpf.UndoData(options, this); - if (options.action) - jpf.actiontracker.actions[options.action](UndoObj, false, this); - - //Add action to stack - UndoObj.id = stackDone.push(UndoObj) - 1; - - this.setProperty("undolength", stackDone.length); - - if (typeof jpf.offline != "undefined") { - var t = jpf.offline.transactions; - if (t.doStateSync) { - t.addAction(this, UndoObj, "undo"); - t.clearActions(this, "redo"); - } - } - - //Respond - this.$addToQueue(UndoObj, false); - - //Reset Redo Stack - stackUndone.length = 0; - this.setProperty("redolength", stackUndone.length); - - //return stack id of action - return UndoObj; - }; - - //deprecated?? - this.$addActionGroup = function(done, rpc){ - var UndoObj = new jpf.UndoData("group", null, [ - //@todo jpf.copyArray is deprecated and no longer exists - jpf.copyArray(done, UndoData), jpf.copyArray(rpc, UndoData) - ]); - stackDone.push(UndoObj); - this.setProperty("undolength", stackDone.length); - - this.dispatchEvent("afterchange", {action: "group", done: done}); - }; - - /** - * Synchronizes all held back changes to the data store. - * @todo I don't really know if this stacking into the parent is - * still used, for instance for jpf.Transactions. please think - * about it. - */ - this.purge = function(nogrouping, forcegrouping){//@todo, maybe add noReset argument - //var parent = this.getParent(); - - //@todo Check if this still works together with transactions - if (true) {//nogrouping && parent - if (execStack.length) { - execStack[0].undoObj.saveChange(execStack[0].undo, this); - lastExecStackItem = execStack[execStack.length - 1]; - } - } - else if (parent) { - /* - Copy Stacked Actions as a single - grouped action to parent ActionTracker - */ - //parent.$addActionGroup(stackDone, stackRPC); - - //Reset Stacks - this.reset(); - } - }; - - /** - * Empties the action stack. After this method is run running undo - * or redo will not do anything. - */ - this.reset = function(){ - stackDone.length = stackUndone.length = 0; - - this.setProperty("undolength", 0); - this.setProperty("redolength", 0); - - this.dispatchEvent("afterchange", {action: "reset"}); - }; - - /** - * Revert the most recent action on the action stack - */ - this.undo = function(id, single, rollback){ - change.call(this, id, single, true, rollback); - }; - - /** - * Re-executes the last undone action - */ - this.redo = function(id, single, rollback){ - change.call(this, id, single, false, rollback); - }; - - function change(id, single, undo, rollback){ - var undoStack = undo ? stackDone : stackUndone; //local vars switch - var redoStack = undo ? stackUndone : stackDone; //local vars switch - - if (!undoStack.length) return; - - if (single) { - var UndoObj = undoStack[id]; - if (!UndoObj) return; - - if (id != undoStack.length - 1) { //@todo callstack got corrupted? - throw new Error("callstack got corrupted"); - } - undoStack.length--; - redoStack.push(UndoObj); //@todo check: moved from outside if(single) - - if (typeof jpf.offline != "undefined" && jpf.offline.transactions.doStateSync) { - jpf.offline.transactions.removeAction(this, true, undo ? "undo" : "redo"); - jpf.offline.transactions.addAction(this, UndoObj, undo ? "redo" : "undo"); - } - - //Undo Client Side Action - if (UndoObj.action) - jpf.actiontracker.actions[UndoObj.action](UndoObj, undo, this); - - if (!rollback) - this.$addToQueue(UndoObj, undo); - - //Set Changed Value - this.setProperty("undolength", stackDone.length); - this.setProperty("redolength", stackUndone.length); - return UndoObj; - } - - jpf.console.info("Executing " + (undo ? "undo" : "redo")); - - //Undo the last X places - where X = id; - if (id == -1) - id = undoStack.length; - - if (!id) - id = 1; - - var i = 0; - while (i < id && undoStack.length > 0) { - if (!undoStack[undoStack.length - 1]) { - undoStack.length--; - - jpf.console.error("The actiontracker is in an invalid \ - state. The entire undo and redo stack will \ - be cleared to prevent further corruption\ - This is a serious error, please contact \ - a specialist."); - - stackDone = []; - stackUndone = []; - - if (typeof jpf.offline != "undefined") { - var t = jpf.offline.transactions; - if (t.doStateSync) - t.clear("undo|redo"); - } - - return false; - } - else { - change.call(this, undoStack.length - 1, true, undo); - i++; - } - } - - this.dispatchEvent("afterchange", { - action : undo ? "undo" : "redo", - rollback : rollback - }) - } - - this.$receive = function(data, state, extra, UndoObj, callback){ - if (state == jpf.TIMEOUT - && extra.tpModule.retryTimeout(extra, state, this) === true) - return true; - - if (state != jpf.SUCCESS) { - //Tell anyone that wants to hear about our failure :( - if (this.dispatchEvent("actionfail", jpf.extend(extra, { - state : state, - message : "Could not sent Action RPC request for control " - + this.name - + "[" + this.tagName + "] \n\n" - + extra.message, - bubbles : true - })) === false) { - - jpf.console.warn("You have cancelled the automatic undo \ - process! Please be aware that if you don't retry this call \ - the queue will fill up and none of the other actions will \ - be sent through."); - - return true; //don't delete the call from the queue - } - - /* - Undo the failed action. We're only undoing one item of the stack - if the developer has told us using the @ignore-fail attribute - that it's ok, the data will be safe if we undo only this one. - - @todo: Shouldn't the stackUndone be cleared after this... or - is it intuitive enough for the user that redo will - let the user retry the action?? - */ - if (typeof jpf.offline != "undefined" && !jpf.offline.reloading) - this.undo(UndoObj.id, extra.userdata, true); - - if (callback) - callback(!extra.userdata); - - if (!extra.userdata) { - /* - Clearing the execStack, none of the changes will be send to - the server. This seems the best way right now and is related - to the todo item above. - - @todo: Think about adding ignore-fail to settings and - actiontracker. - */ - execStack = []; - - throw new Error(jpf.formatErrorString(0, this, - "Executing action", - "Error sending action to the server:\n" - + (extra.url ? "Url:" + extra.url + "\n\n" : "") - + extra.message)); - - return; - } - } - else { - //Tell anyone that wants to hear about our success - this.dispatchEvent("actionsuccess", jpf.extend(extra, { - state : state, - bubbles : true - }, extra)); - - //Sent out the RSB message, letting friends know of our change - UndoObj.processRsbQueue(); - - if (callback) - callback(); - } - - this.$queueNext(UndoObj, callback); - }; - - this.$addToQueue = function(UndoObj, undo, isGroup){ - /* - Remove item from the execution stack if it's not yet executed - to keep the stack clean - */ - if (execStack.length && !UndoObj.state - && execStack[execStack.length - 1].undoObj == UndoObj) { - execStack.length--; - - if (typeof jpf.offline != "undefined" && jpf.offline.transactions.enabled) //We want to maintain the stack for sync - jpf.offline.transactions.removeAction(this, true, "queue"); - - UndoObj.clearRsbQueue(); - - return; - } - - // Add the item to the queue - if (isGroup) { //@todo currently no offline support for grouped actions - var qItem = execStack.shift(); - for (var i = 0; i < UndoObj.length; i++) { - execStack.unshift({ - undoObj : UndoObj[i], - undo : undo - }); - } - if (qItem) - execStack.unshift(qItem); - - return; - } - - var qItem = { - undoObj : UndoObj.preparse(undo, this), - undo : undo - - }; - execStack.push(qItem) - 1; - - if (typeof jpf.offline != "undefined" && jpf.offline.transactions.enabled) //We want to maintain the stack for sync - jpf.offline.transactions.addAction(this, qItem, "queue"); - - //The queue was empty, yay! we're gonna exec immediately - if (execStack.length == 1 && this.realtime) - UndoObj.saveChange(undo, this); - }; - - this.$queueNext = function(UndoObj, callback){ - /* - These thow checks are so important, that they are also executed - in release mode. - */ - if (execStack[0].undoObj != UndoObj){ - throw new Error(jpf.formatErrorString(0, this, "Executing Next \ - action in queue", "The execution stack was corrupted. This is \ - a fatal error. The application should be restarted. You will \ - lose all your changes. Please contact the administrator.")); - } - - //Reset the state of the undo item - UndoObj.state = null; - - //Remove the action item from the stack - var lastItem = execStack.shift(); - - if (typeof jpf.offline != "undefined" && jpf.offline.transactions.enabled) //We want to maintain the stack for sync - jpf.offline.transactions.removeAction(this, null, "queue"); - - //Check if there is a new action to execute; - if (!execStack[0] || lastItem == lastExecStackItem) - return; - - // @todo you could optimize this process by using multicall, but too much for now - - //Execute action next in queue - execStack[0].undoObj.saveChange(execStack[0].undo, this, callback); - }; - - this.$loadQueue = function(stack, type){ - if (type == "queue") { - if (execStack.length) { //@todo - throw new Error("oops"); - } - - execStack = stack; - } - - else if (type == "undo") { - if (stackDone.length) { //@todo - throw new Error("oops"); - } - - stackDone = stack; - } - else if (type == "redo") { - if (stackUndone.length) { //@todo - throw new Error("oops"); - } - - stackUndone = stack; - } - - else { //@todo - throw new Error("unknown"); - } - }; - - this.$getQueueLength = function(){ - return execStack.length; - }; - - this.$startQueue = function(callback){ - if (!execStack[0] || execStack[0].undoObj.state) //@todo This is gonna go wrong, probably - return false; - - //Execute action next in queue - execStack[0].undoObj.saveChange(execStack[0].undo, this, callback); - }; -}; - -/** - * @constructor - */ -jpf.UndoData = function(settings, at){ - this.tagName = "UndoData"; - this.extra = {}; - jpf.extend(this, settings); - - if (at) - this.at = at; - - //Copy Constructor - else if (settings && settings.tagName == "UndoData") { - this.args = settings.args.slice(); - this.rsbArgs = settings.rsbArgs.slice(); - } - //Constructor - else { - /* - @todo: Please check the requirement for this and how to solve - this. Goes wrong with multiselected actions! - */ - this.selNode = this.selNode || (this.action == "removeNode" - ? this.args[0] - : (this.jmlNode - ? this.jmlNode.selected - : null)); - } - - var options, _self = this; - - this.getActionXmlNode = function(undo){ - if (!this.xmlActionNode) return false; - if (!undo) return this.xmlActionNode; - - var xmlNode = $xmlns(this.xmlActionNode, "undo", jpf.ns.jml)[0]; - if (!xmlNode) - xmlNode = this.xmlActionNode; - - return xmlNode; - }; - - var serialState; - this.$export = function(){ - if (serialState) //Caching - return serialState; - - serialState = { - action : this.action, - rsbModel : this.rsbModel ? this.rsbModel.name : null, - rsbQueue : this.rsbQueue, - at : this.at.name, - timestamp : this.timestamp, - parsed : options ? options.parsed : null, //errors when options is not defined - userdata : options ? options.userdata : null, - extra : {} - }; - - //this can be optimized - var rsb = this.rsbModel - ? this.rsbModel.rsb - : jpf.remote; - - //Record arguments - var sLookup = (typeof jpf.offline != "undefined" && jpf.offline.sLookup) - ? jpf.offline.sLookup - : (jpf.offline.sLookup = {}); - if (!sLookup.count) sLookup.count = 0; - var xmlNode, xmlId, args = this.args.slice(); - - for (var i = 0; i < args.length; i++) { - if(args[i] && args[i].nodeType) { - if (!serialState.argsModel) { - var model = jpf.nameserver.get("model", - jpf.xmldb.getXmlDocId(args[i])); - - if(model) - serialState.argsModel = model.name || model.uniqueId; - } - - args[i] = serializeNode(args[i]); - } - } - - var item, name; - for (name in this.extra) { - item = this.extra[name]; - serialState.extra[name] = item && item.nodeType - ? serializeNode(item) - : item; - } - - //check this state and the unserialize function state and check the args and extra props - serialState.args = args; - - if (!serialState.argsModel) - jpf.console.warn("Could not determine model for serialization \ - of undo state. Will not be able to undo the state when the \ - server errors. This creates a potential risk of loosing \ - all changes on sync!") - - return serialState; - - function serializeNode(xmlNode){ - /* - If it's an attribute or directly connected to the root of the - model we'll just record the xpath - */ - if (xmlNode.nodeType == 2 - || jpf.xmldb.isChildOf(model.data, xmlNode, true)) { - xmlId = xmlNode.getAttribute(jpf.xmldb.xmlIdTag); - return { - xpath : rsb.xmlToXpath(xmlNode, model.data, true), - lookup : xmlId - }; - } - // So we've got a disconnected branch, lets serialize it - else { - var contextNode = xmlNode; - while(contextNode.parentNode && contextNode.parentNode.nodeType == 1) //find topmost parent - contextNode = xmlNode.parentNode; - - xmlId = contextNode.getAttribute(jpf.xmldb.xmlIdTag); - if (!xmlId) { - xmlId = "serialize" + sLookup.count++; - contextNode.setAttribute(jpf.xmldb.xmlIdTag, xmlId); - } - - var obj = { - xpath : rsb.xmlToXpath(xmlNode, contextNode, true), - lookup : xmlId - } - - if (!sLookup[xmlId]) { - contextNode.setAttribute(jpf.xmldb.xmlDocTag, - jpf.xmldb.getXmlDocId(contextNode)); - - sLookup[xmlId] = contextNode; - obj.xml = contextNode.xml || contextNode.serialize(); - } - - return obj; - } - } - }; - - this.$import = function(){ - if (this.rsbModel) - this.rsbModel = jpf.nameserver.get("model", this.rsbModel); - - if (this.argsModel) { - var model = jpf.nameserver.get("model", this.argsModel) - || jpf.lookup(this.argsModel); - - //Record arguments - var sLookup = (typeof jpf.offline != "undefined" && jpf.offline.sLookup) - ? jpf.offline.sLookup - : (jpf.offline.sLookup = {}); - if (!sLookup.count) sLookup.count = 0; - - var args = this.args; - var rsb = this.rsbModel - ? this.rsbModel.rsb - : jpf.remote; - - for (var xmlNode, i = 0; i < args.length; i++) { - if(args[i] && args[i].xpath) - args[i] = unserializeNode(args[i], model); - } - - var item, name; - for (name in this.extra) { - item = this.extra[name]; - if(item && item.xpath) - this.extra[name] = unserializeNode(item, model); - } - - this.args = args; - } - - options = { - undoObj : this, - userdata : this.userdata, - parsed : this.parsed - } - - if (this.timestamp) { - options.actionstart = this.timestamp; - options.headers = {"X-JPF-ActionStart": this.timestamp}; - } - - return this; - - function unserializeNode(xmlSerial, model){ - if (xmlSerial.xml) { - xmlNode = jpf.xmldb.getXml(xmlSerial.xml); - sLookup[xmlNode.getAttribute(jpf.xmldb.xmlIdTag)] = xmlNode; - } - else if (xmlSerial.lookup) { - xmlNode = sLookup[xmlSerial.lookup]; - - if (!xmlSerial.xpath) { //@todo - throw new Error("Serialization error"); - } - } - else xmlNode = null; - - return rsb.xpathToXml(xmlSerial.xpath, xmlNode || model.data); - } - }; - - //Send RSB Message.. - this.processRsbQueue = function(){ - if (this.rsbModel) - this.rsbModel.rsb.processQueue(this); - }; - - this.clearRsbQueue = function(){ - this.rsbQueue = null; - this.rsbModel = null; - }; - - this.saveChange = function(undo, at, callback){ - //Grouped undo/redo support - if (this.action == "group") { - var rpcNodes = this.args[1]; - at.$addToQueue(rpcNodes, undo, true); - return at.$queueNext(this); - } - - var xmlActionNode = this.getActionXmlNode(undo); - if (!xmlActionNode || !xmlActionNode.getAttribute("set")) - return at.$queueNext(this); - - this.state = undo ? "restoring" : "saving"; - - if (!options || options.preparse != -1) {//@todo test if this ever happens - throw new Error("Hmm, so sometimes preparse isn't called"); - } - options.preparse = false; - - jpf.saveData(xmlActionNode.getAttribute("set"), null, options, - function(data, state, extra){ - return at.$receive(data, state, extra, _self, callback); - }, {ignoreOffline: true}); - }; - - this.preparse = function(undo, at, multicall){ - var xmlActionNode = this.getActionXmlNode(undo); - if (!xmlActionNode || !xmlActionNode.getAttribute("set")) - return this; - - options = jpf.extend({ - //undoObj : this, - userdata : jpf.isTrue(xmlActionNode.getAttribute("ignore-fail")), - multicall : multicall, - preparse : true - }, this.extra); - - if (this.timestamp) { - options.actionstart = this.timestamp; - options.headers = {"X-JPF-ActionStart": this.timestamp}; - } - - jpf.saveData(xmlActionNode.getAttribute("set"), - this.selNode || this.xmlNode, options); //@todo please check if at the right time selNode is set - - return this; - }; -}; - -/** - * Default actions, that are known to the actiontracker - * @todo test if .extra has impact on speed - */ -jpf.actiontracker.actions = { - "setTextNode" : function(UndoObj, undo){ - var q = UndoObj.args; - - // Set Text Node - if (!undo) - jpf.xmldb.setTextNode(q[0], q[1], q[2], UndoObj); - else //Undo Text Node Setting - jpf.xmldb.setTextNode(q[0], UndoObj.extra.oldValue, q[2]); - }, - - "setAttribute" : function(UndoObj, undo){ - var q = UndoObj.args; - - // Set Attribute - if (!undo) { - //Set undo info - UndoObj.extra.name = q[1]; - UndoObj.extra.oldValue = q[0].getAttribute(q[1]); - - jpf.xmldb.setAttribute(q[0], q[1], q[2], q[3], UndoObj); - } - // Undo Attribute Setting - else { - if (!UndoObj.extra.oldValue) - jpf.xmldb.removeAttribute(q[0], q[1]); - else - jpf.xmldb.setAttribute(q[0], q[1], UndoObj.extra.oldValue, q[3]); - } - }, - - "removeAttribute" : function(UndoObj, undo){ - var q = UndoObj.args; - - // Remove Attribute - if (!undo) { - // Set undo info - UndoObj.extra.name = q[1]; - UndoObj.extra.oldValue = q[0].getAttribute(q[1]); - - jpf.xmldb.removeAttribute(q[0], q[1], q[2], UndoObj); - } - //Undo Attribute Removal - else - jpf.xmldb.setAttribute(q[0], q[1], UndoObj.extra.oldValue, q[2]); - }, - - /** - * @deprecated Use "multicall" from now on - */ - "setAttributes" : function(UndoObj, undo){ - var prop, q = UndoObj.args; - - // Set Attribute - if (!undo) { - // Set undo info - var oldValues = {}; - for (prop in q[1]) { - oldValues[prop] = q[0].getAttribute(prop); - q[0].setAttribute(prop, q[1][prop]); - } - UndoObj.extra.oldValues = oldValues; - - jpf.xmldb.applyChanges("attribute", q[0], UndoObj); - } - //Undo Attribute Setting - else { - for (prop in UndoObj.oldValues) { - if (!UndoObj.extra.oldValues[prop]) - q[0].removeAttribute(prop); - else - q[0].setAttribute(prop, UndoObj.extra.oldValues[prop]); - } - - jpf.xmldb.applyChanges("attribute", q[0], UndoObj); - } - }, - - "replaceNode" : function(UndoObj, undo){ - var q = UndoObj.args; - - //Set Attribute - if (!undo) - jpf.xmldb.replaceNode(q[0], q[1], q[2], UndoObj); - //Undo Attribute Setting - else - jpf.xmldb.replaceNode(q[1], q[0], q[2], UndoObj); - }, - - "addChildNode" : function(UndoObj, undo){ - var q = UndoObj.args; - - //Add Child Node - if (!undo) - jpf.xmldb.addChildNode(q[0], q[1], q[2], q[3], UndoObj); - //Remove Child Node - else - jpf.xmldb.removeNode(UndoObj.extra.addedNode); - }, - - "appendChild" : function(UndoObj, undo){ - var q = UndoObj.args; - - //Append Child Node - if (!undo) - jpf.xmldb.appendChild(q[0], q[1], q[2], q[3], q[4], UndoObj); - //Remove Child Node - else - jpf.xmldb.removeNode(q[1]); - }, - - "moveNode" : function(UndoObj, undo){ - var q = UndoObj.args; - - //Move Node - if (!undo) - jpf.xmldb.moveNode(q[0], q[1], q[2], q[3], UndoObj); - //Move Node to previous position - else - jpf.xmldb.moveNode(UndoObj.extra.parent, q[1], - UndoObj.extra.beforeNode, q[3]); - }, - - "removeNode" : function(UndoObj, undo){ - var q = UndoObj.args; - - //Remove Node - if (!undo) - jpf.xmldb.removeNode(q[0], q[1], UndoObj); - //Append Child Node - else - jpf.xmldb.appendChild(UndoObj.extra.parent, - UndoObj.extra.removedNode, UndoObj.extra.beforeNode); - }, - - /** - * @deprecated Use "multicall" from now on - */ - "removeNodeList" : function(UndoObj, undo){ - if (undo) { - var d = UndoObj.extra.removeList; - for (var i = d.length - 1; i >= 0; i--) { - jpf.xmldb.appendChild(d[i].pNode, - d[i].removedNode, d[i].beforeNode); - } - } - else - jpf.xmldb.removeNodeList(UndoObj.args, UndoObj); - }, - - "setUndoObject" : function(UndoObj, undo){ - var q = UndoObj.args; - UndoObj.xmlNode = q[0]; - }, - - "group" : function(UndoObj, undo, at){ - if (!UndoObj.stackDone) { - var done = UndoObj.args[0]; - UndoObj.stackDone = done; - UndoObj.stackUndone = []; - } - - at[undo ? "undo" : "redo"](UndoObj.stackDone.length, false, - UndoObj.stackDone, UndoObj.stackUndone); - }, - - "setValueByXpath" : function(UndoObj, undo){ - var q = UndoObj.args;//xmlNode, value, xpath - // Setting NodeValue and creating the node if it doesnt exist - if (!undo) { - if (UndoObj.extra.newNode) { - jpf.xmldb.appendChild(UndoObj.extra.parentNode, UndoObj.extra.newNode); - } - else { - var newNodes = []; - jpf.xmldb.setNodeValue(q[0], q[1], true, { - undoObj : UndoObj, - xpath : q[2], - newNodes : newNodes, - forceNew : q[3] - }); - - UndoObj.extra.newNode = newNodes[0]; - } - } - // Undo Setting NodeValue - else { - if (UndoObj.extra.newNode) { - UndoObj.extra.parentNode = UndoObj.extra.newNode.parentNode; - jpf.xmldb.removeNode(UndoObj.extra.newNode); - } - else - jpf.xmldb.setNodeValue(UndoObj.extra.appliedNode, UndoObj.extra.oldValue, true); - } - }, - - //@todo please change .func to .action for constency reasons - "multicall" : function(UndoObj, undo, at){ - var prop, q = UndoObj.args; - - var dUpdate = jpf.xmldb.delayUpdate; - jpf.xmldb.delayUpdate = true; - - // Set Calls - if (!undo) { - for(var i = 0; i < q.length; i++) { - if (!q[i].extra) - q[i].extra = {} - jpf.actiontracker.actions[q[i].func](q[i], false, at); - } - } - // Undo Calls - else { - for (var i = q.length - 1; i >= 0; i--) - jpf.actiontracker.actions[q[i].func](q[i], true, at); - } - - jpf.xmldb.delayUpdate = dUpdate; - - //if (!dUpdate) - //jpf.xmldb.notifyQueued(); - }, - - /** - * @deprecated Use "multicall" from now on - */ - "addRemoveNodes" : function(UndoObj, undo){ - var q = UndoObj.args; - - // Set Text Node - if (!undo) { - // Add - for (var i = 0; i < q[1].length; i++){ - jpf.xmldb.appendChild(q[0], q[1][i], - null, null, null, UndoObj); - } - - // Remove - for (var i = 0; i < q[2].length; i++) - jpf.xmldb.removeNode(q[2][i], null, UndoObj); - } - // Undo Text Node Setting - else { - // Add - for (var i = 0; i < q[2].length; i++) - jpf.xmldb.appendChild(q[0], q[2][i]); - - // Remove - for (var i = 0; i < q[1].length; i++) - jpf.xmldb.removeNode(q[1][i]); - } - } -}; - - -/*FILEHEAD(/var/lib/jpf/src/elements/tree.js)SIZE(-1077090856)TIME(1238950356)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * Element displaying data in a list where each item in the list can contain
- * such a list. This element gives the user the ability to walk through this
- * tree of data by clicking open elements to show more elements. The tree
- * can grow by fetching more data when the user requests it.
- * Example:
- * A tree with inline items.
- * <code>
- * <j:tree id="tree" align="right">
- * <j:item caption="root" icon="icoUsers.gif">
- * <j:item icon="icoUsers.gif" caption="test">
- * <j:item icon="icoUsers.gif" caption="test" />
- * <j:item icon="icoUsers.gif" caption="test" />
- * <j:item icon="icoUsers.gif" caption="test" />
- * </j:item>
- * <j:item icon="icoUsers.gif" caption="test" />
- * <j:item icon="icoUsers.gif" caption="test" />
- * <j:item icon="icoUsers.gif" caption="test" />
- * </j:item>
- * </j:tree>
- * </code>
- * Example:
- * <code>
- * <j:tree model="url:items.xml">
- * <j:bindings>
- * <j:caption select="@name" />
- * <j:icon select="@icon"/>
- * <j:traverse select="file|folder" />
- * </j:bindings>
- * </j:tree>
- * </code>
- *
- * @constructor
- * @define tree
- * @allowchild {smartbinding}
- * @addnode elements
- *
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.4
- *
- * @inherits jpf.Validation
- * @inherits jpf.XForms
- * @inherits jpf.DragDrop
- * @inherits jpf.MultiSelect
- * @inherits jpf.Cache
- * @inherits jpf.Presentation
- * @inherits jpf.DataBinding
- * @inherits jpf.Rename
- * - * @binding insert Determines how new data is loaded when the user expands
- * an item. For instance by clicking on the + button. This way only the root nodes
- * need to be loaded at the start of the application. All other children are
- * received on demand when the user requests it by navigating throught the tree.
- * Example:
- * This example shows an insert rule that only works on folder elements. It will
- * read the directory contents using webdav and insert it under the selected
- * tree node.
- * <code>
- * <j:bindings>
- * <j:caption select="@caption" />
- * <j:insert select="self::folder" get="webdav:readdir({@id})" />
- * <j:traverse select="folder" />
- * </j:bindings>
- * </code>
- * @binding caption Determines the caption of a tree node.
- * @binding icon Determines the icon of a tree node.
- * @binding css Determines a css class for a tree node.
- * Example:
- * In this example a node is bold when the folder contains unread messages:
- * <code>
- * <j:tree>
- * <j:bindings>
- * <j:caption select="@caption" />
- * <j:css select="message[@unread]" value="highlighUnread" />
- * <j:icon select="@icon" />
- * <j:icon select="self::folder" value="icoFolder.gif" />
- * <j:traverse select="folder" />
- * </j:bindings>
- * </j:tree>
- * </code>
- * @binding tooltip Determines the tooltip of a tree node.
- * @binding empty Determines the empty message of a node.
- * Example:
- * This example shows a gouped contact list, that displays a message under
- * empty groups.
- * <code>
- * <j:tree>
- * <j:bindings>
- * <j:caption select="@caption" />
- * <j:icon select="self::contact" value="icoContact.png" />
- * <j:icon select="self::group" value="icoFolder.png" />
- * <j:empty select="self::group" value="Drag a contact to this group." />
- * <j:traverse select="group|contact" />
- * </j:bindings>
- * </j:tree>
- * </code>
- */
-jpf.tree = jpf.component(jpf.NODE_VISIBLE, function(){
- //Options
- this.isTreeArch = true; // This element has a tree architecture.
- this.$focussable = true; // This object can get the focus.
- this.multiselect = false; // Initially multiselect is disabled.
- this.bufferselect = true;
-
- this.startcollapsed = true;
- this.animType = jpf.tween.NORMAL;
- this.animOpenStep = 3;
- this.animCloseStep= 1;
- this.animSpeed = 10;
-
- this.dynCssClasses = [];
-
- var HAS_CHILD = 1 << 1;
- var IS_CLOSED = 1 << 2;
- var IS_LAST = 1 << 3;
- var IS_ROOT = 1 << 4;
-
- var _self = this;
- var treeState = {};
- this.nodes = [];
-
- treeState[0] = "";
- treeState[HAS_CHILD] = "min";
- treeState[HAS_CHILD | IS_CLOSED] = "plus";
- treeState[IS_LAST] = "last";
- treeState[IS_LAST | HAS_CHILD] = "minlast";
- treeState[IS_LAST | HAS_CHILD | IS_CLOSED] = "pluslast";
- treeState[IS_ROOT] = "root";
-
- /**** Properties and Attributes ****/
-
- /**
- * @attribute {Boolean} openadd wether the tree expands the parent to which a node is added. Defaults to true.
- * @attribute {Boolean} startcollapsed wether the tree collapses all nodes that contain children on load. Defaults to true.
- * @attribute {Boolean} nocollapse wether the user cannot collapse a node. Defaults to false.
- * @attribute {Boolean} singleopen wether the tree will expand a node by a single click. Defaults to false.
- * @attribute {Boolean} prerender wether the tree will render all the nodes at load. Defaults to true.
- */
- this.$booleanProperties["openadd"] = true;
- this.$booleanProperties["startcollapsed"] = true;
- this.$booleanProperties["nocollapse"] = true;
- this.$booleanProperties["singleopen"] = true;
- this.$booleanProperties["prerender"] = true;
-
- this.openadd = true;
- this.startcollapsed = 1;
- this.prerender = true;
-
- /**
- * @attribute {String} mode Sets the way this element interacts with the user.
- * Possible values:
- * check the user can select a single item from this element. The selected item is indicated.
- * radio the user can select multiple items from this element. Each selected item is indicated.
- */
- this.mode = "normal";
- this.$propHandlers["mode"] = function(value){
- this.mode = value || "normal";
-
- if ("check|radio".indexOf(this.mode) > -1) {
- this.allowdeselect = false;
-
- this.addEventListener("afterrename", $afterRenameMode);
-
- if (this.mode == "check") {
- this.autoselect = false;
- this.ctrlselect = true;
- this.bufferselect = false;
- this.multiselect = true;
- this.delayedselect = false;
-
- this.addEventListener("afterselect", function(e){
- var pNode = this.getTraverseParent(e.xmlNode);
-
- if (pNode != this.xmlRoot) {
- var nodes = this.getTraverseNodes(pNode);
- var sel = e.list;
-
- var count = 0;
- for (var i = 0; i < nodes.length; i++) {
- if (sel.contains(nodes[i]))
- count++;
- }
-
- if (count) {
- var htmlNode = jpf.xmldb.findHTMLNode(this.getTraverseParent(e.xmlNode), this);
- jpf.setStyleClass(htmlNode, count == nodes.length
- ? "selected"
- : "partial", ["partial", "selected"]);
-
- if (!this.isSelected(pNode))
- this.select(pNode, null, null, null, null, true);
- }
- else {
- var htmlNode = jpf.xmldb.findHTMLNode(pNode, this);
- jpf.setStyleClass(htmlNode, "", ["partial", "selected"]);
-
- if (this.isSelected(pNode))
- this.select(pNode);
- }
- }
-
- var to = this.isSelected(e.xmlNode);
- nodes = this.getTraverseNodes(e.xmlNode);
- if (nodes.length) {
- for (var i = 0; i < nodes.length; i++) {
- if (to != this.isSelected(nodes[i]))
- this.select(nodes[i]);
- }
-
- jpf.setStyleClass(jpf.xmldb.findHTMLNode(e.xmlNode, this),
- to ? "selected" : "", ["partial", "selected"]);
- }
-
- this.setIndicator(e.xmlNode);
- });
- }
- else if (this.mode == "radio")
- this.multiselect = false;
-
- //if (!this.actionRules) //default disabled
- //this.actionRules = {}
- }
- else {
- //@todo undo actionRules setting
- this.ctrlselect = false;
- this.bufferselect = true;//hmm fishy
- this.multiselect = false;//hmm fishy
- this.removeEventListener("afterrename", $afterRenameMode);
- }
- };
-
- function $afterRenameMode(){
- var sb = this.$getMultiBind();
- if (!sb)
- return;
-
- //Make sure that the old value is removed and the new one is entered
- sb.$updateSelection();
- //this.reselect(this.selected);
- }
-
- /**** Public Methods ****/
-
- /**
- * @notimplemented
- * @todo who's volunteering?
- */
- this.openAll = function(){};
-
- /**
- * @notimplemented
- * @todo who's volunteering?
- */
- this.closeAll = function(){};
-
- /**
- * @notimplemented
- * @todo who's volunteering?
- */
- this.selectPath = function(path){};
-
- /**** Sliding functions ****/
-
- /**
- * @private
- */
- this.slideToggle = function(htmlNode, force){
- if(this.nocollapse)
- return;
-
- if (!htmlNode)
- htmlNode = this.$selected;
-
- var id = htmlNode.getAttribute(jpf.xmldb.htmlIdTag);
- while (!id && htmlNode.parentNode)
- var id = (htmlNode = htmlNode.parentNode)
- .getAttribute(jpf.xmldb.htmlIdTag);
-
- var container = this.$getLayoutNode("item", "container", htmlNode);
- if (jpf.getStyle(container, "display") == "block") {
- if(force == 1) return;
- htmlNode.className = htmlNode.className.replace(/min/, "plus");
- this.slideClose(container, jpf.xmldb.getNode(htmlNode));
- }
- else {
- if (force == 2) return;
- htmlNode.className = htmlNode.className.replace(/plus/, "min");
- this.slideOpen(container, jpf.xmldb.getNode(htmlNode));
- }
- };
-
- var lastOpened = {};
- /**
- * @private
- */
- this.slideOpen = function(container, xmlNode, immediate){
- if (!xmlNode)
- xmlNode = this.selected;
-
- var htmlNode = jpf.xmldb.findHTMLNode(xmlNode, this);
- if (!container)
- container = this.$findContainer(htmlNode);
-
- if (this.singleopen) {
- var pNode = this.getTraverseParent(xmlNode)
- var p = (pNode || this.xmlRoot).getAttribute(jpf.xmldb.xmlIdTag);
- if (lastOpened[p] && lastOpened[p][1] != xmlNode
- && this.getTraverseParent(lastOpened[p][1]) == pNode)
- this.slideToggle(lastOpened[p][0], 2);//lastOpened[p][1]);
- lastOpened[p] = [htmlNode, xmlNode];
- }
-
- container.style.display = "block";
-
- if (immediate) {
- container.style.height = "auto";
- return;
- }
-
- jpf.tween.single(container, {
- type : 'scrollheight',
- from : 0,
- to : container.scrollHeight,
- anim : this.animType,
- steps : this.animOpenStep,
- interval: this.animSpeed,
- onfinish: function(container){
- if (xmlNode && _self.hasLoadStatus(xmlNode, "potential")) {
- setTimeout(function(){
- _self.$extend(xmlNode, container);
- });
- container.style.height = "auto";
- }
- else {
- //container.style.overflow = "visible";
- container.style.height = "auto";
- }
- }
- });
- };
-
- /**
- * @private
- */
- this.slideClose = function(container, xmlNode){
- if (this.nocollapse)
- return;
-
- if (!xmlNode)
- xmlNode = this.selected;
-
- if (this.singleopen) {
- var p = (this.getTraverseParent(xmlNode) || this.xmlRoot)
- .getAttribute(jpf.xmldb.xmlIdTag);
- lastOpened[p] = null;
- }
-
- container.style.height = container.offsetHeight;
- container.style.overflow = "hidden";
-
- jpf.tween.single(container, {
- type : 'scrollheight',
- from : container.scrollHeight,
- to : 0,
- anim : this.animType,
- steps : this.animCloseStep,
- interval: this.animSpeed,
- onfinish: function(container, data){
- container.style.display = "none";
- }
- });
- };
-
- /**** DragDrop Support ****/
-
- this.$showDragIndicator = function(sel, e){
- var x = e.offsetX + 22;
- var y = e.offsetY;
-
- this.oDrag.startX = x;
- this.oDrag.startY = y;
-
- document.body.appendChild(this.oDrag);
- this.$updateNode(this.selected, this.oDrag);
-
- return this.oDrag;
- };
-
- this.$hideDragIndicator = function(){
- this.oDrag.style.display = "none";
- };
-
- this.$moveDragIndicator = function(e){
- this.oDrag.style.left = (e.clientX - this.oDrag.startX) + "px";
- this.oDrag.style.top = (e.clientY - this.oDrag.startY) + "px";
- };
-
- this.$initDragDrop = function(){
- if (!this.$hasLayoutNode("dragindicator")) return;
- this.oDrag = jpf.xmldb.htmlImport(
- this.$getLayoutNode("dragindicator"), document.body);
-
- this.oDrag.style.zIndex = 1000000;
- this.oDrag.style.position = "absolute";
- this.oDrag.style.cursor = "default";
- this.oDrag.style.display = "none";
- };
-
- this.findValueNode = function(el){
- if (!el) return null;
-
- while(el && el.nodeType == 1
- && !el.getAttribute(jpf.xmldb.htmlIdTag)) {
- el = el.parentNode;
- }
-
- return (el && el.nodeType == 1 && el.getAttribute(jpf.xmldb.htmlIdTag))
- ? el
- : null;
- };
-
- this.$dragout = function(dragdata){
- if (this.lastel)
- this.$setStyleClass(this.lastel, "", ["dragDenied", "dragInsert",
- "dragAppend", "selected", "indicate"]);
- this.$setStyleClass(this.$selected, "selected", ["dragDenied",
- "dragInsert", "dragAppend", "indicate"]);
-
- this.lastel = null;
- };
-
- this.$dragover = function(el, dragdata, extra){
- if(el == this.oExt) return;
-
- this.$setStyleClass(this.lastel || this.$selected, "", ["dragDenied",
- "dragInsert", "dragAppend", "selected", "indicate"]);
-
- this.$setStyleClass(this.lastel = this.findValueNode(el), extra
- ? (extra[1] && extra[1].getAttribute("operation") == "insert-before"
- ? "dragInsert"
- : "dragAppend")
- : "dragDenied");
- };
-
- this.$dragdrop = function(el, dragdata, extra){
- this.$setStyleClass(this.lastel || this.$selected,
- !this.lastel && (this.$selected || this.lastel == this.$selected)
- ? "selected"
- : "",
- ["dragDenied", "dragInsert", "dragAppend", "selected", "indicate"]);
-
- this.lastel = null;
- };
-
-
- /**** Databinding Support ****/
-
- //@todo refactor
- this.$add = function(xmlNode, Lid, xmlParentNode, htmlParentNode, beforeNode, isLast){
- var loadChildren = this.bindingRules && this.bindingRules["insert"]
- ? this.getNodeFromRule("insert", xmlNode)
- : false;
- var hasTraverseNodes = xmlNode.selectSingleNode(this.traverse) ? true : false;
- var hasChildren = loadChildren || hasTraverseNodes;
-
- var startcollapsed = this.startcollapsed;// || this.applyRuleSetOnNode("collapse", xmlNode, ".") !== false;
- var state = (hasChildren ? HAS_CHILD : 0) | (startcollapsed && hasChildren
- || loadChildren ? IS_CLOSED : 0) | (isLast ? IS_LAST : 0);
-
- var htmlNode = this.$initNode(xmlNode, state, Lid);
- var container = this.$getLayoutNode("item", "container");
- if (!startcollapsed && !this.nocollapse)
- container.setAttribute("style", "overflow:visible;height:auto;display:block;");
-
- var removeContainer = (!this.removecontainer || hasChildren);
-
- //TEMP on for dynamic subloading
- if (!hasChildren || loadChildren) {
- container.setAttribute("style", "display:none;");
- }
-
- //Dynamic SubLoading (Insertion) of SubTree
- if (!this.prerender)
- var traverseLength = this.getTraverseNodes(xmlNode).length;
- if (loadChildren && !this.hasLoadStatus(xmlNode) || hasChildren && !this.prerender && traverseLength > 2)
- this.$setLoading(xmlNode, container);
- else if (!hasTraverseNodes && this.applyRuleSetOnNode("empty", xmlNode))
- this.$setClearMessage(container);
-
- if ((!htmlParentNode || htmlParentNode == this.oInt)
- && xmlParentNode == this.xmlRoot && !beforeNode) {
- this.nodes.push(htmlNode);
- if (!jpf.xmldb.isChildOf(htmlNode, container, true) && removeContainer)
- this.nodes.push(container);
-
- this.$setStyleClass(htmlNode, "root");
- this.$setStyleClass(container, "root");
- }
- else {
- if (!htmlParentNode) {
- htmlParentNode = jpf.xmldb.findHTMLNode(xmlNode.parentNode, this);
- htmlParentNode = htmlParentNode
- ? this.$getLayoutNode("item", "container", htmlParentNode)
- : this.oInt;
- }
-
- if (htmlParentNode == this.oInt) {
- this.$setStyleClass(htmlNode, "root");
- this.$setStyleClass(container, "root");
- }
-
- if (!beforeNode && this.getNextTraverse(xmlNode))
- beforeNode = jpf.xmldb.findHTMLNode(this.getNextTraverse(xmlNode), this);
- if (beforeNode && beforeNode.parentNode != htmlParentNode)
- beforeNode = null;
-
- if (htmlParentNode.style
- && this.getTraverseNodes(xmlNode.parentNode).length == 1)
- this.$removeClearMessage(htmlParentNode);
-
- //alert("|" + htmlNode.nodeType + "-" + htmlParentNode.nodeType + "-" + beforeNode + ":" + container.nodeType);
- //Insert Node into Tree
- if (htmlParentNode.style) {
- jpf.xmldb.htmlImport(htmlNode, htmlParentNode, beforeNode);
- if (!jpf.xmldb.isChildOf(htmlNode, container, true) && removeContainer)
- var container = jpf.xmldb.htmlImport(container,
- htmlParentNode, beforeNode);
- }
- else {
- htmlParentNode.insertBefore(htmlNode, beforeNode);
- if (!jpf.xmldb.isChildOf(htmlParentNode, container, true) && removeContainer)
- htmlParentNode.insertBefore(container, beforeNode);
- }
-
- //Fix parent if child is added to drawn parentNode
- if (htmlParentNode.style) {
- if (!startcollapsed && this.openadd && htmlParentNode != this.oInt
- && htmlParentNode.style.display != "block")
- this.slideOpen(htmlParentNode, xmlParentNode, true);
-
- //this.$fixItem(xmlNode, htmlNode); this one shouldn't be called, because it should be set right at init
- this.$fixItem(xmlParentNode, jpf.xmldb.findHTMLNode(xmlParentNode, this));
- if (this.getNextTraverse(xmlNode, true)) { //should use traverse here
- this.$fixItem(this.getNextTraverse(xmlNode, true),
- jpf.xmldb.findHTMLNode(this.getNextTraverse(xmlNode, true),
- this));
- }
- }
- }
-
- if (this.prerender || traverseLength < 3)
- this.$addNodes(xmlNode, container, true); //checkChildren ???
- /*else {
- this.setLoadStatus(xmlNode, "potential");
- }*/
-
- return container;
- };
-
- this.$fill = function(){
- //if(!this.nodes.length) return;
- //this.oInt.innerHTML = "";
- jpf.xmldb.htmlImport(this.nodes, this.oInt);
- this.nodes.length = 0;
-
- //for(var i=0;i<this.nodes.length;i++)
- //jpf.xmldb.htmlImport(this.nodes[i], this.oInt);
- //this.nodes.length = 0;
- };
-
- this.$getParentNode = function(htmlNode){
- return htmlNode
- ? this.$getLayoutNode("item", "container", htmlNode)
- : this.oInt;
- };
-
- this.$fixItem = function(xmlNode, htmlNode, isDeleting, oneLeft, noChildren){
- if (!htmlNode) return;
-
- if (isDeleting) {
- //if isLast fix previousSibling
- if (prevSib = this.getNextTraverse(xmlNode, true))
- this.$fixItem(prevSib, this.getNodeFromCache(prevSib
- .getAttribute(jpf.xmldb.xmlIdTag) + "|"
- + this.uniqueId), null, true);
-
- //if no sibling fix parent
- if (!this.emptyMessage && xmlNode.parentNode.selectNodes(this.traverse).length == 1)
- this.$fixItem(xmlNode.parentNode, this.getNodeFromCache(
- xmlNode.parentNode.getAttribute(jpf.xmldb.xmlIdTag)
- + "|" + this.uniqueId), null, false, true);
- }
- else {
- var container = this.$getLayoutNode("item", "container", htmlNode);
- var hasChildren = false;
- if (noChildren)
- hasChildren = false;
- else if (xmlNode.selectNodes(this.traverse).length > 0)
- hasChildren = true;
- else if (this.bindingRules && this.bindingRules["insert"]
- && this.getNodeFromRule("insert", xmlNode))
- hasChildren = true;
- else
- hasChildren = false;
-
- var isClosed = hasChildren && container.style.display != "block";
- var isLast = this.getNextTraverse(xmlNode, null, oneLeft ? 2 : 1)
- ? false
- : true;
-
- var state = (hasChildren ? HAS_CHILD : 0)
- | (isClosed ? IS_CLOSED : 0) | (isLast ? IS_LAST : 0);
- this.$setStyleClass(this.$getLayoutNode("item", "class", htmlNode),
- treeState[state], ["min", "plus", "last", "minlast", "pluslast"]);
- this.$setStyleClass(this.$getLayoutNode("item", "container", htmlNode),
- treeState[state], ["min", "plus", "last", "minlast", "pluslast"]);
-
- if (!hasChildren && container)
- container.style.display = "none";
-
- if (state & HAS_CHILD) {
- //@todo please rewrite this to a normal way of doing this
- var elOpenClose = this.$getLayoutNode("item", "openclose", htmlNode);
- if (elOpenClose) {
- elOpenClose.onmousedown = new Function('e', "if(!e) e = event;\
- if (e.button == 2) return;\
- var o = jpf.lookup(" + this.uniqueId + ");\
- o.slideToggle(this);\
- if (o.onmousedown) o.onmousedown(e, this);\
- jpf.cancelBubble(e, o);");
- }
-
- var elIcon = this.$getLayoutNode("item", "icon", htmlNode);
- if (elIcon) {
- elIcon[this.opencloseaction || "ondblclick"]
- = new Function("var o = jpf.lookup(" + this.uniqueId + "); " +
- "o.stopRename();" +
- " o.slideToggle(this);\
- o.choose();");
- }
-
- this.$getLayoutNode("item", "select", htmlNode)[this.opencloseaction || "ondblclick"]
- = new Function("var o = jpf.lookup(" + this.uniqueId + "); " +
- "o.stopRename();" +
- " this.dorename=false;\
- o.slideToggle(this);\
- o.choose();");
- }
- /*else{
- //Experimental
- this.$getLayoutNode("item", "openclose", htmlNode).onmousedown = null;
- this.$getLayoutNode("item", "icon", htmlNode)[this.opencloseaction || "ondblclick"] = null;
- this.$getLayoutNode("item", "select", htmlNode)[this.opencloseaction || "ondblclick"] = null;
- }*/
- }
- };
-
- //@todo please upgrade all the event calls to the 21st century, it hurts my eyes.
- this.$initNode = function(xmlNode, state, Lid){
- //Setup Nodes Interaction
- this.$getNewContext("item");
-
- var hasChildren = state & HAS_CHILD || this.emptyMessage && this.applyRuleSetOnNode("empty", xmlNode);
-
- //should be restructured and combined events set per element
- var oItem = this.$getLayoutNode("item");
- //@todo this should use dispatchEvent, and be moved to oExt
- oItem.setAttribute("onmouseover",
- "var o = jpf.lookup(" + this.uniqueId + ");\
- if (o.onmouseover) o.onmouseover(event, this);\
- jpf.setStyleClass(this, 'hover');");
- oItem.setAttribute("onmouseout",
- "var o = jpf.lookup(" + this.uniqueId + ");\
- if (o.onmouseout) o.onmouseout(event, this);\
- jpf.setStyleClass(this, '', ['hover']);");
- oItem.setAttribute("onmousedown",
- "var o = jpf.lookup(" + this.uniqueId + ");\
- if (o.onmousedown) o.onmousedown(event, this);");
-
- //Set open/close skin class & interaction
- this.$setStyleClass(this.$getLayoutNode("item", "class"), treeState[state]).setAttribute(jpf.xmldb.htmlIdTag, Lid);
- this.$setStyleClass(this.$getLayoutNode("item", "container"), treeState[state])
- //this.$setStyleClass(oItem, xmlNode.tagName)
- var elOpenClose = this.$getLayoutNode("item", "openclose");
- if (hasChildren && elOpenClose) {
- elOpenClose.setAttribute(this.opencloseaction || "onmousedown",
- "var o = jpf.lookup(" + this.uniqueId + ");\
- o.slideToggle(this);\
- if (o.onmousedown) o.onmousedown(event, this);\
- jpf.cancelBubble(event, o);");
- }
-
- //Icon interaction
- var elIcon = this.$getLayoutNode("item", "icon");
- if (elIcon) {
- if (hasChildren) {
- var strFunc = "var o = jpf.lookup(" + this.uniqueId + ");\
- o.choose()" +
- "o.stopRename();" +
- "o.slideToggle(this);\
- jpf.cancelBubble(event,o);";
-
- if (this.opencloseaction != "onmousedown")
- elIcon.setAttribute(this.opencloseaction || "ondblclick", strFunc);
- }
-
- elIcon.setAttribute("onmousedown",
- "jpf.lookup(" + this.uniqueId + ").select(this, event.ctrlKey, event.shiftKey);"
- + (strFunc && this.opencloseaction == "onmousedown" ? strFunc : ""));
-
- if (!elIcon.getAttribute("ondblclick"))
- elIcon.setAttribute("ondblclick", "var o = jpf.lookup(" + this.uniqueId + ");\
- o.choose();" +
- "o.stopRename();" +
- ""
- );
- }
-
- //Select interaction
- var elSelect = this.$getLayoutNode("item", "select");
- if (hasChildren) {
- var strFunc2 = "var o = jpf.lookup(" + this.uniqueId + ");\
- o.choose();" +
- "o.stopRename();" +
- "o.slideToggle(this);\
- jpf.cancelBubble(event,o);";
- if (this.opencloseaction != "onmousedown")
- elSelect.setAttribute(this.opencloseaction || "ondblclick", strFunc2);
- }
- //if(event.button != 1) return;
- elSelect.setAttribute("onmousedown",
- "var o = jpf.lookup(" + this.uniqueId + ");\
- if (!o.renaming && o.hasFocus() \
- && jpf.xmldb.isChildOf(o.$selected, this) && o.selected)\
- this.dorename = true;\
- o.select(this, event.ctrlKey, event.shiftKey);\
- if (o.onmousedown)\
- o.onmousedown(event, this);"
- + (strFunc2 && this.opencloseaction == "onmousedown" ? strFunc2 : ""));
-
- if (!elSelect.getAttribute("ondblclick"))
- elSelect.setAttribute("ondblclick",
- "var o = jpf.lookup(" + this.uniqueId + ");" +
- "o.stopRename();" +
- "o.choose();");
-
- elSelect.setAttribute("onmouseup",
- "var o = jpf.lookup(" + this.uniqueId + ");\
- if (this.dorename && o.mode == 'normal') \
- o.startDelayedRename(event);\
- this.dorename = false;");
-
- //elItem.setAttribute("contextmenu", "alert(1);var o = jpf.lookup(" + this.uniqueId + ");o.dispatchEvent("contextMenu", o.selected);");
-
- //Setup Nodes Identity (Look)
- if (elIcon) {
- var iconURL = this.applyRuleSetOnNode("icon", xmlNode);
- if (iconURL) {
- if (elIcon.tagName.match(/^img$/i))
- elIcon.setAttribute("src", this.iconPath + iconURL);
- else
- elIcon.setAttribute("style", "background-image:url(" + this.iconPath + iconURL + ")");
- }
- }
-
- var elCaption = this.$getLayoutNode("item", "caption");
- if (elCaption)
- jpf.xmldb.setNodeValue(elCaption,
- this.applyRuleSetOnNode("caption", xmlNode));
-
- var strTooltip = this.applyRuleSetOnNode("tooltip", xmlNode)
- if (strTooltip)
- oItem.setAttribute("title", strTooltip);
-
- var cssClass = this.applyRuleSetOnNode("css", xmlNode);
- if (cssClass) {
- this.$setStyleClass(this.$getLayoutNode("item", null, oItem), cssClass);
- this.$setStyleClass(this.$getLayoutNode("item", "container", oItem), cssClass);
- this.dynCssClasses.push(cssClass);
- }
-
- return oItem;
- };
-
- this.$deInitNode = function(xmlNode, htmlNode){
- //Lookup container
- var containerNode = this.$getLayoutNode("item", "container", htmlNode);
- var pContainer = htmlNode.parentNode;
-
- //Remove htmlNodes from tree
- containerNode.parentNode.removeChild(containerNode);
- pContainer.removeChild(htmlNode);
-
- //Fix Images (+, - and lines)
- if (xmlNode.parentNode != this.xmlRoot)
- this.$fixItem(xmlNode, htmlNode, true);
-
- if (this.emptyMessage && !pContainer.childNodes.length)
- this.$setClearMessage(pContainer);
-
- //Fix look (tree thing)
- this.$fixItem(xmlNode, htmlNode, true);
- //this.$fixItem(xmlNode.parentNode, jpf.xmldb.findHTMLNode(xmlNode.parentNode, this));
- /*throw new Error();
- if(xmlNode.previousSibling) //should use traverse here
- this.$fixItem(xmlNode.previousSibling, jpf.xmldb.findHTMLNode(xmlNode.previousSibling, this));*/
- };
-
- this.$moveNode = function(xmlNode, htmlNode){
- if (!self.jpf.debug && !htmlNode)
- return;
-
- if (this.hasLoadStatus(xmlNode.parentNode, "potential")) {
- var container = this.$getLayoutNode("item", "container", htmlNode);
- htmlNode.parentNode.removeChild(htmlNode);
- container.parentNode.removeChild(container);
- this.$extend(xmlNode.parentNode);
- return;
- }
-
- var oPHtmlNode = htmlNode.parentNode;
- var pHtmlNode = jpf.xmldb.findHTMLNode(xmlNode.parentNode, this);
- //if(!pHtmlNode) return;
-
- var nSibling = this.getNextTraverse(xmlNode);
- var beforeNode = nSibling
- ? jpf.xmldb.findHTMLNode(nSibling, this)
- : null;
- var pContainer = pHtmlNode
- ? this.$getLayoutNode("item", "container", pHtmlNode)
- : this.oInt;
- var container = this.$getLayoutNode("item", "container", htmlNode);
-
- if (pContainer != oPHtmlNode && this.getTraverseNodes(xmlNode.parentNode).length == 1)
- this.$removeClearMessage(pContainer);
-
- pContainer.insertBefore(htmlNode, beforeNode);
- pContainer.insertBefore(container, beforeNode);
-
- /*if (!this.startcollapsed) {
- pContainer.style.display = "block";
- pContainer.style.height = "auto";
- }*/
-
- if (this.emptyMessage && !oPHtmlNode.childNodes.length)
- this.$setClearMessage(oPHtmlNode);
-
- if (this.openadd && pHtmlNode != this.oInt && pContainer.style.display != "block")
- this.slideOpen(pContainer, pHtmlNode, true);
-
- //Fix look (tree thing)
- this.$fixItem(xmlNode, htmlNode);
- this.$fixItem(xmlNode.parentNode,
- jpf.xmldb.findHTMLNode(xmlNode.parentNode, this));
- if (this.getNextTraverse(xmlNode, true)) { //should use traverse here
- this.$fixItem(this.getNextTraverse(xmlNode, true),
- jpf.xmldb.findHTMLNode(this.getNextTraverse(xmlNode, true),
- this));
- }
- };
-
- this.$updateNode = function(xmlNode, htmlNode){
- var elIcon = this.$getLayoutNode("item", "icon", htmlNode);
- var iconURL = this.applyRuleSetOnNode("icon", xmlNode);
- if (elIcon && iconURL) {
- if (elIcon.tagName && elIcon.tagName.match(/^img$/i))
- elIcon.src = this.iconPath + iconURL;
- else
- elIcon.style.backgroundImage = "url(" + this.iconPath + iconURL + ")";
- }
-
- var elCaption = this.$getLayoutNode("item", "caption", htmlNode);
- if (elCaption) {
- /*if (elCaption.nodeType == 1)
- elCaption.innerHTML = this.applyRuleSetOnNode("caption", xmlNode);
- else
- elCaption.nodeValue = this.applyRuleSetOnNode("caption", xmlNode);*/
-
- if (elCaption.nodeType != 1)
- elCaption = elCaption.parentNode;
-
- elCaption.innerHTML = this.applyRuleSetOnNode("caption", xmlNode);
- }
-
- var strTooltip = this.applyRuleSetOnNode("tooltip", xmlNode);
- if (strTooltip)
- htmlNode.setAttribute("title", strTooltip);
-
- var cssClass = this.applyRuleSetOnNode("css", xmlNode);
- if (cssClass || this.dynCssClasses.length) {
- this.$setStyleClass(htmlNode, cssClass, this.dynCssClasses);
- if (cssClass && !this.dynCssClasses.contains(cssClass))
- this.dynCssClasses.push(cssClass);
- }
- };
-
- this.$setLoading = function(xmlNode, container){
- this.$getNewContext("loading");
- this.setLoadStatus(xmlNode, "potential");
- jpf.xmldb.htmlImport(this.$getLayoutNode("loading"), container);
- };
-
- this.$removeLoading = function(htmlNode){
- if (!htmlNode) return;
- this.$getLayoutNode("item", "container", htmlNode).innerHTML = "";
- };
-
- //check databinding for how this is normally implemented
- this.$extend = function(xmlNode, container){
- var rule = this.getNodeFromRule("insert", xmlNode, null, true);
- var xmlContext = rule
- ? xmlNode.selectSingleNode(rule.getAttribute("select") || ".")
- : null;
-
- if (rule && xmlContext) {
- this.setLoadStatus(xmlNode, "loading");
-
- if (rule.getAttribute("get")) {
- if (!jpf.offline.onLine) {
- jpf.offline.transactions.actionNotAllowed();
- this.slideClose(container, xmlNode);
- return;
- }
-
- this.getModel().insertFrom(rule.getAttribute("get"), xmlContext, {
- insertPoint : xmlContext,
- jmlNode : this
- });
- }
- else {
- var data = this.applyRuleSetOnNode("insert", xmlNode);
- if (data)
- this.insert(data, xmlContext);
- }
- }
- else if (!this.prerender) {
- this.setLoadStatus(xmlNode, "loading");
- this.$removeLoading(jpf.xmldb.findHTMLNode(xmlNode, this));
- var result = this.$addNodes(xmlNode, container, true); //checkChildren ???
- xmlUpdateHandler.call(this, {
- action : "insert",
- xmlNode : xmlNode,
- result : result,
- anim : true
- });
- }
- };
-
- function xmlUpdateHandler(e){
- /*
- Display the animation if the item added is
- * Not in the cache
- - Being insterted using xmlUpdate
- - there is at least 1 child inserted
- */
-
- if (e.action == "move-away")
- this.$fixItem(e.xmlNode, jpf.xmldb.findHTMLNode(e.xmlNode, this), true);
-
- if (e.action != "insert") return;
-
- var htmlNode = this.getNodeFromCache(e.xmlNode.getAttribute(
- jpf.xmldb.xmlIdTag) + "|" + this.uniqueId);
- if (!htmlNode) return;
-
- if (this.hasLoadStatus(e.xmlNode, "loading") && e.result.length > 0) {
- var container = this.$getLayoutNode("item", "container", htmlNode);
- this.slideOpen(container, e.xmlNode, e.anim ? false : true);
- }
- else
- this.$fixItem(e.xmlNode, htmlNode);
-
- //Can this be removed?? (because it was added in the insert function)
- if (this.hasLoadStatus(e.xmlNode, "loading"))
- this.setLoadStatus(e.xmlNode, "loaded");
- }
-
- this.addEventListener("xmlupdate", xmlUpdateHandler);
-
- /**** Keyboard Support ****/
-
- this.addEventListener("beforerename", function(){
- if (this.$tempsel) {
- clearTimeout(this.timer);
- this.select(this.$tempsel);
- this.$tempsel = null;
- this.timer = null;
- }
- });
-
- this.addEventListener("keydown", function(e){
- var key = e.keyCode;
- var ctrlKey = e.ctrlKey;
- var shiftKey = e.shiftKey;
- var selHtml = this.$indicator || this.$selected;
-
- if (!selHtml || this.renaming)
- return;
-
- var selXml = this.indicator || this.selected;
- var oExt = this.oExt;
-
- switch (key) {
- case 13:
- if (this.$tempsel)
- this.selectTemp();
-
- if (this.ctrlselect == "enter")
- this.select(this.indicator, true);
-
- this.choose(selHtml);
- break;
- case 32:
- //if (ctrlKey)
- this.select(this.indicator, true);
- break;
- case 46:
- if (this.$tempsel)
- this.selectTemp();
-
- //DELETE
- //this.remove();
- this.remove(this.mode ? this.indicator : null); //this.mode != "check"
- break;
- case 109:
- case 37:
- //LEFT
- if (this.$tempsel)
- this.selectTemp();
-
- if (this.indicator.selectSingleNode(this.traverse))
- this.slideToggle(this.$indicator || this.$selected, 2)
- break;
- case 107:
- case 39:
- //RIGHT
- if (this.$tempsel)
- this.selectTemp();
-
- if (this.indicator.selectSingleNode(this.traverse))
- this.slideToggle(this.$indicator || this.$selected, 1)
- break;
- case 187:
- //+
- if (shiftKey)
- arguments.callee(39);
- break;
- case 189:
- //-
- if (!shiftKey)
- arguments.callee(37);
- break;
- case 38:
- //UP
- if (!selXml && !this.$tempsel)
- return;
-
- var node = this.$tempsel
- ? jpf.xmldb.getNode(this.$tempsel)
- : selXml;
-
- var sNode = this.getNextTraverse(node, true);
- if (sNode) {
- var nodes = this.getTraverseNodes(sNode);
-
- do {
- var container = this.$getLayoutNode("item", "container",
- this.getNodeFromCache(jpf.xmldb.getID(sNode, this)));
- if (container && jpf.getStyle(container, "display") == "block"
- && nodes.length) {
- sNode = nodes[nodes.length-1];
- }
- else
- break;
- }
- while (sNode && (nodes = this.getTraverseNodes(sNode)).length);
- }
- else if (this.getTraverseParent(node) == this.xmlRoot) {
- this.dispatchEvent("selecttop");
- return;
- }
- else
- sNode = this.getTraverseParent(node);
-
- if (sNode && sNode.nodeType == 1)
- this.setTempSelected(sNode, ctrlKey, shiftKey);
-
- if (this.$tempsel && this.$tempsel.offsetTop < oExt.scrollTop)
- oExt.scrollTop = this.$tempsel.offsetTop;
-
- return false;
-
- break;
- case 40:
- //DOWN
- if (!selXml && !this.$tempsel)
- return;
-
- var node = this.$tempsel
- ? jpf.xmldb.getNode(this.$tempsel)
- : selXml;
-
- var sNode = this.getFirstTraverseNode(node);
- if (sNode) {
- var container = this.$getLayoutNode("item", "container",
- this.getNodeFromCache(jpf.xmldb.getID(node, this)));
- if (container && jpf.getStyle(container, "display") != "block")
- sNode = null;
- }
-
- while (!sNode) {
- var pNode = this.getTraverseParent(node);
- if (!pNode) break;
-
- var i = 0;
- var nodes = this.getTraverseNodes(pNode);
- while (nodes[i] && nodes[i] != node)
- i++;
- sNode = nodes[i+1];
- node = pNode;
- }
-
- if (sNode && sNode.nodeType == 1)
- this.setTempSelected(sNode, ctrlKey, shiftKey);
-
- if (this.$tempsel && this.$tempsel.offsetTop + this.$tempsel.offsetHeight
- > oExt.scrollTop + oExt.offsetHeight)
- oExt.scrollTop = this.$tempsel.offsetTop
- - oExt.offsetHeight + this.$tempsel.offsetHeight + 10;
-
- return false;
- break;
- case 33: //@todo
- //PGUP
- break;
- case 34: //@todo
- //PGDN
- break;
- case 36: //@todo
- //HOME
- break;
- case 35: //@todo
- //END
- break;
- }
- }, true);
-
- /**** Rename Support ****/
-
- this.$getCaptionElement = function(){
- var x = this.$getLayoutNode("item", "caption", this.$selected);
- return x.nodeType == 1 ? x : x.parentNode;
- };
-
- /**** Selection Support ****/
-
- this.$calcSelectRange = function(xmlStartNode, xmlEndNode){
- var r = [];
- var nodes = this.getTraverseNodes();
- for (var f = false, i = 0; i < nodes.length; i++) {
- if (nodes[i] == xmlStartNode)
- f = true;
- if (f)
- r.push(nodes[i]);
- if (nodes[i] == xmlEndNode)
- f = false;
- }
-
- if (!r.length || f) {
- r = [];
- for (var f = false, i = nodes.length - 1; i >= 0; i--) {
- if (nodes[i] == xmlStartNode)
- f = true;
- if (f)
- r.push(nodes[i]);
- if (nodes[i] == xmlEndNode)
- f = false;
- }
- }
-
- return r;
- }
-
- this.$findContainer = function(htmlNode){
- return this.$getLayoutNode("item", "container", htmlNode);
- };
-
- this.$selectDefault = function(xmlNode){
- if (this.select(this.getFirstTraverseNode(xmlNode)))
- return true;
- else {
- var nodes = this.getTraverseNodes(xmlNode);
- for (var i = 0; i < nodes.length; i++) {
- if (this.$selectDefault(nodes[i]))
- return true;
- }
- }
- };
-
- /**** Init ****/
-
- /**
- * @event click Fires when the user presses a mousebutton while over this element and then let's the mousebutton go.
- * @see baseclass.multiselect.event.beforeselect
- * @see baseclass.multiselect.event.afterselect
- * @see baseclass.multiselect.event.beforechoose
- * @see baseclass.multiselect.event.afterchoose
- */
- this.$draw = function(){
- if (!this.$jml.getAttribute("skin")) {
- var mode = this.$jml.getAttribute("mode");
- if (mode == "check")
- this.$loadSkin("default:checktree"); //@todo use getOption here
- else if (mode == "radio")
- this.$loadSkin("default:radiotree"); //@todo use getOption here
- }
-
- //Build Main Skin
- this.oExt = this.$getExternal();
- this.oInt = this.$getLayoutNode("main", "container", this.oExt);
- this.opencloseaction = this.$getOption("main", "openclose");
-
- //Need fix...
- //this.oExt.style.MozUserSelect = "none";
-
- if (jpf.hasCssUpdateScrollbarBug && !this.mode)
- this.$fixScrollBug();
-
- this.oExt.onclick = function(e){
- _self.dispatchEvent("click", {htmlEvent : e || event});
- };
- };
-
- this.$loadJml = function(x){
- if (this.nocollapse)
- this.startcollapsed = false;
- else if (this.startcollapsed === 1)
- this.startcollapsed = this.$getOption("main", "startcollapsed");
-
- if (this.$jml.childNodes.length)
- this.$loadInlineData(this.$jml);
- };
-
- this.$destroy = function(){
- this.oExt.onclick = null;
-
- jpf.removeNode(this.oDrag);
- this.oDrag = null;
- };
-}).implement(
- jpf.Validation,
- jpf.Rename,
- jpf.DragDrop,
-
- jpf.MultiSelect,
- jpf.Cache,
- jpf.Presentation,
- jpf.DataBinding
-);
-
- - -/*FILEHEAD(/var/lib/jpf/src/elements/browser.js)SIZE(-1077090856)TIME(1238944817)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * Element displaying the rendered contents of an URL.
- *
- * @constructor
- * @addnode elements:browser
- * @define browser
- *
- * @inherits jpf.JmlElement
- * @inherits jpf.Validation
- * @inherits jpf.XForms
- * @inherits jpf.DataBinding
- *
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.4
- *
- * @binding value Determines the way the value for the element is retrieved
- * from the bound data.
- * Example:
- * Sets the url based on data loaded into this component.
- * <code>
- * <j:browser>
- * <j:bindings>
- * <j:value select="@url" />
- * </j:bindings>
- * </j:browser>
- * </code>
- * Example:
- * A shorter way to write this is:
- * <code>
- * <j:colorpicker ref="@url" />
- * </code>
- */
-jpf.browser = jpf.component(jpf.NODE_VISIBLE, function(){
- /**
- * Retrieves the current url that is displayed.
- */
- this.getURL = function(){
- return this.oInt.src;
- };
-
- /**
- * Browses to the previous page
- */
- this.back = function(){
- this.oInt.contentWindow.history.back();
- };
-
- /**
- * Browses to the next page
- */
- this.forward = function(){
- this.oInt.contentWindow.history.forward();
- };
-
- /**
- * Reload the current page
- */
- this.reload = function(){
- this.oInt.src = this.oInt.src;
- };
-
- /**
- * Print the currently displayed page
- */
- this.print = function(){
- this.oInt.contentWindow.print();
- };
-
- /**
- * Execute a string of javascript on the page. This is subject to browser
- * security and will most likely only work when the browsed page is loaded
- * from the same domain.
- * @param {String} str javascript string to be executed.
- * @param {Boolean} noError whether the execution can throw an exception. Defaults to false.
- */
- this.runCode = function(str, noError){
- if (noError)
- try {
- this.oInt.contentWindow.eval(str);
- } catch(e) {}
- else
- this.oInt.contentWindow.eval(str);
- };
-
- /**
- * @attribute {String} src the url to be displayed in this element
- */
- this.$supportedProperties.push("value", "src");
- this.$propHandlers["src"] =
- this.$propHandlers["value"] = function(value, force){
- try {
- this.oInt.src = value || "about:blank";
- } catch(e) {
- this.oInt.src = "about:blank";
- }
- };
-
- this.$draw = function(parentNode){
- if (!parentNode)
- parentNode = this.pHtmlNode;
-
- //Build Main Skin
- if (jpf.cannotSizeIframe) {
- this.oExt = parentNode.appendChild(document.createElement("DIV"))
- .appendChild(document.createElement("iframe")).parentNode;//parentNode.appendChild(document.createElement("iframe"));//
- this.oExt.style.width = "100px";
- this.oExt.style.height = "100px";
- this.oInt = this.oExt.firstChild;
- //this.oInt = this.oExt;
- this.oInt.style.width = "100%";
- this.oInt.style.height = "100%";
- }
- else {
- this.oExt = parentNode.appendChild(document.createElement("iframe"));
- this.oExt.style.width = "100px";
- this.oExt.style.height = "100px";
- this.oInt = this.oExt;
- //this.oExt.style.border = "2px inset white";
- }
-
- //this.oInt = this.oExt.contentWindow.document.body;
- this.oExt.host = this;
- //this.oInt.host = this;
- };
-
- this.$loadJml = function(x){};
-}).implement(
- jpf.Validation,
- jpf.DataBinding
-);
- - -/*FILEHEAD(/var/lib/jpf/src/elements/draw.js)SIZE(-1077090856)TIME(1238933683)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-/**
- * @experimental
- */
-jpf.draw = jpf.component(jpf.NODE_VISIBLE, function() {
- var _self = this;
- engine = null;
- mode = "draw";
- this.properties = {
- shape : "rect",
- fill : "green", /* none */
- stroke : "red",
- strokeWidth : 1
- };
-
- this.$handlePropSet = function(prop, value) {
-
- }
-
- this.$draw = function() {
- //Build Main Skin
- this.oExt = this.$getExternal();
- }
- /* change drawed object */
- this.changeProperties = function(p) {
- for(var id in p){
- this.properties[id] = p[id];
- }
- }
-
- this.mode = function(m) {
- mode = m;
- }
-
- this.load = function(data) {
- if(jpf.supportSVG){
- var l = data.childNodes.length;
-
- for(var i = 0; i < l; i++){
- if(data.childNodes[i].nodeType == 1){
- engine.area.appendChild(data.childNodes[i].cloneNode(true));
- }
- }
- }
- }
-
- this.$loadJml = function(x) {
- this.chartType = x.getAttribute("type") || "linear2D";
-
- this.oInt = this.$getLayoutNode("main", "container", this.oExt);
-
- engine = jpf.supportSVG
- ? jpf.draw.svgDraw
- : jpf.draw.vmlDraw;
-
- engine.init(this, this.oInt);
-
- /* Events */
-
- var timer;
- engine.area.onmousedown = function(e) {
- var e = (e || event);
-
- var abs = jpf.getAbsolutePosition(_self.oInt);
- var sw = 0, sh = 0, sx = 0, sy = 0, cy = e.layerY - abs[1], cx = e.layerX - abs[0], x, y;
-
- var element = mode == "draw" ? new engine[_self.properties.shape](cx, cy) : engine.selected;
-
- var ox = parseInt(element.element.getAttribute("x"));
- var oy = parseInt(element.element.getAttribute("y"));
-
- clearInterval(timer);
- timer = setInterval(function() {
- if(mode == "draw") {
- element.redraw((sx || cx), (sy || cy), (sw || 1), (sh || 1));
- }
- else if(mode == "move") {
- element.move(ox + sx, oy + sy);
- }
- }, 10);
-
- engine.area.onmousemove = function(e) {
- var e = (e || event);
- y = e.layerY - abs[1];
- x = e.layerX - abs[0];
-
- sh = cy - y;
- sw = cx - x;
-
- sx = mode == "draw" ? (sw > 0 ? x : cx) : -1 * sw;
- sy = mode == "draw" ? (sh > 0 ? y : cy) : -1 * sh;
-
- sw = Math.abs(sw);
- sh = Math.abs(sh);
- }
-
- engine.area.onmouseup = function(e) {
- clearInterval(timer);
- engine.area.onmousemove = null;
- return false;
- }
- }
-
-
- engine.area.onclick = function(e) {
- var e = (e || event);
- }
- }
-}).implement(jpf.Presentation);
-
-jpf.draw.svgDraw = {
- object : null,
- area : null,
- container : null,
- selected : null,
- ns : "http://www.w3.org/2000/svg",
- xmlns : "http://www.w3.org/2000/xmlns/",
- id : 1,
- elements : {},
-
- init : function(object, container) {
- jpf.draw.svgDraw.object = object;
- jpf.draw.svgDraw.container = container;
-
- var svg = document.createElementNS(jpf.draw.svgDraw.ns, "svg:svg");
- svg.setAttribute("id", "drel"+jpf.draw.svgDraw.id++);
-
- svg.setAttribute("width", container.offsetWidth);
- svg.setAttribute("height", container.offsetHeight);
- svg.setAttribute("viewBox", "0 0 " + container.offsetWidth + " " + container.offsetHeight);
- svg.setAttributeNS(jpf.draw.svgDraw.xmlns, "xmlns:xlink", "http://www.w3.org/1999/xlink");
-
- container.appendChild(svg);
-
- jpf.draw.svgDraw.area = svg;
- },
-
- rect : function(x, y) {
- var s = jpf.draw.svgDraw;
- var p = s.object.properties;
- this.element = document.createElementNS(s.ns, "rect");
-
- this.element.setAttribute("id", "drel" + s.id++);
- this.element.setAttribute("x", x);
- this.element.setAttribute("y", y);
- this.element.setAttribute("width", 1);
- this.element.setAttribute("height", 1);
- this.element.setAttribute("fill", p.fill);
- this.element.setAttribute("stroke", p.stroke);
- this.element.setAttribute("stroke-width", p.strokeWidth);
-
- s.elements["drel" + s.id - 1] = this;
- s.area.appendChild(this.element);
- s.selected = this;
-
- this.redraw = function(x, y, w, h){
- this.element.setAttribute("x", x);
- this.element.setAttribute("y", y);
- this.element.setAttribute("width", w);
- this.element.setAttribute("height", h);
- }
-
- this.move = function(x, y){
- this.element.setAttribute("x", x);
- this.element.setAttribute("y", y);
- }
- }
-}
-
-jpf.draw.vmlDraw = {
- object : null,
- area : null,
- container : null,
- selected : null,
- id : 1,
- elements : {},
-
- init : function(object, container) {
- jpf.draw.vmlDraw.object = object;
- jpf.draw.vmlDraw.area = container;
-
- jpf.importCssString(document, "v\:* {behavior: url(#default#VML);}");
- },
-
- rect : function(x, y) {
- var element = '<v:rect style="width:100;height:100" fillcolor="red" strokecolor="blue"/>';
- jpf.draw.vmlDraw.area.innerHTML = element;
- }
-}
-
- - -/*FILEHEAD(/var/lib/jpf/src/elements/text.js)SIZE(-1077090856)TIME(1238933683)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -/** - * Element displaying a rectangle containing arbritrary (X)HTML. - * This element can be databound and use databounding rules to - * convert data into (X)HTML using for instance XSLT or JSLT. - * - * @constructor - * @define text - * @addnode elements - * - * @inherits jpf.Cache - * - * @author Ruben Daniels - * @version %I%, %G% - * @since 0.1 - * @todo Please refactor this object - */ -jpf.text = jpf.component(jpf.NODE_VISIBLE, function(){ - this.$focussable = true; // This object can't get the focus - this.focussable = false; - this.$hasStateMessages = true; - var _self = this; - - /**** Properties and Attributes ****/ - - /** - * @attribute {Boolean} scrolldown whether this elements viewport is always scrolled down. This is especially useful when this element is used to displayed streaming content such as a chat conversation. - * @attribute {Boolean} secure whether the content loaded in this element should be filtered in order for it to not be able to execute javascript. This is especially useful when the content does not come from a trusted source, like a web service or xmpp feed. - */ - this.$booleanProperties["scrolldown"] = true; - this.$booleanProperties["secure"] = true; - this.$supportedProperties.push("behavior", "scrolldown", "secure", "value"); - - /** - * @attribute {String} behaviour specifying how this elements handles new values - * Possible values - * normal new values replace the old value. - * addonly new values are added to the current value. - */ - this.$propHandlers["behavior"] = function(value){ - this.addOnly = value == "addonly"; - } - - /** - * @attribute {String} value the contents of this element. This can be text or html or xhtml. - */ - this.$propHandlers["value"] = function(value){ - var cacheObj = false; - - if (value) - this.$removeClearMessage(); - //@todo else - - if (typeof value != "string") - value = value ? value.toString() : ""; - - if (this.secure) { - value = value.replace(/<a /gi, "<a target='_blank' ") - .replace(/<object.*?\/object>/g, "") - .replace(/<script.*?\/script>/g, "") - .replace(new RegExp("ondblclick|onclick|onmouseover|onmouseout|onmousedown|onmousemove|onkeypress|onkeydown|onkeyup|onchange|onpropertychange", "g"), "ona") - } - - if (this.addOnly) { - if (cacheObj) - cacheObj.contents += value; - else - this.oInt.insertAdjacentHTML("beforeend", value); - } - else { - value = value.replace(/\<\?xml version="1\.0" encoding="UTF-16"\?\>/, ""); - - //var win = window.open(); - //win.document.write(value); - if (cacheObj) - cacheObj.contents = value; - else - this.oInt.innerHTML = value;//.replace(/<img[.\r\n]*?>/ig, "") - } - - //Iframe bug fix for IE (leaves screen white); - if (jpf.cannotSizeIframe && this.oIframe) - this.oIframe.style.width = this.oIframe.offsetWidth + "px"; - - if (this.scrolldown && this.$scrolldown) - this.oScroll.scrollTop = this.oScroll.scrollHeight; - }; - - /**** Public methods ****/ - - /** - * @copy Widget#setValue - */ - this.setValue = function(value){ - this.setProperty("value", value); - }; - - /** - * @copy Widget#getValue - */ - this.getValue = function(){ - return this.oInt.innerHTML; - }; - - /**** Keyboard Support ****/ - - this.addEventListener("keydown", function(e){ - var key = e.keyCode; - var ctrlKey = e.ctrlKey; - var shiftKey = e.shiftKey; - - switch (key) { - case 33: - //PGUP - this.oInt.scrollTop -= this.oInt.offsetHeight; - break; - case 34: - //PGDN - this.oInt.scrollTop += this.oInt.offsetHeight; - break; - case 35: - //END - this.oInt.scrollTop = this.oInt.scrollHeight; - break; - case 36: - //HOME - this.oInt.scrollTop = 0; - break; - case 38: - this.oInt.scrollTop -= 10; - break; - case 40: - this.oInt.scrollTop += 10; - break; - default: - return; - } - - return false; - }, true); - - /**** Private methods ****/ - - this.$xmlUpdate = function(action, xmlNode, listenNode, UndoObj){ - if (this.addOnly && action != "add") return; - - //Action Tracker Support - if (UndoObj) - UndoObj.xmlNode = this.addOnly ? xmlNode : this.xmlRoot;//(contents ? contents.xmlRoot : this.xmlRoot); - - //Refresh Properties - if (this.addOnly) { - jpf.xmldb.nodeConnect(this.documentId, xmlNode, null, this); - var cacheObj = this.getNodeFromCache(listenNode.getAttribute("id") - + "|" + this.uniqueId); - - this.$propHandlers["value"].call(this, - this.applyRuleSetOnNode("value", xmlNode) || ""); - } - else { - this.$propHandlers["value"].call(this, - this.applyRuleSetOnNode("value", this.xmlRoot) || ""); - } - }; - - this.$load = function(node){ - //Add listener to XMLRoot Node - jpf.xmldb.addNodeListener(node, this); - var value = this.applyRuleSetOnNode("value", node); - - if (value || typeof value == "string") { - if (this.caching) { - var cacheObj = this.getNodeFromCache(node.getAttribute("id") - + "|" + this.uniqueId); - if (cacheObj) - cacheObj.contents = value; - } - this.$propHandlers["value"].call(this, value); - } - else - this.$propHandlers["value"].call(this, ""); - }; - - this.$getCurrentFragment = function(){ - return { - nodeType : 1, - contents : this.oInt.innerHTML - } - }; - - this.$setCurrentFragment = function(fragment){ - this.oInt.innerHTML = fragment.contents; - if (this.scrolldown) - this.oInt.scrollTop = this.oInt.scrollHeight; - }; - - this.$findNode = function(cacheNode, id){ - id = id.split("\|"); - - if ((cacheNode ? cacheNode : this).xmlRoot - .selectSingleNode("descendant-or-self::node()[@id='" + (id[0]+"|"+id[1]) + "']")) - return (cacheNode ? cacheNode : null); - - return false; - }; - - var lastMsg; - this.$setClearMessage = this.$updateClearMessage = function(msg){ - this.$setStyleClass(this.oExt, this.baseCSSname + "Empty"); - - if (msg) { - this.oInt.innerHTML = msg; - lastMsg = this.oInt.innerHTML; - } - }; - - this.$removeClearMessage = function(){ - this.$setStyleClass(this.oExt, "", [this.baseCSSname + "Empty"]); - - if (this.oInt.innerHTML == lastMsg) - this.oInt.innerHTML = ""; //clear if no empty message is supported - }; - - this.$clear = function(){ - //this.oInt.innerHTML = "<div style='text-align:center;font-family:MS Sans Serif;font-size:8pt'>" + this.msg + "</div>"; - this.setProperty("value", ""); - }; - - this.caching = false; //Fix for now - - /**** Init ****/ - - this.$draw = function(){ - this.oExt = this.$getExternal(); - this.oInt = this.$getLayoutNode("main", "container", this.oExt); - - if (jpf.hasCssUpdateScrollbarBug && !jpf.getStyle(this.oInt, "padding")) - this.$fixScrollBug(); - - this.oScroll = this.oFocus ? this.oFocus.parentNode : this.oInt; - - this.$scrolldown = true; - this.oScroll.onscroll = function(){ - _self.$scrolldown = this.scrollTop >= this.scrollHeight - - this.offsetHeight + jpf.getVerBorders(this); - } - setInterval(function(){ - if (_self.$scrolldown && _self.scrolldown) { - _self.oScroll.scrollTop = _self.oScroll.scrollHeight; - } - }, 60); - - if (this.oInt.tagName.toLowerCase() == "iframe") { - if (jpf.isIE) { - this.oIframe = this.oInt; - var iStyle = this.skin.selectSingleNode("iframe_style"); - this.oIframe.contentWindow.document.write( - "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\ - <head>\ - <style>" + (iStyle ? iStyle.firstChild.nodeValue : "") + "</style>\ - <script>\ - document.onkeydown = function(e){\ - if (!e) e = event;\ - if (" + 'top.jpf.disableF5' + " && e.keyCode == 116) {\ - e.keyCode = 0;\ - return false;\ - }\ - }\ - </script>\ - </head>\ - <body oncontextmenu='return false'></body>"); - this.oInt = this.oIframe.contentWindow.document.body; - } - else { - var node = document.createElement("div"); - this.oExt.parentNode.replaceChild(node, this.oExt); - node.className = this.oExt.className; - this.oExt = this.oInt = node; - } - } - else { - this.oInt.onselectstart = function(e){ - (e ? e : event).cancelBubble = true; - } - - this.oInt.oncontextmenu = function(e){ - if (!this.host.contextmenus) - (e ? e : event).cancelBubble = true; - } - - this.oInt.style.cursor = ""; - - this.oInt.onmouseover = function(e){ - if (!self.STATUSBAR) return; - if (!e) - e = event; - - if (e.srcElement.tagName.toLowerCase() == "a") { - if (!this.lastStatus) - this.lastStatus = STATUSBAR.getStatus(); - STATUSBAR.status("icoLink.gif", e.srcElement.getAttribute("href")); - } - else if (this.lastStatus) { - STATUSBAR.status(this.lastStatus[0], this.lastStatus[1]); - this.lastStatus = false; - } - } - } - }; - - this.$loadJml = function(x){ - this.caching = false;// hack - - if (this.emptyMsg && !this.childNodes.length) - this.$setClearMessage(this.emptyMsg); - - if (jpf.xmldb.isOnlyChild(x.firstChild, [3,4])) - this.$handlePropSet("value", x.firstChild.nodeValue.trim()); - else - jpf.JmlParser.parseChildren(this.$jml, null, this); - }; - - this.$destroy = function(){ - jpf.removeNode(this.oDrag); - this.oDrag = null; - this.oIframe = null; - this.oScroll.onscoll = null; - this.oScroll = null; - this.oFocus = null; - }; -}).implement( - jpf.Cache, - jpf.BaseSimple -); - - - -/*FILEHEAD(/var/lib/jpf/src/elements/splitter.js)SIZE(-1077090856)TIME(1238933683)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -/** - * @constructor - * @private - */ - -jpf.splitter = function(pHtmlNode){ - jpf.register(this, "splitter", jpf.NODE_VISIBLE);/** @inherits jpf.Class */ - this.pHtmlNode = pHtmlNode || document.body; - this.pHtmlDoc = this.pHtmlNode.ownerDocument; - - var jmlNode = this; - this.$focussable = true; // This object can get the focus - - /* *********************** - Inheritance - ************************/ - this.inherit(jpf.Presentation); /** @inherits jpf.Presentation */ - - /* ******************************************************************** - PUBLIC METHODS - *********************************************************************/ - - this.update = function(){ - //Optimize this to not recalc for certain cases - var b = (this.type == "vertical") - ? { - fsize : "fwidth", - size : "width", - offsetPos : "offsetLeft", - offsetSize : "offsetWidth", - pos : "left" - } - : { - fsize : "fheight", - size : "height", - offsetPos : "offsetTop", - offsetSize : "offsetHeight", - pos : "top" - }; - - var jmlNode = this.refNode; - var htmlNode = this.refHtml; - - var v = jpf.layout.vars; - var oItem = this.oItem; - var needRecalc = false; - - var itemStart = htmlNode - ? htmlNode[b.offsetPos] - : v[b.pos + "_" + oItem.id]; - var itemSize = htmlNode - ? htmlNode[b.offsetSize] - : v[b.size + "_" + oItem.id]; - - var row = oItem.parent.children; - for (var z = 0, i = 0; i < row.length; i++) - if (!row[i][b.fsize]) - z++; - - if (!oItem[b.fsize] && z > 1) { - for (var rTotal = 0, rSize = 0, i = oItem.stackId + 1; i < row.length; i++) { - if (!row[i][b.fsize]) { - rTotal += row[i].weight || 1; - rSize += (row[i].node - ? row[i].oHtml[b.offsetSize] - : v[b.size + "_" + row[i].id]); - } - } - - var diff = this.oExt[b.offsetPos] - itemStart - itemSize; - var rEach = (rSize - diff)/rTotal; - - for (var i = 0; i < oItem.stackId; i++) { - if (!row[i][b.fsize]) - row[i].original.weight = (row[i].node - ? row[i].oHtml[b.offsetSize] - : v[b.size + "_" + row[i].id]) / rEach; - } - - oItem.original.weight = (itemSize + diff) / rEach - needRecalc = true; - } - else { - var isNumber = oItem[b.fsize] ? oItem[b.fsize].match(/^\d+$/) : false; - var isPercentage = oItem[b.fsize] ? oItem[b.fsize].match(/^([\d\.]+)\%$/) : false; - if (isNumber || isPercentage || !oItem[b.fsize]) { - var diff = this.oExt[b.offsetPos] - itemStart - itemSize; - var newHeight = this.oExt[b.offsetPos] - itemStart; - - for (var total = 0, size = 0, i = oItem.stackId + 1; i < row.length; i++) { - if (!row[i][b.fsize]) { - total += row[i].weight || 1; - size += (row[i].node - ? row[i].oHtml[b.offsetSize] - : v[b.size + "_" + row[i].id]); - } - } - - if (total > 0) { - var ratio = ((size-diff)/total)/(size/total); - for (var i = oItem.stackId + 1; i < row.length; i++) - row[i].original.weight = ratio * (row[i].weight || 1); - } - else { - for (var i = oItem.stackId + 1; i < row.length; i++) { - if (row[i][b.fsize].match(/^\d+$/)) { - //should check for max here as well - var nHeight = (row[i].node - ? row[i].oHtml[b.offsetSize] - : v[b.size + "_" + row[i].id]) - diff; - row[i].original[b.fsize] = "" + Math.max(0, nHeight, row[i].minheight || 0); - if (row[i][b.fsize] - nHeight != 0) - diff = row[i][b.fsize] - nHeight; - else - break; - } - else - if (row[i][b.fsize].match(/^([\d\.]+)\%$/)) { - var nHeight = (row[i].node - ? row[i].oHtml[b.offsetSize] - : v[b.size + "_" + row[i].id]) - diff; - row[i].original[b.fsize] = Math.max(0, - ((parseFloat(RegExp.$1) / (row[i].node - ? row[i].oHtml[b.offsetSize] - : v[b.size + "_" + row[i].id])) * nHeight)) + "%"; - //check fheight - break; - } - } - } - - if (oItem.original[b.fsize]) { - oItem.original[b.fsize] = isPercentage - ? ((parseFloat(isPercentage[1])/itemSize) * newHeight) + "%" - : "" + newHeight; - } - - //if(total > 0 || isPercentage) needRecalc = true; - needRecalc = true; - } - } - - if (needRecalc) { - /* - var l = jpf.layout.layouts[this.oExt.parentNode.getAttribute("id")]; - jpf.layout.compileAlignment(l.root); - jpf.layout.activateRules(this.oExt.parentNode); - - */ - - jpf.layout.compile(this.oExt.parentNode); - jpf.layout.activateRules(this.oExt.parentNode); - - if (jpf.hasSingleRszEvent) - jpf.layout.forceResize(); - - return; - } - - jpf.layout.forceResize(this.oExt.parentNode); - }; - - this.onmouseup = function(){ - jmlNode.$setStyleClass(jmlNode.oExt, "", ["moving"]); - - jpf.plane.hide(); - - jmlNode.update(); - jmlNode.$setStyleClass(document.body, "", ["n-resize", "w-resize"]); - - jpf.dragmode.clear(); - }; - - this.onmousemove = function(e){ - if(!e) e = event; - - if (jmlNode.type == "vertical") { - if (e.clientX >= 0) { - var pos = jpf.getAbsolutePosition(jmlNode.oExt.offsetParent); - jmlNode.oExt.style.left = (Math.min(jmlNode.max, - Math.max(jmlNode.min, (e.clientX - pos[0]) - jmlNode.tx))) + "px"; - } - } - else { - if (e.clientY >= 0) { - var pos = jpf.getAbsolutePosition(jmlNode.oExt.offsetParent); - jmlNode.oExt.style.top = (Math.min(jmlNode.max, - Math.max(jmlNode.min, (e.clientY - pos[1]) - jmlNode.ty))) + "px"; - } - } - - e.returnValue = false; - e.cancelBubble = true; - }; - - /* ********* - INIT - **********/ - //this.inherit(jpf.JmlElement); /** @inherits jpf.JmlElement */ - - var lastinit, sizeArr, verdiff, hordiff; - this.init = function(size, refNode, oItem){ - /*var li = size + min + max + (refNode.uniqueId || refNode); - if(li == lastinit) return; - lastinit = li;*/ - this.min = 0; - this.max = 1000000; - this.size = parseInt(size) || 3; - this.refNode = null; - this.refHtml = null; - - var pNode; - if (refNode) { - if (typeof refNode != "object") - refNode = jpf.lookup(refNode); - this.refNode = refNode; - this.refHtml = this.refNode.oExt; - pNode = this.refHtml.parentNode; - - oItem = refNode.aData.calcData; - } - else - pNode = oItem.pHtml; - - this.oItem = oItem; - if (pNode && pNode != this.oExt.parentNode) - pNode.appendChild(this.oExt); - - var diff = jpf.getDiff(this.oExt); - verdiff = diff[0]; - hordiff = diff[1]; - sizeArr = []; - - this.type = oItem.parent.vbox ? "horizontal" : "vertical"; - - var layout = jpf.layout.get(this.oExt.parentNode).layout; - var name = "splitter" + this.uniqueId; - layout.addRule("var " + name + " = jpf.lookup(" + this.uniqueId + ").oExt"); - - var vleft = [name + ".style.left = "]; - var vtop = [name + ".style.top = "]; - var vwidth = [name + ".style.width = -" + hordiff + " + "]; - var vheight = [name + ".style.height = -" + verdiff + " + "]; - var oNext = oItem.parent.children[oItem.stackId+1]; - - if (this.type == "horizontal") { - vwidth.push("Math.max("); - if (oItem.node) { - vleft.push(oItem.id + ".offsetLeft"); - vtop.push(oItem.id + ".offsetTop + " + oItem.id + ".offsetHeight"); - vwidth.push(oItem.id + ".offsetWidth"); - } - else { - vleft.push("v.left_" + oItem.id); - vtop.push("v.top_" + oItem.id + " + v.height_" + oItem.id); - vwidth.push("v.width_" + oItem.id); - } - vwidth.push(",", oNext - ? (oNext.node - ? oNext.id + ".offsetWidth" - : "v.width_" + oNext.id) - : 0, ")"); - - layout.addRule(vwidth.join("")); - this.oExt.style.height = (oItem.splitter - hordiff) + "px"; - } - else { - vheight.push("Math.max("); - if (oItem.node) { - vleft.push(oItem.id + ".offsetLeft + " + oItem.id + ".offsetWidth"); - vtop.push(oItem.id + ".offsetTop"); - vheight.push(oItem.id + ".offsetHeight"); - } - else { - vleft.push("v.left_" + oItem.id + " + v.width_" + oItem.id); - vtop.push("v.top_" + oItem.id); - vheight.push("v.height_" + oItem.id); - } - vheight.push(",", oNext - ? (oNext.node - ? oNext.id + ".offsetHeight" - : "v.height_" + oNext.id) - : 0, ")"); - - layout.addRule(vheight.join("")); - this.oExt.style.width = (oItem.splitter - hordiff) + "px"; - } - - layout.addRule(vleft.join("")); - layout.addRule(vtop.join("")); - - //if(!jpf.p) jpf.p = new jpf.ProfilerClass(); - //jpf.p.start(); - - //Determine min and max - var row = oItem.parent.children; - if (this.type == "vertical") { - layout.addRule(name + ".host.min = " + (oItem.node - ? "document.getElementById('" + oItem.id + "').offsetLeft" - : "v.left_" + oItem.id) + " + " - + parseInt(oItem.minwidth || oItem.childminwidth || 10)); - - var max = [], extra = []; - for (var hasRest = false, i = oItem.stackId + 1; i < row.length; i++) { - if (!row[i].fwidth) - hasRest = true; - } - - for (var d, i = oItem.stackId + 1; i < row.length; i++) { - d = row[i]; - - //should take care here of minwidth due to html padding and html borders - if (d.minwidth || d.childminheight) - max.push(parseInt(d.minwidth || d.childminheight)); - else - if (d.fwidth) { - if (!hasRest && i == oItem.stackId+1) - max.push(10); - else - if(d.fwidth.indexOf("%") != -1) - max.push("(" + d.parent.innerspace + ") * " - + (parseFloat(d.fwidth)/100)); - else - max.push(d.fwidth); - } - else - max.push(10); - - max.push(d.edgeMargin); - } - - layout.addRule(name + ".host.max = v.left_" + oItem.parent.id - + " + v.width_" + oItem.parent.id + " - (" - + (max.join("+")||0) + ")"); - } - else { - layout.addRule(name + ".host.min = " + (oItem.node - ? "document.getElementById('" + oItem.id + "').offsetTop" - : "v.top_" + oItem.id) + " + " - + parseInt(oItem.minheight || oItem.childminheight || 10)); - - var max = [], extra = []; - for (var hasRest = false, i = oItem.stackId + 1; i < row.length; i++) { - if (!row[i].fheight) - hasRest = true; - } - - //This line prevents splitters from sizing minimized items without a rest - if (!hasRest && oNext && oNext.state > 0) - return this.oExt.parentNode.removeChild(this.oExt); - - for (var d, i = oItem.stackId + 1; i < row.length; i++) { - d = row[i]; - - //should take care here of minwidth due to html padding and html borders - if (d.minheight || d.childminheight) - max.push(parseInt(d.minheight || d.childminheight)); - else if (d.fheight) { - if (!hasRest && i == oItem.stackId+1) - max.push(10); - else if(d.fheight.indexOf("%") != -1) - max.push("(" + d.parent.innerspace + ") * " - + (parseFloat(d.fheight)/100)); - else - max.push(d.fheight); - } - else - max.push(10); - - if (d.edgeMargin) - max.push(d.edgeMargin); - } - - layout.addRule(name + ".host.max = v.top_" + oItem.parent.id - + " + v.height_" + oItem.parent.id + " - (" - + (max.join("+")||0) + ")"); - } - - //jpf.p.stop(); - //document.title = jpf.p.totalTime; - - this.$setStyleClass(this.oExt, this.type, - [this.type == "horizontal" ? "vertical" : "horizontal"]); - - if (this.type == "vertical") - this.$setStyleClass(this.oExt, "w-resize", ["n-resize"]); - else - this.$setStyleClass(this.oExt, "n-resize", ["w-resize"]); - - return this; - }; - - this.$draw = function(){ - //Build Main Skin - this.oExt = this.$getExternal(); - - this.oExt.onmousedown = function(e){ - if (!e) - e = event; - - var pos = jpf.getAbsolutePosition(this); - if (jmlNode.type == "vertical") - jmlNode.tx = e.clientX - pos[0]; - else - jmlNode.ty = e.clientY - pos[1]; - jmlNode.startPos = jmlNode.type == "vertical" - ? this.offsetLeft - : this.offsetTop; - - e.returnValue = false; - e.cancelBubble = true; - - jpf.plane.show(this); - - jmlNode.$setStyleClass(this, "moving"); - - jmlNode.$setStyleClass(document.body, - jmlNode.type == "vertical" ? "w-resize" : "n-resize", - [jmlNode.type == "vertical" ? "n-resize" : "w-resize"]); - jpf.dragmode.setMode("splitter" + jmlNode.uniqueId); - } - }; - - this.$loadJml = function(x){ - if (x.getAttribute("left") || x.getAttribute("top")) { - var O1 = x.getAttribute("left") || x.getAttribute("top"); - var O2 = x.getAttribute("right") || x.getAttribute("bottom"); - O1 = O1.split(/\s*,\s*/); - O2 = O2.split(/\s*,\s*/); - - for (var i = 0; i < O1.length; i++) - O1[i] = O1[i]; - for (var i = 0; i < O2.length; i++) - O2[i] = O2[i]; - - //Not a perfect hack, but ok, for now - setTimeout(function(){ - jmlNode.init(x.getAttribute("type"), - x.getAttribute("size"), - x.getAttribute("min"), - x.getAttribute("max"), - x.getAttribute("change"), O1, O2); - }); - } - }; - - jpf.plane.init(); - jpf.dragmode.defineMode("splitter" + this.uniqueId, this); - - this.$destroy = function(){ - jpf.dragmode.removeMode("splitter" + this.uniqueId); - }; -}; - - -/*FILEHEAD(/var/lib/jpf/src/elements/bar.js)SIZE(-1077090856)TIME(1238933683)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * Element displaying a skinnable rectangle which can contain other
- * jml elements. This element is used by other elements such as the
- * toolbar and statusbar element to specify sections within those elements
- * which in turn can contain other jml elements.
- *
- * @constructor
- *
- * @define bar, panel, menubar
- * @attribute {String} icon the url pointing to the icon image.
- * @allowchild button
- * @allowchild {elements}, {anyjml}
- * @addnode elements
- *
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.4
- */
-jpf.panel =
-jpf.bar = jpf.component(jpf.NODE_VISIBLE, function(){
- this.canHaveChildren = true;
- this.$focussable = false;
-
- this.$domHandlers["reparent"].push(
- function(beforeNode, pNode, withinParent){
- if (!this.$jmlLoaded)
- return;
-
- if (isUsingParentSkin && !withinParent
- && this.skinName != pNode.skinName
- || !isUsingParentSkin
- && this.parentNode.$hasLayoutNode
- && this.parentNode.$hasLayoutNode(this.tagName)) {
- isUsingParentSkin = true; - this.$forceSkinChange(this.parentNode.skinName.split(":")[0] + ":" + skinName);
- }
- });
-
- var isUsingParentSkin = false;
- this.$draw = function(){
- if (this.parentNode && this.parentNode.$hasLayoutNode
- && this.parentNode.$hasLayoutNode(this.tagName)) {
- isUsingParentSkin = true;
- if (this.skinName != this.parentNode.skinName)
- this.$loadSkin(this.parentNode.skinName);
- }
- else if(isUsingParentSkin){
- isUsingParentSkin = false;
- this.$loadSkin();
- }
-
- //Build Main Skin
- this.oExt = this.$getExternal(isUsingParentSkin
- ? this.tagName
- : "main");
-
- //Draggable area support, mostly for j:toolbar
- if (this.oDrag) //Remove if already exist (skin change)
- this.oDrag.parentNode.removeChild(this.oDrag);
-
- this.oDrag = this.$getLayoutNode(isUsingParentSkin
- ? this.tagName
- : "main", "dragger", this.oExt);
- };
-
- this.$loadJml = function(x){
- var oInt = this.$getLayoutNode(isUsingParentSkin
- ? this.tagName
- : "main", "container", this.oExt);
-
- this.oInt = this.oInt
- ? jpf.JmlParser.replaceNode(oInt, this.oInt)
- : jpf.JmlParser.parseChildren(x, oInt, this);
- };
-
- this.$skinchange = function(){ - - } -}).implement(jpf.Presentation);
-
- - -/*FILEHEAD(/var/lib/jpf/src/elements/upload.js)SIZE(-1077090856)TIME(1238944817)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - -/** - * Element allowing the user to upload a file to a server. When the file is - * being uploaded this element shows a virtual progressbar. The element - * can also provides a visual representation of the uploaded file depending on - * the skin. - * Example: - * This example shows an upload element that pushes an image to the server. The - * asp script returns an xml string which is added to the list of images on a - * successfull upload. - * <code> - * <j:list id="lstImages" smartbinding="..." model="..." /> - * - * <j:upload id="flLogoUpload" - * target = "../api/UploadPicture.asp" - * ontimeout = "alert('It seems the server went away')" - * oncancel = "alert('Could not upload logo')" - * onreceive = "lstImages.add(arguments[0])" /> - * </code> - * - * @event afterbrowse Fires after the user has made a selection. - * object: - * {String} value the path of the file selected - * - * @constructor - * @alias upload - * @addnode elements - * - * @inherits jpf.DataBinding - * @inherits jpf.Presentation - * - * @author Ruben Daniels - * @version %I%, %G% - * @since 0.4 - * - * @binding value Determines the way the value for the element is retrieved - * from the bound data. - * Example: - * Sets the value based on data loaded into this component. - * <code> - * <j:upload> - * <j:bindings> - * <j:value select="@filename" /> - * </j:bindings> - * </j:upload> - * </code> - * Example: - * A shorter way to write this is: - * <code> - * <j:upload ref="@filename" /> - * </code> - * - * @todo get server side information to update the progressbar. - */ - -jpf.upload = jpf.component(jpf.NODE_VISIBLE, function(){ - this.$focussable = false; - var _self = this; - - /**** Properties and attributes ****/ - - this.timeout = 100000; - - /** - * @attribute {String} value the path of the file to uploaded, or the online path after upload. - * @attribute {Boolean} target the url the form is posted to. - * @attribute {Number} !progress the position of the progressbar indicating the position in the upload process. - * @attribute {Boolean} !uploading whether this upload element is uploading. - * Example: - * When the skin doesn't have a progressbar you can use property binding to - * update a seperate or central progressbar. - * <code> - * <j:upload id="upExample" /> - * <j:progressbar value="{upExample.progress}" /> - * </code> - */ - this.$supportedProperties.push("value", "target", "progress", "uploading"); - - this.$propHandlers["value"] = function(value){ - if (!this.value) - this.old_value = value; - this.value = value; - - /* - if (this.oLabel.nodeType == 1) - this.oLabel.innerHTML = value; - else - this.oLabel.nodeValue = value; - */ - }; - - this.$propHandlers["target"] = function(value){ - if (this.form) - this.form.setAttribute("action", value); - } - - /**** Public methods ****/ - - - /** - * Sets the icon of the button - * @param {String} url the location of the image to be used as an icon - */ - this.setIcon = function(url){ - this.setProperty("icon", url); - }; - - /** - * Sets the caption of the button - * @param {String} value the text displayed on the button - */ - this.setCaption = function(value){ - this.setProperty("caption", value); - }; - - - /** - * @ref global#getValue - * @todo set these global descriptions - */ - this.getValue = function(){ - return this.value; - }; - - /** - * @ref global#setValue - * @todo set these global descriptions - */ - this.setValue = function(value){ - this.setProperty("value", value); - }; - - /** - * Opens the browse window which allows the user to choose a file to upload. - */ - this.browse = function(){ - if (this.disabled) - return; - - this.inpFile.click(); - //this.$startUpload(); - - if (this.inpFile.value != this.value) { - this.setProperty("value", this.inpFile.value); - this.dispatchEvent("afterbrowse", {value: this.value}); - } - }; - - this.upload = function(){ - if (this.value != this.inpFile.value || !this.inpFile.value) - return; - - this.old_value = this.value; - this.value = this.inpFile.value; - this.setValue(this.value); - - this.$upload(); - }; - - /** - * Cancels the upload process - * @param {String} msg the reason why the process was cancelled. - */ - this.cancel = function(msg){ - return this.$cancel(msg); - } - - /** - * Sets the target frame to which the form is posted - * @param {String} target the name of the frame receiving the form post. - */ - this.setTarget = function(target){ - this.target = target; - this.$initForm(); - }; - - /**** Private state handling methods ****/ - - this.$updateProgress = function(){ - //@todo use getDiff here - /*this.setProperty("progress", - this.oSlider.offsetWidth / this.oSlider.parentNode.offsetWith);*/ - }; - - this.$upload = function(){ - this.$uploading = true; - - //this.$disableEvents(); - //this.oCaption.nodeValue = "Uploading..."; - this.setProperty("uploading", true); - - //@todo ass possibility for real progress indication - this.timer = setInterval('jpf.lookup(' + this.uniqueId + ').$updateProgress()', 800); - this.timeout_timer = setTimeout('jpf.lookup(' + this.uniqueId + ').$timeout()', this.timeout); - this.form.submit(); - }; - - /** - * @event receive Fires when the upload succeeded, was cancelled or failed. - * object: - * {String} data the data that was returned by the upload post. - */ - this.$done = function(data){ - window.clearInterval(this.timer); - window.clearInterval(this.timeout_timer); - window.setTimeout('jpf.lookup(' + this.uniqueId + ').$clearProgress()', 300); - - //if (value) - // this.setValue(value); - this.old_value = null; - - //if(caption) - //this.setCaption(this.lastCaption); - - this.data = data; - - this.dispatchEvent("receive", { - data: data - }); - - this.$initForm(); - this.$uploading = false; - }; - - this.$cancel = function(value, caption){ - window.clearInterval(this.timer); - window.clearInterval(this.timeout_timer); - this.$clearProgress(); - - //this.setCaption(this.lastCaption); - if (this.old_value) - this.setValue(this.old_value); - this.old_value = null; - - this.dispatchEvent("cancel", { - returnValue: value - }); - - this.$initForm(); - this.$uploading = false; - }; - - /** - * @event timeout Fires when the upload timed out. - */ - this.$timeout = function(){ - clearInterval(this.timer); - clearInterval(this.timeout_timer); - - /*this.oCaption.nodeValue = this.$jml.firstChild - ? this.$jml.firstChild.nodeValue - : "";*/ - this.$clearProgress(); - - if (this.old_value) - this.setValue(this.old_value); - this.old_value = null; - - this.dispatchEvent("timeout"); - - this.$initForm(); - this.$uploading = false; - }; - - this.$clearProgress = function(){ - this.setProperty("progress", 0); - this.setProperty("uploading", false); - }; - - /**** Event handling ****/ - - this.$initForm = function(){ - if (jpf.isIE) { - this.oFrame.contentWindow.document.write("<body></body>"); - this.form = jpf.xmldb.htmlImport(this.$getLayoutNode("form"), - this.oFrame.contentWindow.document.body); - } - - //this.form = this.$getLayoutNode("main", "form", this.oExt); - this.form.setAttribute("action", this.target); - this.form.setAttribute("target", "upload" + this.uniqueId); - this.$getLayoutNode("form", "inp_uid", this.form) - .setAttribute("value", this.uniqueId); - this.inpFile = this.$getLayoutNode("form", "inp_file", this.form); - - var jmlNode = this; - this.inpFile.onchange = function(){ - //jmlNode.$startUpload(); - } - - if (jpf.debug == 2) { - this.oFrame.style.visibility = "visible"; - this.oFrame.style.width = "100px"; - this.oFrame.style.height = "100px"; - } - }; - - /** - * @event beforereceive Fires before data is received. - * cancellabel: Prevents the data from being received. - * object: - * {String} data the data that was returned by the upload post. - * {HTMLFrameElement} frame the iframe serving as the target to the form post. - */ - this.$draw = function(){ - //Build Main Skin - this.oExt = this.$getExternal("main", null, function(oExt){ - oExt.appendChild(oExt.ownerDocument.createElement("iframe")) - .setAttribute("name", "upload" + this.uniqueId); - }); - - if (!jpf.isIE) - this.form = jpf.xmldb.htmlImport( - this.$getLayoutNode("form"), this.oExt); - - this.oFrame = this.oExt.getElementsByTagName("iframe")[0]; - jpf.AbstractEvent.addListener(this.oFrame, "load", function(){ - if (!_self.uploading) - return; - - var data = ""; - try{ - data = jpf.html_entity_decode(_self.oFrame.contentWindow.document.body.innerHTML.replace(/<PRE>|<\/PRE>/g, "")); - } - catch(e){} - - var hasFailed = _self.dispatchEvent("beforereceive", { - data : data, - frame : _self.oFrame - } === false); - - if (hasFailed) - _self.$cancel(); - else - _self.$done(data); - }); - - jpf.AbstractEvent.addListener(this.oFrame, "error", function(){ - if (!_self.uploading) - return; - - _self.$cancel(); - }); - }; - - this.$loadJml = function(x){ - this.bgswitch = x.getAttribute("bgswitch") ? true : false; - if (this.bgswitch) { - this.$getLayoutNode("main", "background", this.oExt) - .style.backgroundImage = "url(" + this.mediaPath - + x.getAttribute("bgswitch") + ")"; - this.$getLayoutNode("main", "background", this.oExt) - .style.backgroundRepeat = "no-repeat"; - } - - this.$initForm(); - }; - - this.$destroy = function(){ - this.oFrame.onload = null; - }; -}).implement( - jpf.DataBinding, - jpf.Presentation -); - - -/*FILEHEAD(/var/lib/jpf/src/elements/flowchart.js)SIZE(-1077090856)TIME(1238944817)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - -/** - * Element is implementing adding and removing block elements. - * Every block could be rotated, flipped, resized, renamed, locked and moved. - * It's possible to add connections between them. - * - * Example: - * Flowchart element: - * <code> - * <j:flowchart id="WF" template="url:template.xml" model="modelName"> - * <j:css default="red" /> - * <j:bindings> - * <j:move select = "self::node()[not(@move='0') and not(@lock='1')]" /> - * <j:resize select = "self::node()[@resize='1' and not(@lock='1')]" /> - * <j:css select = "self::node()[@lock='1']" default="locked"/> - * <j:left select = "@left" /> - * <j:top select = "@top" /> - * <j:id select = "@id" /> - * <j:width select = "@width" /> - * <j:height select = "@height" /> - * <j:flipv select = "@flipv" /> - * <j:fliph select = "@fliph" /> - * <j:rotation select = "@rotation" /> - * <j:lock select = "@lock" /> - * <j:type select = "@type" /> - * <j:type value = "" /> - * <j:zindex select = "@zindex" /> - * <j:image select = "@src" /> - * <j:traverse select="block" /> - * - * <!-- Connection Binding Rules --> - * <j:connection select = "connection" /> - * <j:ref select = "@ref" /> - * <j:input select = "@input" /> - * <j:output select = "@output" /> - * <j:ttype select = "@type" /> - * </j:bindings> - * </j:flowchart> - * </code> - * - * Example: - * Flowchat model - * <code> - * <j:model id="modelName" save-original="true"> - * <flowchart> - * <block id="b1" type="current_source_cc" left="500" top="520" width="56" height="56" lock="false" flipv="true" fliph="false"></block> - * <block id="b5" type="mosfet_p" left="800" top="400" width="56" height="56" lock="0"> - * <connection ref="b1" output="3" input="3" /> - * </block> - * </flowchart> - * </j:model> - * </code> - * - * @define flowchart - * @attribute {String} template the data instruction to load the xml for the - * template that defines all the elements which are available in the flowchart. - * Example: - * A template describing a single transistor element - * <code> - * <template> - * <element type="capacitor" - * picture = "elements/capacitor.png" - * dwidth = "56" - * dheight = "56" - * scaley = "false" - * scalex = "false" - * scaleration = "true"> - * <input x="28" y="0" position="top" name="1" /> - * <input x="28" y="56" position="bottom" name="2" /> - * </element> - * </template> - * </code> - * - * @binding lock prohibit block move, default is false. - * Possible values: - * false block element is unlocled - * true block element is locked - * @binding fliph whether to mirror the block over the horizontal axis, default is false - * Possible values: - * true block element is flipped - * false block element is not flipped - * @binding flipv whether to mirror the block over the vertical axis, default is false - * Possible values: - * true block element is flipped - * false block element is not flipped - * @binding rotation the rotation in degrees clockwise, default is 0 - * Possible values: - * 0 0 degrees rotation - * 90 90 degrees rotation - * 180 180 degrees rotation - * 270 270 degrees rotation - * @binding id unique block element name - * @binding image path to block image file - * @binding width block element horizontal size - * @binding height block element vertical size - * @binding type name of block with special abilities, which could be set in template file - * @binding ttype relation to block with special abilities defined in template file - * @binding zindex block's z-index number - * @binding left horizontal position of block element - * @binding top vertical position of block element - * @binding connection xml representation of connection element - * @binding ref unique name of destination block which will be connected with source block - * @binding input source block input number - * @binding output destination block input number - * - * @constructor - * - * @inherits jpf.Presentation - * @inherits jpf.DataBinding - * @inherits jpf.Cache - * @inherits jpf.MultiSelect - * @inherits jpf.BaseList - * @inherits jpf.Rename - * - * @author Lukasz Lipinski - * @version %I%, %G% - */ -jpf.flowchart = jpf.component(jpf.NODE_VISIBLE, function() { - this.objCanvas; - this.nodes = []; - - lastBlockId = 0; - - template = null; - //torename = null; - resizeManager = null; - - xmlBlocks = {}; - objBlocks = {}; - xmlConnections = {}; - connToPaint = []; - - var _self = this; - - var onkeydown_ = function(e) { - e = (e || event); - - var key = e.keyCode, - ctrlKey = e.ctrlKey, - shiftKey = e.shiftKey, - sel = this.getSelection(), - value = (ctrlKey ? 10 : (shiftKey ? 100 : 1)); - var disabled = _self.objCanvas.disableremove; - - if (!sel || disabled) - return; - - if (!key && shiftKey) { - resizeManager - } - - switch (key) { - case 37: - //Left Arrow - this.moveTo(sel, - value, 0); - break; - case 38: - //Top Arrow - this.moveTo(sel, 0, - value); - break; - case 39: - //Right Arrow - this.moveTo(sel, value, 0); - break; - case 40: - //Bottom Arrow - this.moveTo(sel, 0, value); - break; - case 46: - //Delete - resizeManager.hide(); - - switch (_self.objCanvas.mode) { - case "normal": - //Removing Blocks - this.removeBlocks(sel); - break; - case "connection-change": - //Removing Connections - var connectionsToDelete = [], - connectors = _self.objCanvas.htmlConnectors; - for (var id in connectors) { - if (connectors[id].selected) { - connectionsToDelete.push(connectors[id].other.xmlNode); - connectors[id].destroy(); - } - } - _self.removeConnectors(connectionsToDelete); - _self.objCanvas.mode = "normal"; - break; - } - break; - } - - return false; - } - - this.addEventListener("onkeydown", onkeydown_, true); - - jpf.addEventListener("contextmenu", function() {return false;}); - - this.$getCaptionElement = function() { - var objBlock = objBlocks[this.applyRuleSetOnNode("id", this.selected)]; - if (!objBlock) - return; - return objBlock.caption; - }; - - this.$beforeRename = function(e) { - e = e || event; - var target = e.srcElement || e.target; - _self.$selectCaption(target); - - _self.objCanvas.disableremove = true; - _self.$deselectCaption(target); - _self.startRename(); - - var rename_input = this.pHtmlDoc.getElementById("txt_rename"); - this.$setStyleClass(rename_input, target.className); - - var c = rename_input; - if ((target.className || "").indexOf("inside") != -1) { - if (c.offsetHeight !== 0) { - - c.style.marginTop = - "-" + (Math.ceil(c.offsetHeight / 2)) + "px"; - } - } - - return false; - } - - function $afterRenameMode() { - _self.objCanvas.disableremove = false; - } - this.addEventListener("afterrename", $afterRenameMode); - this.addEventListener("stoprename", $afterRenameMode); - - this.$selectCaption = function(o) { - this.$setStyleClass(o, "selected"); - } - - this.$deselectCaption = function(o) { - this.$setStyleClass(o, "", ["selected"]); - } - - this.$select = function(o) { - if (!o) - return; - - var objBlock = jpf.flow.isBlock(o); - - if (objBlock) { - if (resizeManager) { - var prop = objBlock.other; - - if (prop.lock == 1) - return; - - var scales = { - scalex : prop.scalex, - scaley : prop.scaley, - scaleratio : prop.scaleratio, - dwidth : prop.dwidth, - dheight : prop.dheight, - ratio : prop.ratio - } - - resizeManager.grab(o, scales); - } - this.$setStyleClass(o, "selected"); - - if (objBlock.other.capPos !== "inside") { - _self.$selectCaption(objBlock.caption); - } - } - }; - - this.$deselect = function(o) { - if (!o) - return; - this.$setStyleClass(o, "", ["selected"]); - - var objBlock = jpf.flow.isBlock(o); - this.$deselectCaption(objBlock.caption); - - resizeManager.hide(); - }; - - /* ******************************************************************** - PUBLIC METHODS - *********************************************************************/ - - /** - * Moves block to new x, y position and update his xmlNode. This is an - * action. It's possible to return to previous state with Undo/Redo. - * - * @param {Object} xmlNodeArray xml representations of blocks elements list - * @param {Number} dl New horizontal coordinate - * @param {Number} dt New vertical coordinate - */ - this.moveTo = function(xmlNodeArray, dl, dt) { - if (!xmlNodeArray.length) { - xmlNodeArray = [xmlNodeArray]; - } -//jpf.flow.alert_r(xmlNodeArray[0]) - - var props = changes = []; - var setNames = ["top", "left"]; - - for (var i = 0, l = xmlNodeArray.length; i < l; i++) { - for (var j = 0; j < setNames.length; j++) { - var node = this.getNodeFromRule(setNames[j], xmlNodeArray[i], false, false, this.createModel), - value = (setNames[j] == "left" ? dl : dt) + (parseInt(this.applyRuleSetOnNode(setNames[j], xmlNodeArray[i])) || 0); -//alert((setNames[j] == "left" ? dl : dt) + (parseInt(this.applyRuleSetOnNode(setNames[j], xmlNodeArray[i])) || 0)) - if (node) { - var atAction = node.nodeType == 1 || node.nodeType == 3 - || node.nodeType == 4 - ? "setTextNode" - : "setAttribute"; - var args = node.nodeType == 1 - ? [node, value] - : (node.nodeType == 3 || node.nodeType == 4 - ? [node.parentNode, value] - : [node.ownerElement || node.selectSingleNode(".."), - node.nodeName, value]); - changes.push({ - func: atAction, - args: args - }); - } - } - } -//jpf.flow.alert_r(changes[0].args[1]+" "+changes[0].args[2]); -//jpf.flow.alert_r(changes[1].args[1]+" "+changes[1].args[2]); - this.executeAction("multicall", changes, "moveTo", xmlNodeArray); - }; - - /** - * Set to block xmlNode new z-index propertie. This is an action. It's - * possible to return to previous state with Undo/Redo. - * - * @param {XMLElement} xmlNode xml representation of block element - * @param {Number} value new z-index number - */ - this.setZindex = function(xmlNode, value) { - this.executeActionByRuleSet("setzindex", "zindex", xmlNode, value); - }; - - /** - * Sets mode to canvas object. Modes adds new features. For example, - * if connection-change mode is active, possible is deleting connections - * between blocks. All operations from "normal" mode are allowed in other - * modes. - * - * Modes: - * normal - all operations are allowed except operations from different modes - * connection-add - it's possible to add new connection between blocks - * connection-change - it's possible to change existing connection - * - * @param {String} mode Operations mode - */ - this.setMode = function(mode) { - _self.objCanvas.setMode(mode); - }; - - this.getMode = function() { - return _self.objCanvas.getMode(); - }; - - /** - * Immobilise block element on flowchart element. This is an action. - * It's possible to return to previous state with Undo/Redo. - * - * @param {XMLElement} xmlNode xml representation of block element - * @param {Boolean} value prohibit block move, default is false. - * Possible values: - * true block is locked - * false block is unlocked - */ - this.setLock = function(xmlNode, value) { - this.executeActionByRuleSet("setlock", "lock", xmlNode, String(value)); - }; - - /** - * Rotate block element. This is an action. It's possible to return to - * previous state with Undo/Redo - * - * @param {XMLElement} xmlNode xml representation of block element - * @param {Number} newRotation the rotation in degrees clockwise, default is 0 - * Possible values: - * 0 0 degrees rotation - * 90 90 degrees rotation - * 180 180 degrees rotation - * 270 270 degrees rotation - * @param {Number} start - */ - this.rotate = function(xmlNode, newRotation, start) { - var prevFlipV = this.applyRuleSetOnNode("flipv", xmlNode) == "true" - ? true - : false, - prevFlipH = this.applyRuleSetOnNode("fliph", xmlNode) == "true" - ? true - : false, - prevRotation = start - ? 0 - : parseInt(this.applyRuleSetOnNode("rotation", xmlNode)) || 0, - names = ["fliph", "flipv", "rotation"], - values; - - if (prevFlipV && prevFlipH) { - values = ["false", "false", (newRotation + 180) % 360]; - } - else { - values = [String(prevFlipH), String(prevFlipV), newRotation]; - - if (Math.abs(newRotation - prevRotation) % 180 !== 0) { - var - w = parseInt(this.applyRuleSetOnNode("width", xmlNode)) || 0, - h = parseInt(this.applyRuleSetOnNode("height", xmlNode)) || 0; - - names.push("width", "height"); - values.push(h, w); - } - } - - this.executeMulticallAction("rotate", names, xmlNode, values); - }; - - /** - * Wether to mirror the block over the vertical axis. This is an action. - * It's possible to return to previous state with Undo/Redo. - * - * @param {XMLElement} xmlNode xml representation of block element - * @param {Number} newFlipV new flip value, default is false - * Possible values: - * true block element is flipped - * false block element is not flipped - */ - this.flipVertical = function(xmlNode, newFlipV) { - var prevFlipH = this.applyRuleSetOnNode("fliph", xmlNode) == "true" - ? true - : false, - prevRotate = this.applyRuleSetOnNode("rotation", xmlNode) - ? parseInt(this.applyRuleSetOnNode("rotation", xmlNode)) - : 0; - - var values = prevFlipH && newFlipV - ? ["false", "false", (prevRotate + 180) % 360] - : [String(prevFlipH), String(newFlipV), prevRotate]; - - this.executeMulticallAction( - "verticalFlip", ["fliph", "flipv", "rotation"], xmlNode, values); - }; - - /** - * Wether to mirror the block over the horizontal axis. This is an action. - * It's possible to return to previous state with Undo/Redo. - * - * @param {XMLElement} xmlNode xml representation of block element - * @param {Number} newFlipV new flip value, default is false - * Possible values: - * true block element is flipped - * false block element is not flipped - */ - this.flipHorizontal = function(xmlNode, newFlipH) { - var prevFlipV = this.applyRuleSetOnNode("flipv", xmlNode) == "true" - ? true - : false, - prevFlipH = this.applyRuleSetOnNode("fliph", xmlNode) == "true" - ? true - : false, - prevRotate = this.applyRuleSetOnNode("rotation", xmlNode) - ? parseInt(this.applyRuleSetOnNode("rotation", xmlNode)) - : 0; - - var values = prevFlipV && newFlipH - ? ["false", "false", (prevRotate + 180) % 360] - : [String(newFlipH), String(prevFlipV), prevRotate]; - - this.executeMulticallAction( - "horizontalFlip", ["fliph", "flipv", "rotation"], xmlNode, values); - }; - - /** - * Resize block element in vertical and horiznontal plane. This is an - * action. It's possible to return to previous state with Undo/Redo. - * - * @param {XMLElement} xmlNode xml representation of block element - * @param {Number} newWidth block element horizontal size - * @param {Number} newHeight block element vertical size - * @param {Number} newTop vertical position of block element - * @param {Number} newLeft horizontal position of block element - */ - this.resize = function(xmlNode, newWidth, newHeight, newTop, newLeft) { - this.executeMulticallAction( - "resize", - ["top", "left", "width", "height"], - xmlNode, - [newTop, newLeft, newWidth, newHeight]); - }; - - /** - * Executes an actions based on the set names and the new values - * - * @param {String} atName the name of action rule defined in j:actions for this element. - * @param {Object} setNames the names list of the binding rule defined in j:bindings for this element. - * @type {String} - * @param {XMLElement} xmlNode the xml representation of element to which rules are applied - * @param {Object} values the new values list of the node - * @type {String} - */ - this.executeMulticallAction = function(atName, setNames, xmlNode, values) { - var props = changes = [], l = setNames.length; - for (var i = 0; i < l; i++) { - var node = this.getNodeFromRule(setNames[i], xmlNode, false, false, - this.createModel), - value = values[i]; - - if (node) { - var atAction = node.nodeType == 1 || node.nodeType == 3 - || node.nodeType == 4 - ? "setTextNode" - : "setAttribute"; - var args = node.nodeType == 1 - ? [node, value] - : (node.nodeType == 3 || node.nodeType == 4 - ? [node.parentNode, value] - : [node.ownerElement || node.selectSingleNode(".."), - node.nodeName, value]); - changes.push({ - func: atAction, - args: args - }); - } - } - this.executeAction("multicall", changes, atName, xmlNode); - } - - /** - * Creates new connection between two blocks. This is an action. It's - * possible to return to previous state with Undo/Redo. - * - * @param {XMLElement} sXmlNode xml representation of source block element - * @param {Number} sInput source block input number - * @param {XMLElement} dXmlNode xml representation of destination block element - * @param {Number} dInput destination block output number - */ - this.addConnector = function(sXmlNode, sInput, dXmlNode, dInput) { - var nXmlNode = _self.xmlRoot.ownerDocument.createElement("connection"); - - nXmlNode.setAttribute("ref", _self.applyRuleSetOnNode("id", dXmlNode)); - nXmlNode.setAttribute("output", sInput); - nXmlNode.setAttribute("input", dInput); - - this.executeAction("appendChild", [sXmlNode, nXmlNode], - "addConnector", sXmlNode); - }; - - /** - * Removes connections between blocks. It's possible to remove more - * connections in one call. This is an action. It's possible to return - * to previous state with Undo/Redo. - * - * @param {Object} xmlNodeArray xml representations of connections elements - */ - this.removeConnectors = function(xmlNodeArray) { - var changes = []; - - for (var i = 0, l = xmlNodeArray.length; i < l; i++) { - changes.push({ - func : "removeNode", - args : [xmlNodeArray[i]] - }); - } - - this.executeAction("multicall", changes, - "removeConnectors", xmlNodeArray[0]); - }; - - /** - * Creates new xml representation of block element - * - * @param {XMLElement} parentXmlNode xml representation of block parent node - * @param {Number} left horizontal position of block element - * @param {Number} top vertical position of block element - * @param {String} type name of block with special abilities, which could be set in template file - * @param {Number} width block element horizontal size - * @param {Number} height block element vertical size - * @param {String} id unique block element name - */ - this.addBlock = function(type, left, top, caption) { - if (!type) - return; - - var elTemplate = - template.selectSingleNode("//element[@type='" + type + "']"); - - if (!elTemplate) - return; - - var nXmlNode = this.xmlRoot.ownerDocument.createElement("block"); - - nXmlNode.setAttribute("id", "b"+(lastBlockId + 1)); - nXmlNode.setAttribute("left", left || 20); - nXmlNode.setAttribute("top", top || 20); - nXmlNode.setAttribute("width", elTemplate.getAttribute("dwidth")); - nXmlNode.setAttribute("height", elTemplate.getAttribute("dheight")); - nXmlNode.setAttribute("type", type); - nXmlNode.setAttribute("caption", caption); - - this.executeAction("appendChild", [this.xmlRoot, nXmlNode], - "addBlock", this.xmlRoot); - }; - - /** - * Removes xml representation of block. It's possible to remove more - * xmlNodes in one call. This is an action. It's possible to return to - * previous state with Undo/Redo. - * - * @param {Object} xmlNodeArray xml representations of blocks elements - */ - this.removeBlocks = function(xmlNodeArray) { - var changes = []; - var ids = []; - - for (var i = 0, l = xmlNodeArray.length; i < l; i++) { - var id = this.applyRuleSetOnNode("id", xmlNodeArray[i]); - ids.push(id); - - changes.push({ - func : "removeNode", - args : [xmlNodeArray[i]] - }); - } - - /* Removing connections from other blocks */ - for (var id2 in xmlConnections) { - for (var j = xmlConnections[id2].length - 1; j >= 0 ; j--) { - for (var k = 0; k < ids.length; k++) { - if (xmlConnections[id2][j].ref == ids[k]) { - changes.push({ - func : "removeNode", - args : [xmlConnections[id2][j].xmlNode] - }); - - } - } - } - } - - this.executeAction("multicall", changes, - "removeBlocksWithConnections", xmlNodeArray); - }; - - this.$draw = function() { - //Build Main Skin - this.oExt = this.$getExternal(); - this.oInt = this.$getLayoutNode("main", "container", this.oExt); - - _self.objCanvas = new jpf.flow.getCanvas(this.oInt); - jpf.flow.init(); - /*jpf.flow.onconnectionrename = function(e) { - _self.$beforeRename(e); - }*/ - }; - - /* Action when block is removed */ - this.$deInitNode = function(xmlNode, htmlNode) { - var id = this.applyRuleSetOnNode("id", xmlNode); - - objBlocks[id].destroy(); - - delete objBlocks[id]; - delete xmlBlocks[id]; - htmlNode.parentNode.removeChild(htmlNode); - resizeManager.hide(); - } - - this.$dragdrop = function(el, dragdata, candrop) { - var blockPos = jpf.getAbsolutePosition(dragdata.indicator); - var canvasPos = jpf.getAbsolutePosition(_self.objCanvas.htmlElement); - - this.moveTo( - [dragdata.xmlNode], - blockPos[0] - canvasPos[0], - blockPos[1] - canvasPos[1] - ); - } - - this.$updateModifier = function(xmlNode, htmlNode) { -jpf.console.info("UPDATE"); -//alert("update") - var blockId = this.applyRuleSetOnNode("id", xmlNode); - - objBlock = objBlocks[blockId]; - - var t = parseInt(this.applyRuleSetOnNode("top", xmlNode)) - ? this.applyRuleSetOnNode("top", xmlNode) - : parseInt(objBlock.htmlElement.style.top), - l = parseInt(this.applyRuleSetOnNode("left", xmlNode)) - ? this.applyRuleSetOnNode("left", xmlNode) - : parseInt(objBlock.htmlElement.style.left); - - objBlock.moveTo(t, l); - - var w = parseInt(this.applyRuleSetOnNode("width", xmlNode)) - ? this.applyRuleSetOnNode("width", xmlNode) - : objBlock.other.dwidth, - h = parseInt(this.applyRuleSetOnNode("height", xmlNode)) - ? this.applyRuleSetOnNode("height", xmlNode) - : objBlock.other.dheight; - objBlock.resize(w, h); - - /* Rename */ - objBlock.setCaption(this.applyRuleSetOnNode("caption", xmlNode)); - - /* Lock */ - var lock = this.applyRuleSetOnNode("lock", xmlNode) == "true" - ? true - : false; - - objBlock.setLock(lock); - - objBlock.changeRotation( - this.applyRuleSetOnNode("rotation", xmlNode), - this.applyRuleSetOnNode("fliph", xmlNode), - this.applyRuleSetOnNode("flipv", xmlNode)); - - /* Checking for changes in connections */ - var xpath = this.getSelectFromRule("connection", xmlNode)[0]; - var cNew = xmlNode.selectNodes(xpath); - var cCurrent = xmlConnections[blockId] || []; - - //Checking for removed connections - if (cCurrent.length) { - for (var i = 0; i < cCurrent.length; i++) { - for (var j = 0, found = false; j < cNew.length; j++) { - if (cCurrent[i].xmlNode == cNew[j]) { - found = true; - break; - } - } - - if (!found) { - if (objBlocks[blockId] && objBlocks[cCurrent[i].ref]) { - var ConToDel = jpf.flow.findConnector( - objBlocks[blockId], cCurrent[i].output, - objBlocks[cCurrent[i].ref], cCurrent[i].input); - if (ConToDel) { - jpf.flow.removeConnector(ConToDel.connector.htmlElement); - } - xmlConnections[blockId].removeIndex(i); - } - } - } - } - else{ - delete xmlConnections[blockId]; - } - - //Checking for new connections - for (var i = 0; i < cNew.length; i++) { - var found = false; - if (cCurrent) { - for (var j = 0; j < cCurrent.length; j++) { - if (cCurrent[j].xmlNode == cNew[i]) { - found = true; - break; - } - } - } - - if (!found) { - var ref = this.applyRuleSetOnNode("ref", cNew[i]); - var output = this.applyRuleSetOnNode("output", cNew[i]); - var input = this.applyRuleSetOnNode("input", cNew[i]); - var label = this.applyRuleSetOnNode("label", cNew[i]); - var type = this.applyRuleSetOnNode("type", cNew[i]); - - if (xmlBlocks[ref]) { - var r = xmlConnections[blockId] || []; - r.push({ - ref : ref, - output : output, - input : input, - label : label, - type : type, - xmlNode : cNew[i] - }); - - new jpf.flow.addConnector(_self.objCanvas, - objBlocks[blockId], objBlocks[ref], { - output : output, - input : input, - label : label, - type : type, - xmlNode: cNew[i] - } - ); - xmlConnections[blockId] = r; - } - else { - jpf.console.info("Destination block don't exist."); - } - } - } - - if (resizeManager && xmlNode == this.selected && !lock) { - resizeManager.show(); - } - else { - resizeManager.hide(); - } - - objBlock.updateOutputs(); - objBlock.onMove(); - } - - this.$add = function(xmlNode, Lid, xmlParentNode, htmlParentNode, beforeNode) { - /* Creating Block */ - lastBlockId++; -//jpf.flow.alert_r(xmlNode) -jpf.console.info("ADD"); - this.$getNewContext("block"); - var block = this.$getLayoutNode("block"); - var elSelect = this.$getLayoutNode("block", "select"); - var elImage = this.$getLayoutNode("block", "image"); - var elimageContainer = this.$getLayoutNode("block", "imagecontainer"); - var elCaption = this.$getLayoutNode("block", "caption"); - - elCaption.setAttribute("ondblclick", 'jpf.lookup(' + this.uniqueId - + ').$beforeRename(event); return false;'); - - this.nodes.push(block); - - /* Set Css style */ - var style = [], style2 = []; - var left = this.applyRuleSetOnNode("left", xmlNode) || 0; - var top = this.applyRuleSetOnNode("top", xmlNode) || 0; - var zindex = this.applyRuleSetOnNode("zindex", xmlNode) || 1001; - - style.push("z-index:" + zindex); - style.push("left:" + left + "px"); - style.push("top:" + top + "px"); - - if (template) { - var elTemplate = template.selectSingleNode("//element[@type='" - + this.applyRuleSetOnNode("type", xmlNode) - + "']"); - if (elTemplate) { - var stylesFromTemplate = elTemplate.getAttribute("css"); - - if (stylesFromTemplate) { - stylesFromTemplate = stylesFromTemplate.split(";"); - - for (var k = 0; k < stylesFromTemplate.length; k++) { - var _style = stylesFromTemplate[k].trim(); - if (_style !== "") { - if (_style.substr(0, 5) == "color") { - elCaption.setAttribute("style", [_style].join(";")); - } - else { - style.push(_style); - } - } - } - } - var w = elTemplate.getAttribute("dwidth"); - var h = elTemplate.getAttribute("dheight"); - } - } - - if (this.applyRuleSetOnNode("id", xmlNode)) { - var _id = this.applyRuleSetOnNode("id", xmlNode).substr(1); - if (_id > lastBlockId) { - lastBlockId = _id; - } - } - - var id = this.applyRuleSetOnNode("id", xmlNode) || "b"+lastBlockId; - var width = this.applyRuleSetOnNode("width", xmlNode) || w || 56; - var height = this.applyRuleSetOnNode("height", xmlNode) || h || 56; - var lock = this.applyRuleSetOnNode("lock", xmlNode) || "false"; - var capPos = this.applyRuleSetOnNode("cap-pos", xmlNode) || "outside"; - - style.push("width:" + width + "px"); - style.push("height:" + height + "px"); - - /* Set styles to block */ - block.setAttribute("style", style.join(";")); - - style2.push("width:" + width + "px"); - style2.push("height:" + height + "px"); - - /* Set styles to image container */ - elImage.setAttribute("style", style2.join(";")); - elimageContainer.setAttribute("style", style2.join(";")); - /* End - Set Css style */ - -//jpf.flow.alert_r(xmlNode); - xmlNode.setAttribute("id", id); - xmlNode.setAttribute("width", width); - xmlNode.setAttribute("height", height); - xmlNode.setAttribute("lock", lock); - xmlNode.setAttribute("left", left); - xmlNode.setAttribute("top", top); - xmlNode.setAttribute("zindex", zindex); - xmlNode.setAttribute("cap-pos", capPos); -//jpf.flow.alert_r(xmlNode); - - this.$setStyleClass(elCaption, capPos); - - elSelect.setAttribute(this.itemSelectEvent || - "onmousedown", 'var o = jpf.lookup(' - + this.uniqueId - + '); o.select(this, event.ctrlKey, event.shiftKey)'); - - - - jpf.xmldb.nodeConnect(this.documentId, xmlNode, block, this); - xmlBlocks[id] = xmlNode; - - /* Creating Connections */ - var r = []; - var xpath = this.getSelectFromRule("connection", xmlNode)[0]; - var connections = xmlNode.selectNodes(xpath); - - for (var i = 0, l = connections.length; i < l; i++) { - r.push({ - ref : this.applyRuleSetOnNode("ref", connections[i]), - output : this.applyRuleSetOnNode("output", connections[i]), - input : this.applyRuleSetOnNode("input", connections[i]), - label : this.applyRuleSetOnNode("label", connections[i]), - type : this.applyRuleSetOnNode("type", connections[i]), - xmlNode : connections[i] - }); - - } - if (r.length > 0) { - xmlConnections[id] = r; - } - - }; - - this.$fill = function() { - jpf.xmldb.htmlImport(this.nodes, this.oInt); -jpf.console.info("FILL"); - for (var id in xmlBlocks) { - var xmlBlock = xmlBlocks[id], - htmlElement = jpf.xmldb.findHTMLNode(xmlBlock, this), - type = xmlBlocks[id].getAttribute("type") || null, - inputList = {}; - - if (type) { - if (template) { - var elTemplate = template.selectSingleNode("element[@type='" + this.applyRuleSetOnNode("type", xmlBlock) + "']"); - - var inputs = elTemplate.selectNodes("input"); - for (var i = 0, l = inputs.length; i < l; i++) { - inputList[parseInt(inputs[i].getAttribute("name"))] = { - x : parseInt(inputs[i].getAttribute("x")), - y : parseInt(inputs[i].getAttribute("y")), - position : inputs[i].getAttribute("position") - }; - } - } - } - - var lock = this.applyRuleSetOnNode("lock", xmlBlock) == "true" - ? true - : false; - var other = { - lock : lock, - flipv : this.applyRuleSetOnNode("flipv", xmlBlock) == "true" - ? true - : false, - fliph : this.applyRuleSetOnNode("fliph", xmlBlock) == "true" - ? true - : false, - rotation : parseInt(this.applyRuleSetOnNode("rotation", xmlBlock)) - || 0, - inputList : inputList, - type : type, - picture : type && template - ? elTemplate.getAttribute("picture") - : null, - dwidth : type && template - ? parseInt(elTemplate.getAttribute("dwidth")) - : 56, - dheight : type && template - ? parseInt(elTemplate.getAttribute("dheight")) - : 56, - scalex : type && template - ? (elTemplate.getAttribute("scalex") == "true" - ? true - : false) - : true, - scaley : type && template - ? (elTemplate.getAttribute("scaley") == "true" - ? true - : false) - : true, - scaleratio : type && template - ? (elTemplate.getAttribute("scaleratio") == "true" - ? true - : false) - : false, - xmlNode : xmlBlock, - caption : this.applyRuleSetOnNode("caption", xmlBlock), - capPos : this.applyRuleSetOnNode("cap-pos", xmlBlock) - } - - var objBlock = jpf.flow.isBlock(htmlElement); - - if (objBlock) { - this.$setStyleClass(htmlElement, "", ["empty"]); - objBlock.other = other; - objBlock.initBlock(); - } - else { - var objBlock = jpf.flow.addBlock(htmlElement, _self.objCanvas, other); - - objBlock.oncreateconnection = function(sXmlNode, sInput, dXmlNode, dInput) { - _self.addConnector(sXmlNode, sInput, dXmlNode, dInput); - }; - objBlock.onremoveconnection = function(xmlNodeArray) { - _self.removeConnectors(xmlNodeArray); - }; - objBlocks[id] = objBlock; - } - } - - for (var id in xmlBlocks) { - var c = xmlConnections[id] || []; - - for (var i = 0, l = c.length; i < l; i++) { - var con = jpf.flow.findConnector(objBlocks[id], c[i].output, - objBlocks[c[i].ref], c[i].input); - if (!con) { - if (objBlocks[id] && objBlocks[c[i].ref]) { - //it's called because connection labels must be aligned - objBlocks[id].onMove(); - new jpf.flow.addConnector(_self.objCanvas, objBlocks[id], - objBlocks[c[i].ref], { - output : c[i].output, - input : c[i].input, - label : c[i].label, - type : c[i].type, - xmlNode : c[i].xmlNode - }); - } - else { - connToPaint.push({ - id : id, - id2 : c[i].ref, - output : c[i].output, - input : c[i].input, - label : c[i].label, - type : c[i].type, - xmlNode : c[i].xmlNode - }); - } - } - else { - con.connector.other = { - output : c[i].output, - input : c[i].input, - label : c[i].label, - type : c[i].type, - xmlNode : c[i].xmlNode - }; - con.connector.activateInputs(); - con.connector.draw(); - } - } - } - - /* Try to draw rest of connections */ - for (var i = connToPaint.length-1; i >= 0 ; i--) { - if (objBlocks[connToPaint[i].id] && objBlocks[connToPaint[i].id2]) { - new jpf.flow.addConnector(_self.objCanvas, - objBlocks[connToPaint[i].id], - objBlocks[connToPaint[i].id2], { - output : connToPaint[i].output, - input : connToPaint[i].input, - label : connToPaint[i].label, - type : connToPaint[i].type, - xmlNode : connToPaint[i].xmlNode - }); - connToPaint.removeIndex(i); - } - } - - this.nodes = []; - - } - - this.$destroy = function() { - /*this.oPrevious.onclick = null; - - this.removeEventListener("onkeydown", onkeydown_); - this.removeEventListener("mousescroll", onmousescroll_); - - this.x = null;*/ - } - - this.$loadJml = function(x) { - if (this.$jml.childNodes.length) - this.$loadInlineData(this.$jml); - - /* Loading template */ - jpf.getData(this.$jml.getAttribute("template"), null, null, - function(data, state, extra) { - if (state == jpf.SUCCESS) { - _self.loadTemplate(data); - } - else { - jpf.console.info("An error has occurred: " + extra.message, 2); - return; - } - }); - - /* Resize */ - resizeManager = new jpf.resize(); - - resizeManager.onresizedone = function(w, h, t , l) { - _self.resize(_self.selected, w, h, t, l); - }; - - resizeManager.onresize = function(htmlElement, t, l, w, h) { - if (!htmlElement) - return; - var objBlock = jpf.flow.isBlock(htmlElement); - objBlock.moveTo(t, l); - objBlock.resize(w, h); - objBlock.updateOutputs(); - objBlock.onMove(); - }; - - jpf.flow.onaftermove = function(dt, dl) { - _self.moveTo(_self.selected, dl, dt); - }; - - jpf.flow.onblockmove = function() { - resizeManager.show(); - }; - }; - - this.loadTemplate = function(data) { - template = jpf.xmldb.getBindXmlNode(data); - this.$checkLoadQueue(); - }; - - this.$canLoadData = function() { - return template ? true : false; - }; - -}).implement( - jpf.Presentation, - jpf.DataBinding, - jpf.Cache, - jpf.MultiSelect, - jpf.BaseList, - jpf.Rename, - jpf.DragDrop -); - - -/*FILEHEAD(/var/lib/jpf/src/elements/flashplayer.js)SIZE(-1077090856)TIME(1238944817)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-/**
- * Element displaying the contents of a .swf (adobe flash) file.
- *
- * @constructor
- * @define flashplayer
- * @allowchild {smartbinding}
- * @addnode elements
- *
- * @inherits jpf.BaseSimple
- *
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.9
- *
- * @binding value Determines the way the value for the element is retrieved
- * from the bound data.
- * Example:
- * Sets the flash source text based on data loaded into this component.
- * <code>
- * <j:flashplayer>
- * <j:bindings>
- * <j:value select="@src" />
- * </j:bindings>
- * </j:flashplayer>
- * </code>
- * Example:
- * A shorter way to write this is:
- * <code>
- * <j:flashplayer ref="@src" />
- * </code>
- */
-jpf.flashplayer = jpf.component(jpf.NODE_VISIBLE, function(){
- //this.editableParts = {"main" : [["image","@src"]]};
-
- /**** Public methods ****/
-
- /**
- * @ref global#setValue
- */
- this.setValue = function(value){
- this.setProperty("value", value);
- };
-
- /**** Properties and attributes ****/
-
- this.$supportedProperties.push("value");
- this.$propHandlers["value"] = function(value){
- this.setSource(value);
- };
-
- /**** Init ****/
-
- this.$draw = function(){
- //Build Main Skin
- //this.oInt = this.oExt = this.$getExternal();
- //this.oExt.onclick = function(){this.host.dispatchEvent("click");}
-
- var src = this.$jml.getAttribute("src") || "";
- document.body.insertAdjacentHTML("beforeend",
- '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" \
- codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" \
- width="1" \
- height="1" \
- align="middle">\
- <param name="allowScriptAccess" value="sameDomain" />\
- <param name="allowFullScreen" value="false" />\
- <param name="movie" value="' + src + '" />\
- <param name="play" value="false" />\
- <param name="menu" value="false" />\
- <param name="quality" value="high" />\
- <param name="wmode" value="transparent" />\
- <param name="bgcolor" value="#ffffff" />\
- <embed src="' + src + '" play="false" menu="false" \
- quality="high" wmode="transparent" bgcolor="#ffffff" width="1" \
- height="1" align="middle" allowScriptAccess="sameDomain" \
- allowFullScreen="false" type="application/x-shockwave-flash" \
- pluginspage="http://www.macromedia.com/go/getflashplayer" />\
- </object>')
- this.oExt = document.body.lastChild;
- pHtmlNode.appendChild(this.oExt);
- };
-
- this.$loadJml = function(x){
- //this.$makeEditable("main", this.oExt, this.$jml);
-
- jpf.JmlParser.parseChildren(x, null, this);
- };
-}).implement(
- jpf.BaseSimple
-);
-
- - -/*FILEHEAD(/var/lib/jpf/src/elements/statusbar.js)SIZE(-1077090856)TIME(1238944817)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -/** - * Element displaying a bar consisting of panels containing other text, icons - * and more jml. This element is usually placed in the bottom of the screen to - * display context sensitive and other information about the state of the - * application. - * Example: - * <code> - * <j:statusbar align="bottom"> - * <j:panel> - * Javeline PlatForm - * </j:panel> - * <j:progressbar value="{jpf.offline.position}" /> - * <j:panel> - * - * </j:panel> - * </j:statusbar> - * </code> - * - * @constructor - * @define statusbar - * @allowchild panel - * @allowchild progressbar - * @addnode elements - * - * @author Ruben Daniels - * @version %I%, %G% - * @since 0.9 - */ - -jpf.statusbar = jpf.component(jpf.NODE_VISIBLE, function(){ - this.canHaveChildren = true; - this.$focussable = false; - - /**** DOM Hooks ****/ - var insertChild; - - this.$domHandlers["removechild"].push(function(jmlNode, doOnlyAdmin){ - if (doOnlyAdmin) - return; - - }); - - this.$domHandlers["insert"].push(insertChild = function (jmlNode, beforeNode, withinParent){ - if (jmlNode.tagName != "panel") - return; - - jmlNode.$propHandlers["caption"] = function(value){ - jpf.xmldb.setNodeValue( - this.$getLayoutNode("panel", "caption", this.oExt), value); - } - jmlNode.$propHandlers["icon"] = function(value){ - var oIcon = this.$getLayoutNode("panel", "icon", this.oExt); - if (!oIcon) return; - - if (value) - this.$setStyleClass(this.oExt, this.baseCSSname + "Icon"); - else - this.$setStyleClass(this.oExt, "", [this.baseCSSname + "Icon"]); - - if (oIcon.tagName == "img") - oIcon.setAttribute("src", value ? this.iconPath + value : ""); - else { - oIcon.style.backgroundImage = value - ? "url(" + this.iconPath + value + ")" - : ""; - } - } - }); - - - /**** Init ****/ - - this.$draw = function(){ - //Build Main Skin - this.oExt = this.$getExternal(); - this.oInt = this.$getLayoutNode("main", "container", this.oExt); - }; - - this.$loadJml = function(x){ - var bar, tagName, i, l, node, nodes = this.$jml.childNodes; - - //Let's not parse our children, when we've already have them - if (!this.oInt && this.childNodes.length) - return; - - //@todo Skin switching here... - - for (i = 0, l = nodes.length; i < l; i++) { - node = nodes[i]; - if (node.nodeType != 1) - continue; - - tagName = node[jpf.TAGNAME]; - if (tagName == "panel") { - bar = new jpf.panel(this.oInt, tagName); - bar.skinName = this.skinName - insertChild.call(this, bar); - bar.loadJml(node, this); - - /*if (!bar.caption && node.childNodes.length == 1 - && "3|4".indexOf(node.childNodes.nodeType) > -1) - jmlNode.setCaption(node.firstChild.nodeValue);*/ - } - else if (tagName == "progressbar") { - new jpf.progressbar(this.oInt, tagName).loadJml(node, this); - } - } - - if (bar) { - this.$setStyleClass(bar.oExt, bar.baseCSSname + "Last"); - } - }; -}).implement(jpf.Presentation); - - -/*FILEHEAD(/var/lib/jpf/src/elements/model.js)SIZE(-1077090856)TIME(1238944817)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * Element functioning as the central access point for xml data. Data can be
- * retrieved from any data source using data instructions. Data can be
- * submitted using data instructions in a similar way to html form posts. The
- * modal can be reset to it's original state. It has support for offline use and
- * synchronization between multiple clients.
- * Example:
- * <code>
- * <j:model load="url:products.xml" />
- * </code>
- * Example:
- * A small form where a form is submitted using a model.
- * <code>
- * <j:model id="mdlForm" submission="url:save_form.asp" />
- *
- * <j:bar model="mdlForm">
- * <j:label>Name</j:label>
- * <j:textbox ref="name" />
- * <j:label>Address</j:label>
- * <j:textarea ref="address" />
- * ...
- *
- * <j:button default="true" action="submit">Submit</j:button>
- * </j:bar>
- * </code>
- *
- * @event beforeretrieve Fires before a request is made to retrieve data.
- * cancellable: Prevents the data from being retrieved.
- * @event afterretrieve Fires when the request to retrieve data returns both on success and failure.
- * @event receive Fires when data is successfully retrieved
- * object:
- * {String} data the retrieved data
- * @event beforeload Fires before data is loaded into the model.
- * cancellable:
- * @event afterload Fires after data is loaded into the model.
- * @event beforesubmit Fires before data is submitted.
- * cancellable: Prevents the submit.
- * object:
- * {String} instruction The data instruction used to store the data.
- * @event submiterror Fires when submitting data has failed.
- * @event submitsuccess Fires when submitting data was successfull.
- * @event aftersubmit Fires after submitting data.
- * @event error Fires when a communication error has occured while making a request for this element.
- * cancellable: Prevents the error from being thrown.
- * bubbles:
- * object:
- * {Error} error the error object that is thrown when the event callback doesn't return false.
- * {Number} state the state of the call
- * Possible values:
- * jpf.SUCCESS the request was successfull
- * jpf.TIMEOUT the request has timed out.
- * jpf.ERROR an error has occurred while making the request.
- * jpf.OFFLINE the request was made while the application was offline.
- * {mixed} userdata data that the caller wanted to be available in the callback of the http request.
- * {XMLHttpRequest} http the object that executed the actual http request.
- * {String} url the url that was requested.
- * {Http} tpModule the teleport module that is making the request.
- * {Number} id the id of the request.
- * {String} message the error message.
- *
- * @constructor
- * @define model
- * @allowchild [cdata], instance, load, submission
- * @addnode smartbinding, global
- * @attribute {String} load the data instruction on how to load data from the data source into this model.
- * @attribute {String} submission the data instruction on how to record the data from the data source from this model.
- * @attribute {String} session the data instruction on how to store the session data from this model.
- * @attribute {String} schema not implemented.
- * @attribute {Boolean} init whether to initialize the model immediately. If set to false you are expected to call init() when needed. This is useful when the system has to log in first.
- * @attribute {Boolean} save-original whether to save the original state of the data. This enables the use of the reset() call.
- * @attribute {String} remote the id of the {@link element.remote} element to use for data synchronization between multiple clients.
- * @define instance
- * @attribute {String} src the url to retrieve the data from.
- * @define load
- * @attribute {String} get the data instruction on how to load data from the data source into this model.
- * @define submission
- * @attribute {String} ref not implemented.
- * @attribute {String} bind not implemented.
- * @attribute {String} action the url to sent the data to.
- * @attribute {String} method how to serialize the data, and how to sent it.
- * Possible values:
- * post sent xml using the http post protocol. (application/xml)
- * get sent urlencoded form data using the http get protocol. (application/x-www-form-urlencoded)
- * put sent xml using the http put protocol. (application/xml)
- * multipart-post not implemented (multipart/related)
- * form-data-post not implemented (multipart/form-data)
- * urlencoded-post sent urlencoded form data using the http get protocol. (application/x-www-form-urlencoded)
- * @attribute {String} set the data instruction on how to record the data from the data source from this model.
- *
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.8
- */
-jpf.model = function(data, caching){
- jpf.register(this, "model", jpf.NODE_HIDDEN);/** @inherits jpf.Class */
- this.data = data;
- this.caching = caching;
- this.cache = {};
- var _self = this;
-
- if (!jpf.globalModel)
- jpf.globalModel = this;
-
- this.saveOriginal = true;
-
- jpf.console.info("Creating Model");
-
- this.$supportedProperties = ["submission", "load"];
- this.$handlePropSet = function(prop, value, force){
- if (prop == "submission")
- defSubmission = value;
- }
-
- /**
- * @private
- */
- this.loadInJmlNode = function(jmlNode, xpath){
- if (this.data && xpath) {
- if (!jpf.supportNamespaces && (this.data.prefix || this.data.scopeName))
- (this.data.nodeType == 9 ? this.data : this.data.ownerDocument)
- .setProperty("SelectionNamespaces", "xmlns:"
- + (this.data.prefix || this.data.scopeName) + "='"
- + this.data.namespaceURI + "'");
-
- var xmlNode = this.data.selectSingleNode(xpath);
- if (!xmlNode)
- jmlNode.$listenRoot = jpf.xmldb.addNodeListener(this.data, jmlNode);
- }
- else
- xmlNode = this.data || null;
-
- jmlNode.load(xmlNode);
- };
-
- var jmlNodes = {};
- /**
- * Registers a jml element to this model in order for the jml element to
- * receive data loaded in this model.
- *
- * @param {JMLElement} jmlNode The jml element to be registered.
- * @param {String} [xpath] the xpath query which is executed on the data of the model to select the node to be loaded in the <code>jmlNode</code>.
- * @return {Model} this model
- */
- this.register = function(jmlNode, xpath){
- if (!jmlNode)
- return this;
-
- jmlNodes[jmlNode.uniqueId] = [jmlNode, xpath];
- jmlNode.$model = this;
- //if(!jmlNode.smartBinding) return this; //Setting model too soon causes object not to have XMLRoot which is incorrect
-
- if (this.connect) {
- //This model is a connect proxy
- if (this.connect.type)
- this.connect.node.connect(jmlNode, null, this.connect.select, this.connect.type);
- else
- this.connect.node.connect(jmlNode, true, this.connect.select);
- }
- else {
- //jmlNode.$model = this;
-
- if (this.data)
- this.loadInJmlNode(jmlNode, xpath);
- }
-
- return this;
- };
-
- this.$register = function(jmlNode, xpath){
- jmlNodes[jmlNode.uniqueId][1] = xpath;
- };
-
- /**
- * Removes a jml element from the group of registered jml elements.
- * The jml element will not receive any updates from this model, however
- * the data loaded in the jml element is not unloaded.
- *
- * @param {JMLElement} jmlNode The jml element to be unregistered.
- */
- this.unregister = function(jmlNode){
- //if (this.connect)
- //this.connect.node.disconnect(jmlNode);
- if(jmlNode.dataParent)
- jmlNode.dataParent.parent.disconnect(jmlNode);
-
- delete jmlNodes[jmlNode.uniqueId]
- };
-
- this.getXpathByJmlNode = function(jmlNode){
- var n = jmlNodes[jmlNode.uniqueId];
- if (!n)
- return false;
-
- return n[1];
- };
-
- /**
- * Returns a string representation of the data in this model.
- */
- this.toString = function(){
- var xml = jpf.xmldb.clearConnections(this.data.cloneNode(true));
- return this.data
- ? jpf.formatXml(xml.xml || xml.serialize())
- : "Model has no data.";
- };
-
- /**
- * Gets a copy of current state of the xml of this model.
- *
- * @return {XMLNode} context of this model
- */
- this.getXml = function(){
- return this.data
- ? jpf.xmldb.clearConnections(this.data.cloneNode(true))
- : false;
- };
-
- /**
- * Sets a value of an XMLNode based on an xpath statement executed on the data of this model.
- *
- * @param {String} xpath the xpath used to select a XMLNode.
- * @param {String} value the value to set.
- * @return {XMLNode} the changed XMLNode
- */
- this.setQueryValue = function(xpath, value){
- var node = jpf.xmldb.createNodeFromXpath(this.data, xpath);
- if (!node)
- return null;
-
- jpf.xmldb.setTextNode(node, value);
- return node;
- };
-
- /**
- * Gets the value of an XMLNode based on a xpath statement executed on the data of this model.
- *
- * @param {String} xpath the xpath used to select a XMLNode.
- * @return {String} value of the XMLNode
- */
- this.queryValue = function(xpath){
- return jpf.getXmlValue(this.data, xpath);
- };
-
- /**
- * Gets the value of an XMLNode based on a xpath statement executed on the data of this model.
- *
- * @param {String} xpath the xpath used to select a XMLNode.
- * @return {String} value of the XMLNode
- */
- this.queryValues = function(xpath){
- return jpf.getXmlValue(this.data, xpath);
- };
-
- /**
- * Executes an xpath statement on the data of this model
- *
- * @param {String} xpath the xpath used to select the XMLNode(s).
- * @return {variant} XMLNode or NodeList with the result of the selection
- */
- this.queryNode = function(xpath){
- return this.data.selectSingleNode(xpath)
- };
- /**
- * Executes an xpath statement on the data of this model
- *
- * @param {String} xpath the xpath used to select the XMLNode(s).
- * @return {variant} XMLNode or NodeList with the result of the selection
- */
- this.queryNodes = function(xpath){
- return this.data.selectNodes(xpath);
- };
-
- /**
- * Appends a copy of the xmlNode or model to this model as a child
- * of it's root node
- */
- this.appendXml = function(xmlNode){
- if (typeof xmlNode == "string")
- xmlNode = jpf.getXml(xmlNode);
-
- xmlNode = !model.nodeType //Check if a model was passed
- ? model.getXml()
- : jpf.xmldb.copyNode(xmlNode);
-
- if(!xmlNode) return;
-
- jpf.xmldb.appendChild(this.data, xmlNode);
- };
-
- /**
- * @private
- */
- this.getBindNode = function(bindId){
- var bindObj = jpf.nameserver.get("bind", bindId);
-
- if (!bindObj) {
- throw new Error(jpf.formatErrorString(0, this,
- "Binding Component", "Could not find bind element with name '"
- + x.getAttribute("bind") + "'"));
- }
-
- return bindObj;
- };
-
- /**
- * @private
- */
- this.isValid = function(){
- //Loop throug bind nodes and process their rules.
- for (var bindNode, i = 0; i < bindValidation.length; i++) {
- bindNode = bindValidation[i];
- if (!bindNode.isValid()) {
- //Not valid
- return false;
- }
- }
-
- //Valid
- return true;
- };
-
-
- /**
- * Clears the loaded data from this model.
- */
- this.clear = function(){
- this.load(null);
- doc = null; //Fix for safari refcount issue;
- };
-
- /**
- * Resets data in this model to the last saved point.
- *
- */
- this.reset = function(){
- this.load(this.copy);
-
- };
-
- /**
- * Sets a new saved point based on the current state of the data in this
- * model. The reset() method returns the model to this point.
- */
- this.savePoint = function(){
- this.copy = jpf.xmldb.copyNode(this.data);
- };
-
-
- /**
- * @private
- */
- this.reloadJmlNode = function(uniqueId){
- if (!this.data)
- return;
-
- var xmlNode = jmlNodes[uniqueId][1] ? this.data.selectSingleNode(jmlNodes[uniqueId][1]) : this.data;
- jmlNodes[uniqueId][0].load(xmlNode);
- };
-
- /* *********** PARSE ***********/
-
-
- var bindValidation = [], defSubmission, submissions = {},
- loadProcInstr, loadProcOptions;
-
- /**
- * @private
- */
- this.loadJml = function(x, parentNode){
- this.name = x.getAttribute("id");
- this.$jml = x;
-
- this.parentNode = parentNode;
- this.inherit(jpf.JmlDom); /** @inherits jpf.JmlDom */
-
- //Events
- var attr = x.attributes;
- for (var i = 0, l = attr.length; i < l; i++) {
- if (attr[i].nodeName.indexOf("on") == 0)
- this.addEventListener(attr[i].nodeName, new Function(attr[i].nodeValue));
- }
-
-
- if (x.getAttribute("save-original") == "true")
- this.saveOriginal = true;
-
- //Parse submissions
- var oSub;
-
- if (!defSubmission)
- defSubmission = x.getAttribute("submission"); //Javeline Extension on XForms
-
- this.submitType = x.getAttribute("submittype");
- this.useComponents = x.getAttribute("useComponents");
-
- //Session support
- this.session = x.getAttribute("session");
-
- //Find load string
- var instanceNode;
- loadProcInstr = jpf.parseExpression(x.getAttribute("load") || x.getAttribute("get"));
- if (!loadProcInstr) {
- var prefix = jpf.findPrefix(x, jpf.ns.jml);
- if (!jpf.supportNamespaces)
- if (prefix)
- (x.nodeType == 9
- ? x
- : x.ownerDocument).setProperty("SelectionNamespaces",
- "xmlns:" + prefix + "='" + jpf.ns.jml + "'");
- if (prefix)
- prefix += ":";
-
- var loadNode = x.selectSingleNode(prefix + "load");//$xmlns(x, "load", jpf.ns.jml)[0];
- if (loadNode)
- loadProcInstr = loadNode.getAttribute("get");
- }
-
- //Process bind nodes
-
- //Load literal model
- if (!oSub && !loadProcInstr) {
- var xmlNode = instanceNode || x;
- if (xmlNode.childNodes.length && jpf.getNode(xmlNode, [0])) {
- this.load((xmlNode.xml || xmlNode.serialize())
- .replace(new RegExp("^<" + xmlNode.tagName + "[^>]*>"), "")
- .replace(new RegExp("<\/\s*" + xmlNode.tagName + "[^>]*>$"), "")
- .replace(/xmlns=\"[^"]*\"/g, ""));
- }
- }
-
- //Default data for XForms models without an instance but with a submission node
- if (oSub && !this.data && !instanceNode)
- this.load("<data />");
-
- //Load data into model if allowed
- if (!jpf.isFalse(x.getAttribute("init")))
- this.init();
-
- //Connect to a remote smartbinding
- if (x.getAttribute("remote")) {
- this.rsb = jpf.nameserver.get("remote", x.getAttribute("remote"));
-
- if (!this.rsb || !this.rsb.models) {
- throw new Error(jpf.formatErrorString(0, null,
- "Loading JML into model",
- "Could not find reference to remote smartbinding: '"
- + x.getAttribute("remote") + "'", x))
- }
-
- this.rsb.models.push(this);
- }
-
-
- return this;
- };
-
- /**
- * Changes the jml element that provides data to this model.
- * Only relevant for models that are a connect proxy.
- * A connect proxy is set up like this:
- * Example:
- * <code>
- * <j:model connect="element_name" type="select" select="xpath" />
- * </code>
- *
- * @param {JMLElement} jmlNode the jml element to be registered.
- * @param {String} [type] select
- * Possible values:
- * default sents data when a node is selected
- * choice sents data when a node is chosen (by double clicking, or pressing enter)
- * @param {String} [select] an xpath query which is executed on the data of the model to select the node to be loaded in the jml element.
- */
- //Only when model is a connect proxy
- this.setConnection = function(jmlNode, type, select){
- if (!this.connect)
- this.connect = {};
- var oldNode = this.connect.node;
-
- this.connect.type = type;
- this.connect.node = jmlNode;
- this.connect.select = select;
-
- for (var uniqueId in jmlNodes) {
- if (oldNode)
- oldNode.disconnect(jmlNodes[uniqueId][0]);
- this.register(jmlNodes[uniqueId][0]);
- }
- };
-
- /**
- * Loads the initial data into this model
- */
- //callback here is private
- this.init = function(callback){
- if (this.session) {
- this.loadFrom(this.session, null, {isSession: true});
- }
- else {
- if (typeof jpf.offline != "undefined" && jpf.offline.models.enabled) {
- //Check if there's stored data
- if (jpf.offline.models.loadModel(this)) {
- return;
- }
-
- //Hmm we're offline, lets wait until we're online again
- //@todo this will ruin getting data from offline resources
- if (loadProcInstr && !jpf.offline.onLine) {
- jpf.offline.models.addToInitQueue(this);
- return;
- }
- }
-
- if (loadProcInstr)
- this.loadFrom(loadProcInstr, null, {callback: callback});
- //loadProcInstr = null;
- }
-
- };
-
- /* *********** LOADING ****************/
-
- /**
- * Loads data into this model using a data instruction.
- * @param {String} instruction the data instrution how to retrieve the data.
- * @param {XMLElement} xmlContext the xml data element that provides context to the data instruction.
- * @param {Object} options
- * Properties:
- * {Function} callback the code executed when the data request returns.
- * {mixed} <> Custom properties available in the data instruction.
- */
- this.loadFrom = function(instruction, xmlContext, options, callback){
- var data = instruction.split(":");
- var instrType = data.shift();
-
- if (!options || !options.isSession) {
- loadProcInstr = instruction;
- loadProcOptions = [instruction, xmlContext, options, callback];
- }
-
- if (!callback && options)
- callback = options.callback;
-
- /*
- Make connectiong with a jml element to get data streamed in
- from existing client side source
- */
- if (instrType.substr(0, 1) == "#") {
- instrType = instrType.substr(1);
-
- try {
- eval(instrType).test
- }
- catch (e) {
- throw new Error(jpf.formatErrorString(1031, null,
- "Model Creation", "Could not find object reference to \
- connect databinding: '" + instrType + "'", dataNode))
- }
-
- this.setConnection(eval(instrType), data[0] || "select", data[1]);
-
- return this;
- }
-
- //Loading data in non-literal model
- this.dispatchEvent("beforeretrieve");
-
- jpf.getData(instruction, xmlContext, options, function(data, state, extra){
- _self.dispatchEvent("afterretrieve");
-
- if (state == jpf.OFFLINE) {
- jpf.offline.models.addToInitQueue(this);
- return false;
- }
-
- if (state != jpf.SUCCESS) {
- var oError;
-
- oError = new Error(jpf.formatErrorString(1032,
- _self, "Inserting xml data", "Could not load data \
- Instruction:" + instruction + "\n\
- Url: " + extra.url + "\n\
- Info: " + extra.message + "\n\n" + data));
-
- if (extra.tpModule.retryTimeout(extra, state, _self, oError) === true)
- return true;
-
- throw oError;
- }
-
- if (options && options.isSession && !data) {
- if (loadProcInstr)
- return _self.loadFrom(loadProcInstr);
- }
- else {
- if (options && options.cancel)
- return;
-
- _self.load(data);
- _self.dispatchEvent("receive", {
- data: data
- });
-
- if (callback)
- callback.apply(this, arguments);
- }
- });
-
- return this;
- };
-
- this.reload = function(){
- if (!this.data)
- return;
-
- if (loadProcOptions)
- this.loadFrom.apply(this, loadProcOptions);
- else if (loadProcInstr)
- this.loadFrom(loadProcInstr);
- }
-
- /**
- * Loads data in this model
- *
- * @param {XMLElement} [xmlNode] the data to load in this model. null will clear the data from this model.
- * @param {Boolean} [nocopy] Wether the data loaded will not overwrite the reset point.
- */
- var doc;
- this.load = function(xmlNode, nocopy){
- if (this.dispatchEvent("beforeload", {xmlNode: xmlNode}) === false)
- return false;
-
- if (typeof xmlNode == "string")
- xmlNode = jpf.getXmlDom(xmlNode).documentElement;
-
- doc = xmlNode ? xmlNode.ownerDocument : null; //Fix for safari refcount issue;
-
- //FU IE
- //if(jpf.isIE) xmlNode.ownerDocument.setProperty("SelectionNamespaces", "xmlns:j='http://www.javeline.com/2001/PlatForm'");
-
- if (xmlNode) {
- jpf.xmldb.nodeConnect(
- jpf.xmldb.getXmlDocId(xmlNode, this), xmlNode, null, this);
-
- if (!nocopy && this.saveOriginal)
- this.copy = jpf.xmldb.copyNode(xmlNode);
- }
-
- this.data = xmlNode;
-
- var uniqueId;
- for (uniqueId in jmlNodes) {
- if (!jmlNodes[uniqueId] || !jmlNodes[uniqueId][0])
- continue;
-
- this.loadInJmlNode(jmlNodes[uniqueId][0], jmlNodes[uniqueId][1]);
- //var xmlNode = this.data ? (jmlNodes[uniqueId][1] ? this.data.selectSingleNode(jmlNodes[uniqueId][1]) : this.data) : null;
- //jmlNodes[uniqueId][0].load(xmlNode);
- }
-
- this.dispatchEvent("afterload", {xmlNode: xmlNode});
-
- return this;
- };
-
- /**** INSERT ****/
-
- /**
- * Inserts data into the data of this model using a data instruction.
- * @param {String} instruction the data instrution how to retrieve the data.
- * @param {XMLElement} xmlContext the xml data element that provides context to the data instruction.
- * @param {Object} options
- * Properties:
- * {XMLElement} insertPoint the parent element for the inserted data.
- * {mixed} <> Custom properties available in the data instruction.
- * @param {Function} callback the code executed when the data request returns.
- */
- this.insertFrom = function(instruction, xmlContext, options, callback){
- if (!instruction) return false;
-
- this.dispatchEvent("beforeretrieve");
-
- var jmlNode = options.jmlNode;
-
- jpf.getData(instruction, xmlContext, options, function(data, state, extra){
- _self.dispatchEvent("afterretrieve");
-
- if (state != jpf.SUCCESS) {
- var oError;
-
- oError = new Error(jpf.formatErrorString(1032,
- _self, "Inserting xml data", "Could not insert data for \
- Instruction:" + instruction + "\n\
- Url: " + extra.url + "\n\
- Info: " + extra.message + "\n\n" + data));
-
- if (extra.tpModule.retryTimeout(extra, state,
- jmlNode ||
- _self, oError) === true)
- return true;
-
- throw oError;
- }
-
- if (!options.insertPoint) {
- throw new Error(jpf.formatErrorString(0, jmlNode || _self,
- "Inserting data", "Could not determine insertion point for \
- instruction: " + instruction));
- }
-
- //Checking for xpath
- if (typeof options.insertPoint == "string")
- insertPoint = _self.data.selectSingleNode(options.insertPoint);
-
- //Call insert function
- (options.jmlNode || _self).insert(data, options.insertPoint, jpf.extend({
- clearContents: jpf.isTrue(extra.userdata[1])
- }, options));
-
- if (callback)
- callback.call(this, extra.data);
- });
- };
-
- /**
- * Inserts data in this model as a child of the currently loaded data.
- *
- * @param {XMLElement} XMLRoot the xml data element to insert into this model.
- * @param {XMLElement} [parentXMLNode] the parent element for the inserted data.
- */
- this.insert = function(XMLRoot, parentXMLNode, options, jmlNode){
- if (typeof XMLRoot != "object")
- XMLRoot = jpf.getXmlDom(XMLRoot).documentElement;
- if (!parentXMLNode)
- parentXMLNode = this.data;
-
- //if(this.dispatchEvent("beforeinsert", parentXMLNode) === false) return false;
-
- //Integrate XMLTree with parentNode
- var newNode = jpf.xmldb.integrate(XMLRoot, parentXMLNode,
- jpf.extend({copyAttributes: true}, options));
-
- //Call __XMLUpdate on all listeners
- jpf.xmldb.applyChanges("insert", parentXMLNode);
-
- //this.dispatchEvent("afterinsert");
-
- return XMLRoot;
- };
-
- /* *********** SUBMISSION ****************/
-
- //Json
- /**
- * Retrieves a json representation of the data in this model
- * @return {Object}
- * @todo rewrite this function
- */
- this.getJsonObject = function(){
- var data = {};
-
- for (var p in this.elements) {
- var name = this.elements[p].$jml.getAttribute("name") || this.elements[p].name;
- if (name)
- data[name] = this.elements[p].getValue();
- }
-
- return data;
- };
-
- //URL encoded
- /**
- * Retrieves a cgi string representation of the data in this model.
- * @return {String}
- */
- this.getCgiString = function(){
- //use components
- var uniqueId, k, sel, oJmlNode, name, value, str = [];
-
- for (uniqueId in jmlNodes) {
- oJmlNode = jmlNodes[uniqueId][0];
- //if(!elements[i].active) continue;
- if (oJmlNode.disabled || !oJmlNode.change && !oJmlNode.hasFeature(__MULTISELECT__))
- continue;
- if (oJmlNode.tagName == "MultiBinding")
- oJmlNode = oJmlNode.getHost();
-
- if (oJmlNode.multiselect) {
- sel = oJmlNode.getSelection();
- for (k = 0; k < sel.length; k++) {
- name = oJmlNode.$jml.getAttribute("name");//oJmlNode.$jml.getAttribute("id")
- if (!name && oJmlNode.$jml.getAttribute("ref"))
- name = oJmlNode.$jml.getAttribute("ref").replace(/[\/\]\[@]/g, "_");
- if (!name)
- name = sel[k].tagName;
- if (!name.match(/\]$/))
- name += "[]";
-
- value = oJmlNode.applyRuleSetOnNode("value", sel[k])
- || oJmlNode.applyRuleSetOnNode("caption", sel[k]);
- if (value)
- str.push(name + "=" + encodeURIComponent(value));
- }
- }
- else {
- name = oJmlNode.$jml.getAttribute("name")
- || oJmlNode.$jml.getAttribute("id");
- if (!name && oJmlNode.$jml.getAttribute("ref"))
- name = oJmlNode.$jml.getAttribute("ref").replace(/[\/\]\[@]/g, "_");
- if (!name && oJmlNode.xmlRoot)
- name = oJmlNode.xmlRoot.tagName;
-
- if (!name)
- continue;
-
- value = oJmlNode.getValue();//oJmlNode.applyRuleSetOnNode(oJmlNode.mainBind, oJmlNode.xmlRoot);
- if (value)
- str.push(name + "=" + encodeURIComponent(value));
- }
- }
-
- return str.join("&");
- };
-
- /**
- * Submit the data of the model to a data source.
- * @param {String} instruction the id of the submission element or the data instruction on how to sent data to the data source.
- * @param {String} type how to serialize the data, and how to sent it.
- * Possible values:
- * post sent xml using the http post protocol. (application/xml)
- * get sent urlencoded form data using the http get protocol. (application/x-www-form-urlencoded)
- * put sent xml using the http put protocol. (application/xml)
- * multipart-post not implemented (multipart/related)
- * form-data-post not implemented (multipart/form-data)
- * urlencoded-post sent urlencoded form data using the http get protocol. (application/x-www-form-urlencoded)
- * @todo: PUT ??
- * @todo: build in instruction support
- */
- this.submit = function(instruction, xmlNode, type, useComponents, xSelectSubTree){
- if (!this.isValid()) {
- this.dispatchEvent("submiterror");
- return;
- }
-
- if (!instruction && !defSubmission)
- return false;
- if (!xmlNode)
- xmlNode = this.data;
- if (!instruction && typeof defSubmission == "string")
- instruction = defSubmission;
-
- if (!xmlNode) {
- throw new Error(jpf.formatErrorString(0, this,
- "Submitting model",
- "Could not submit data, because no data was passed and the \
- model does not have data loaded."));
- }
-
- //First check if instruction is a known submission
- var sub;
- if (submissions[instruction] || !instruction && defSubmission) {
- sub = submissions[instruction] || defSubmission;
-
- //<j:submission id="" ref="/" bind="" action="url" method="post|get|urlencoded-post" set="" />
- useComponents = false;
- type = sub.getAttribute("method")
- .match(/^(?:urlencoded-post|get)$/) ? "native" : "xml";
- xSelectSubTree = sub.getAttribute("ref") || "/";//Bind support will come later
- instruction = (sub.getAttribute("method")
- .match(/post/) ? "url.post:" : "url:") + sub.getAttribute("action");
- var file = sub.getAttribute("action");
-
- //set contenttype oRpc.contentType
- }
- else
- if (instruction) {
- if (!type)
- type = this.submitType || "native";
- if (!useComponents)
- useComponents = this.useComponents;
- }
- else {
- throw new Error(jpf.formatErrorString(0, "Submitting a Model", "Could not find a submission with id '" + id + "'"));
- }
-
- //if(type == "xml" || type == "post")
- // throw new Error(jpf.formatErrorString(0, this, "Submitting form", "This form has no model specified", this.$jml));
-
- if (this.dispatchEvent("beforesubmit", {
- instruction: instruction
- }) === false)
- return false;
-
-
- //this.showLoader();
-
- var model = this;
- function cbFunc(data, state, extra){
- if ((state == jpf.TIMEOUT
- || (_self.retryOnError && state == jpf.ERROR))
- && extra.retries < jpf.maxHttpRetries)
- return extra.tpModule.retry(extra.id);
- else
- if (state != jpf.SUCCESS) {
- model.dispatchEvent("submiterror", extra);
-
- }
- else {
- model.dispatchEvent("submitsuccess", jpf.extend({
- data: data
- }, extra));
-
- }
-
- //this.hideLoader();
- }
-
- if (type == "array" || type == "xml") {
- var data = type == "array"
- ? this.getJsonObject()
- : jpf.xmldb.serializeNode(xmlNode);
-
- jpf.saveData(instruction, xmlNode, {args : [data]}, cbFunc);
- }
- else {
- var data = useComponents
- ? this.getCgiString()
- : jpf.xmldb.convertXml(jpf.xmldb.copyNode(xmlNode), type != "native" ? type : "cgivars");
-
- if (instruction.match(/^rpc\:/)) {
- rpc = rpc.split(".");
- var oRpc = self[rpc[0]];
- oRpc.callWithString(rpc[1], data, cbFunc);
- //Loop throught vars
- //Find components with the same name
- //Set arguments and call method
- }
- else {
- if (instruction.match(/^url/))
- instruction += (instruction.match(/\?/) ? "&" : "?") + data;
-
- jpf.saveData(instruction, xmlNode, null, cbFunc);
- }
- }
-
- this.dispatchEvent("aftersubmit");
- };
-
- this.$destroy = function(){
- if (this.session && this.data)
- jpf.saveData(this.session, this.getXml());
- };
-};
-
-
- - -/*FILEHEAD(/var/lib/jpf/src/elements/xslt.js)SIZE(-1077090856)TIME(1238933683)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-/**
- * Element displaying the contents of an xslt transformation on
- * the bound dataset.
- *
- * @todo please test this, especially the clear function.
- * @constructor
- * @allowchild [cdata]
- * @addnode elements:jslt
- *
- * @inherits jpf.DataBinding
- *
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.9
- */
-jpf.xslt = jpf.component(jpf.NODE_VISIBLE, function(){
- this.$hasStateMessages = true;
- // DATABINDING
- this.mainBind = "contents";
-
- // INIT
- this.parse = function(code){
- this.setProperty("value", code);
- };
-
- this.$clear = function(a, b){
- if (b == true) {
- this.oInt.innerHTML = "";//alert(a+"-"+b);
- this.setProperty("value", "");
- }
- };
-
- this.$supportedProperties.push("value");
- this.$propHandlers["value"] = function(code){
- if (this.createJml) {
- if (typeof code == "string")
- code = jpf.xmldb.getXml(code);
- // To really make it dynamic, the objects created should be
- // deconstructed and the xml should be attached and detached
- // of the this.$jml xml.
- jpf.JmlParser.parseChildren(code, this.oInt, this);
- if (jpf.JmlParser.inited)
- jpf.JmlParser.parseLastPass();
- }
- else {
- this.oInt.innerHTML = code;
- }
- };
-
- this.$draw = function(){
- //Build Main Skin
- //alert("REDRAW");
- this.oInt = this.oExt = (this.$jml.parentNode.lastChild == this.$jml.parentNode.firstChild)
- ? pHtmlNode
- : pHtmlNode.appendChild(document.createElement("div"));
- if (this.$jml.getAttribute("cssclass"))
- this.oExt.className = this.$jml.getAttribute("cssclass");
- };
-
- this.$loadJml = function(x){
- this.createJml = jpf.isTrue(x.getAttribute("jml"));
-
- var nodes = x.childNodes;
- if (nodes.length) {
- var bind = x.getAttribute("ref") || ".";
- x.removeAttribute("ref");
- //<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'><xsl:template match='"
- //+ bind + "'></xsl:template></xsl:stylesheet>
- var strBind = "<smartbinding xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>\
- <bindings><contents select='" + bind + "'>\
- </contents></bindings></smartbinding>";
- var xmlNode = jpf.xmldb.getXml(strBind);
- var tNode = xmlNode.firstChild.firstChild;//.firstChild.firstChild
- for (var i = 0; i < nodes.length; i++) {
- //if(tNode.ownerDocument.importNode
- tNode.appendChild(nodes[i]);
- }
-
- jpf.JmlParser.addToSbStack(this.uniqueId, new jpf.smartbinding(null, xmlNode));
- }
- };
-}).implement(
- jpf.DataBinding
-);
- - -/*FILEHEAD(/var/lib/jpf/src/elements/frame.js)SIZE(-1077090856)TIME(1238944817)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * Element displaying a frame with a caption containing other elements. This
- * element is called a fieldset in html.
- * Example:
- * <code>
- * <j:frame caption="Options">
- * <j:radiobutton value="1">Option 1</j:radiobutton>
- * <j:radiobutton value="2">Option 2</j:radiobutton>
- * <j:radiobutton value="3">Option 3</j:radiobutton>
- * <j:radiobutton value="4">Option 4</j:radiobutton>
- * </j:frame>
- * </code>
- *
- * @constructor
- * @define fieldset, frame
- * @allowchild {elements}, {anyjml}
- * @addnode elements:frame
- *
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.9
- *
- * @inherits jpf.Presentation
- */
-jpf.fieldset =
-jpf.frame = jpf.component(jpf.NODE_VISIBLE, function(){
- this.canHaveChildren = true;
- this.$focussable = false;
-
- this.editableParts = {"main" : [["caption", "@caption"]]};
-
- /**** Properties and Attributes ****/
-
- /**
- * @attribute {String} caption the text of the caption.
- */
- this.$supportedProperties.push("caption");
- this.$propHandlers["caption"] = function(value){
- if (this.oCaption)
- this.oCaption.nodeValue = value;
- };
-
- /**
- * Sets the text of the title of this element
- * @param {String} value the text of the title.
- */
- this.setTitle = function(value){
- this.setProperty("title", value);
- };
-
- /**** Init ****/
-
- this.$draw = function(){
- //Build Main Skin
- this.oExt = this.$getExternal();
- this.oCaption = this.$getLayoutNode("main", "caption", this.oExt);
- var oInt = this.$getLayoutNode("main", "container", this.oExt);
-
- this.$makeEditable("main", this.oExt, this.$jml);
-
- this.oInt = this.oInt
- ? jpf.JmlParser.replaceNode(oInt, this.oInt)
- : jpf.JmlParser.parseChildren(this.$jml, oInt, this);
- };
-
- this.$loadJml = function(x){
- };
-}).implement(jpf.Presentation);
-
- - -/*FILEHEAD(/var/lib/jpf/src/elements/calendar.js)SIZE(-1077090856)TIME(1238944817)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-/**
- * Element displaying a list of day numbers in a grid, ordered by week. It
- * allows the user to choose the month and year for which to display the days.
- * Calendar returns a date in chosen date format. Minimal size of calendar is
- * 150px.
- *
- * Example:
- * Calendar component with date set on "Saint Nicholas Day" in iso date format
- * <code>
- * <j:calendar top="200" left="400" output-format="yyyy-mm-dd" value="2008-12-06" />
- * </code>
- *
- * @constructor
- * @define calendar
- * @addnode elements
- *
- * @attribute {String} output-format style of returned date
- * @attribute {String} default name which represent some date
- * Possible values:
- * today calendar is set on today's date
- * @attribute {String} value the date returned by calendar; should be in the
- * same format as output-format
- *
- * @inherits jpf.Presentation
- * @inherits jpf.DataBinding
- * @inherits jpf.Validation
- * @inherits jpf.XForms
- *
- * @author Lukasz Lipinski
- * @version %I%, %G%
- * @since 1.0
- *
- * @binding value Determines the way the value for the element is retrieved
- * from the bound data.
- * Example:
- * Sets the date based on data loaded into this component.
- * <code>
- * <j:calendar>
- * <j:bindings>
- * <j:value select="@date" />
- * </j:bindings>
- * </j:calendar>
- * </code>
- * Example:
- * A shorter way to write this is:
- * <code>
- * <j:calendar ref="@date" />
- * </code>
- */
-jpf.calendar = jpf.component(jpf.NODE_VISIBLE, function() {
-
- /**** Properties and Attributes ****/
- this.reselectable = true;
- this.$focussable = true;
- this.autoselect = false;
- this.multiselect = false;
- this.disableremove = true;
- this.outputFormat = null;
-
- var _day = null,
- _month = null,
- _year = null,
- _hours = 1,
- _minutes = 0,
- _seconds = 0,
- _currentMonth = null,
- _currentYear = null,
- _numberOfDays = null,
- _dayNumber = null,
- _temp = null;
-
- var _width = null;
-
- var days = ["Sunday", "Monday", "Tuesday", "Wednesday",
- "Thursday", "Friday", "Saturday"];
- var months = [{name : "January", number : 31},
- {name : "February", number : 28},
- {name : "March", number : 31},
- {name : "April", number : 30},
- {name : "May", number : 31},
- {name : "June", number : 30},
- {name : "July", number : 31},
- {name : "August", number : 31},
- {name : "September", number : 30},
- {name : "October", number : 31},
- {name : "November", number : 30},
- {name : "December", number : 31}];
-
- var _self = this;
-
- this.$booleanProperties["disableremove"] = true;
-
- this.$supportedProperties.push("disableremove", "initial-message",
- "output-format", "default");
-
- jpf.onload = function() {
- _self.redraw(_month, _year);
- }
-
- this.$propHandlers["output-format"] = function(value) {
- if (this.value) {
- this.setProperty("value", new Date(_year, _month, _day, _hours,
- _minutes, _seconds).format(this.outputFormat = value));
- }
- else
- this.outputFormat = value;
- }
-
- this.$propHandlers["value"] = function(value) {
- if (!this.outputFormat) {
- _temp = value;
- return;
- }
-
- var date = Date.parse(value, this.outputFormat);
-
- if (!date) {
- throw new Error(jpf.formErrorString(this, "Parsing date",
- "Invalid date: " + value));
- }
-
- _day = date.getDate();
- _month = date.getMonth();
- _year = date.getFullYear();
- _hours = date.getHours();
- _minutes = date.getMinutes();
- _seconds = date.getSeconds();
-
- this.value = value;
- this.redraw(_month, _year);
- }
-
- /**** Public methods ****/
-
- this.setValue = function(value) {
- this.setProperty("value", value);
- };
-
- this.getValue = function() {
- return this.value;
- };
-
- /**** Keyboard Support ****/
-
- this.addEventListener("keydown", function(e) {
- e = e || event;
-
- var key = e.keyCode,
- ctrlKey = e.ctrlKey,
- shiftKey = e.shiftKey;
-
- switch (key) {
- case 13: /* enter */
- this.selectDay(_day);
- break;
-
- case 33: /* page up */
- this.nextMonth();
- break;
-
- case 34: /* page down */
- this.prevMonth();
- break;
-
- case 37: /* left arrow */
- if (ctrlKey)
- this.prevMonth();
- else if (shiftKey)
- this.prevYear();
- else {
- if (_day - 1 < 1) {
- this.prevMonth();
- this.selectDay(months[_currentMonth].number);
- }
- else {
- this.selectDay(_day - 1);
- }
- }
- break;
-
- case 38: /* up arrow */
- if (_day - 7 < 1) {
- this.prevMonth();
- this.selectDay(months[_currentMonth].number + _day - 7);
- }
- else {
- this.selectDay(_day - 7);
- }
- break;
-
- case 39: /* right arrow */
- if (ctrlKey)
- this.nextMonth();
- else if (shiftKey)
- this.nextYear();
- else
- this.selectDay(_day + 1);
- break;
-
- case 40: /* down arrow */
- this.selectDay(_day + 7);
- break;
-
- case 84:
- if (ctrlKey)
- this.today();
- return false;
- break;
- }
- }, true);
-
- this.$blur = function() {
- this.$setStyleClass(this.oExt, "", [this.baseCSSname + "Focus"]);
- };
-
- this.$focus = function(){
- this.$setStyleClass(this.oFocus || this.oExt, this.baseCSSname + "Focus");
- }
-
- var isLeapYear = function(year) {
- return ((year % 4 == 0) && (year % 100 !== 0)) || (year % 400 == 0)
- ? true
- : false;
- };
-
- this.redraw = function(month, year) {
- _currentMonth = month;
- _currentYear = year;
-
- _width = this.oExt.offsetWidth;
-
- this.oNavigation.style.width = (Math.floor((_width - 36) / 8) * 8 + 32
- - jpf.getDiff(this.oNavigation)[0]) + "px";
-
- var w_firstYearDay = new Date(year, 0, 1);
- var w_dayInWeek = w_firstYearDay.getDay();
- var w_days = w_dayInWeek;
-
- for (i = 0; i <= month; i++) {
- if (isLeapYear(year) && i == 1)
- w_days++;
- w_days += months[i].number;
- }
-
- var w_weeks = Math.ceil(w_days / 7);
-
- var date = new Date(year, month);
-
- _numberOfDays = months[date.getMonth()].number;
- if (isLeapYear(year) && date.getMonth() == 1)
- _numberOfDays++;
-
- _dayNumber = new Date(year, month, 1).getDay();
- var prevMonth = month == 0 ? 11 : month - 1;
- var prevMonthDays = months[prevMonth].number - _dayNumber + 1;
-
- var nextMonthDays = 1;
-
- var rows = this.oNavigation.childNodes;
- for (i = 0; i < rows.length; i++) {
- if ((rows[i].className || "").indexOf("today") != -1) {
- if (_width < 300) {
- rows[i].style.width = "10px";
- rows[i].innerHTML = "T";
- }
- else {
- rows[i].innerHTML = "Today";
- }
- }
- else if ((rows[i].className || "").indexOf("status") != -1) {
- if (_width >= 300)
- rows[i].innerHTML = months[_currentMonth].name
- + " " + _currentYear;
- else {
- rows[i].innerHTML = (_currentMonth + 1) + "/" + _currentYear;
- rows[i].style.width = "40px";
- rows[i].style.marginLeft = "-20px";
- }
- }
- }
-
- var squareSize = Math.floor((_width - 37) / 8);
-
- var daysofweek = this.oDow.childNodes;
- this.oDow.style.width = (squareSize * 8 + 32) + "px";
- this.oNavigation.style.width = (squareSize * 8 + 32)
- - jpf.getDiff(this.oNavigation)[0] + "px";
-
- for (var z = 0, i = 0; i < daysofweek.length; i++) {
- if ((daysofweek[i].className || "").indexOf("dayofweek") > -1) {
- daysofweek[i].style.width = squareSize + "px";
- daysofweek[i].style.height = Math.floor((squareSize / 2 + 12) / 2)
- + "px";
- daysofweek[i].style.paddingTop = Math.max(squareSize / 2 - 3
- - (Math.floor((squareSize / 2 + 12 -2) / 2)), 0) + "px";
-
- if (squareSize / 2 < 9) {
- daysofweek[i].style.fontSize = "9px";
- }
-
- if (z > 0) {
- daysofweek[i].innerHTML = days[z - 1].substr(0, 3);
- }
- z++;
- }
- }
-
- rows = this.oExt.childNodes;
- for (z = 0, y = 0, i = 0; i < rows.length; i++) {
- if ((rows[i].className || "").indexOf("row") == -1)
- continue;
-
- rows[i].style.width = (squareSize * 8 + 32) + "px";
- if (!jpf.isGecko) {
- rows[i].style.paddingTop = "1px";
- }
-
- cells = rows[i].childNodes;
- for (var j = 0, disabledRow = 0; j < cells.length; j++) {
- if ((cells[j].className || "").indexOf("cell") == -1)
- continue;
- z++;
- cells[j].style.width = squareSize + "px";
- cells[j].style.height = Math.floor((squareSize + 12) / 2) + "px";
- cells[j].style.paddingTop = squareSize
- - (Math.floor((squareSize + 12) / 2))
- + "px";
-
- this.$setStyleClass(cells[j], "", ["weekend", "disabled",
- "active", "prev", "next"]);
-
- if ((z - 1) % 8 == 0) {
- cells[j].innerHTML = w_weeks
- - Math.ceil((months[_month].number + _dayNumber) / 7)
- + 1 + (z - 1) / 8;
- }
- else {
- y++;
- if (y <= _dayNumber) {
- cells[j].innerHTML = prevMonthDays++;
- this.$setStyleClass(cells[j], "disabled prev");
- }
- else if (y > _dayNumber && y <= _numberOfDays + _dayNumber) {
- cells[j].innerHTML = y - _dayNumber;
-
- var dayNrWeek = new Date(year, month,
- y - _dayNumber).getDay();
-
- if (dayNrWeek == 0 || dayNrWeek == 6) {
- this.$setStyleClass(cells[j], "weekend");
- }
-
- if (month == _month && year == _year
- && y - _dayNumber == _day) {
- this.$setStyleClass(cells[j], "active");
- }
- }
- else if (y > _numberOfDays + _dayNumber) {
- cells[j].innerHTML = nextMonthDays++;
- this.$setStyleClass(cells[j], "disabled next");
- disabledRow++;
- }
- }
- }
-
- if (!this.height) {
- rows[i].style.display = disabledRow == 7
- ? "none"
- : "block";
- }
- else {
- rows[i].style.visibility = disabledRow == 7
- ? "hidden"
- : "visible";
- }
- }
- };
-
- /**
- * Change choosen date with selected and highlight its cell in calendar
- * component
- *
- * @param {Number} nr day number
- * @param {String} type class name of html representation of selected cell
- */
- this.selectDay = function(nr, type) {
- var newMonth = type == "prev"
- ? _currentMonth
- : (type == "next"
- ? _currentMonth + 2
- : _currentMonth + 1);
-
- var newYear = _currentYear;
-
- if (newMonth < 1) {
- newMonth = 12;
- newYear--;
- }
- else if (newMonth > 12) {
- newMonth = 1;
- newYear++;
- }
-
- this.change(new Date(newYear, (newMonth - 1), nr, _hours, _minutes,
- _seconds).format(this.outputFormat));
- };
-
- /**
- * Change displayed year to next
- */
- this.nextYear = function() {
- this.redraw(_currentMonth, _currentYear + 1);
- };
-
- /**
- * Change displayed year to previous
- */
- this.prevYear = function() {
- this.redraw(_currentMonth, _currentYear - 1);
- };
-
- /**
- * Change displayed month to next. If actual month is December, function
- * change current displayed year to next
- */
- this.nextMonth = function() {
- var newMonth, newYear;
- if (_currentMonth > 10) {
- newMonth = 0;
- newYear = _currentYear + 1;
- }
- else {
- newMonth = _currentMonth + 1;
- newYear = _currentYear;
- }
-
- this.redraw(newMonth, newYear);
- };
-
- /**
- * Change displayed month to previous. If actual month is January, function
- * change current displayed year to previous
- */
- this.prevMonth = function() {
- var newMonth, newYear;
- if (_currentMonth < 1) {
- newMonth = 11;
- newYear = _currentYear - 1;
- }
- else {
- newMonth = _currentMonth - 1;
- newYear = _currentYear;
- }
-
- this.redraw(newMonth, newYear);
- };
-
- /**
- * Select today's date on calendar component
- */
- this.today = function() {
- this.setProperty("value", new Date().format(this.outputFormat));
- };
-
- /**** Init ****/
-
- this.$draw = function() {
- this.$animType = this.$getOption("main", "animtype") || 1;
- this.clickOpen = this.$getOption("main", "clickopen") || "button";
-
- //Build Main Skin
- this.oExt = this.$getExternal("main", null, function(oExt) {
- var oExt = this.$getLayoutNode("main", "contents", oExt);
-
- for (var i = 0; i < 6; i++) {
- this.$getNewContext("row");
- var oRow = oExt.appendChild(this.$getLayoutNode("row"));
-
- for (var j = 0; j < 8; j++) {
- this.$getNewContext("cell");
- var oCell = this.$getLayoutNode("cell");
- if (j > 0) {
- oCell.setAttribute("onmouseover",
- "if (this.className.indexOf('disabled') > -1 "
- + "|| this.className.indexOf('active') > -1) "
- + "return; jpf.lookup(" + this.uniqueId
- + ").$setStyleClass(this, 'hover');");
- oCell.setAttribute("onmouseout",
- "var o = jpf.lookup(" + this.uniqueId
- + ").$setStyleClass(this, '', ['hover']);");
- oCell.setAttribute("onmousedown",
- "var o = jpf.lookup(" + this.uniqueId + ");"
- + " if (this.className.indexOf('prev') > -1) { "
- + "o.selectDay(this.innerHTML, 'prev');}"
- + " else if (this.className.indexOf('next') > -1) {"
- + "o.selectDay(this.innerHTML, 'next');}"
- + " else {o.selectDay(this.innerHTML);}");
- }
- oRow.appendChild(oCell);
- }
- }
-
- var oNavigation = this.$getLayoutNode("main", "navigation", oExt);
-
- if (oNavigation) {
- var buttons = ["prevYear", "prevMonth", "nextYear", "nextMonth",
- "today", "status"];
- for (var i = 0; i < buttons.length; i++) {
- this.$getNewContext("button");
- var btn = oNavigation.appendChild(this.$getLayoutNode("button"));
- this.$setStyleClass(btn, buttons[i]);
- if (buttons[i] !== "status")
- btn.setAttribute("onmousedown", 'jpf.lookup('
- + this.uniqueId + ').'
- + buttons[i] + '()');
- }
- }
-
- var oDaysOfWeek = this.$getLayoutNode("main", "daysofweek", oExt);
-
- for (var i = 0; i < days.length + 1; i++) {
- this.$getNewContext("day");
- oDaysOfWeek.appendChild(this.$getLayoutNode("day"));
- }
- });
-
- this.oNavigation = this.$getLayoutNode("main", "navigation", this.oExt);
- this.oDow = this.$getLayoutNode("main", "daysofweek", this.oExt);
- };
-
- this.$loadJml = function(x) {
- if (typeof this.value == "undefined") {
- switch(this["default"]) {
- case "today":
- this.setProperty("value", new Date().format(this.outputFormat));
- break;
- default :
- var date = new Date();
- _day = date.getDate();
- _month = date.getMonth();
- _year = date.getFullYear();
-
- if (!this.selected && this.initialMsg)
- this.$setLabel();
- break;
- }
- }
- else {
- var date = Date.parse(_temp || this.value, this.outputFormat);
- _day = date.getDate();
- _month = date.getMonth();
- _year = date.getFullYear();
-
- this.setProperty("value", new Date(_year, _month, _day, _hours, _minutes, _seconds).format(this.outputFormat));
- }
- };
-
-
- this.$destroy = function() {
- jpf.popup.removeContent(this.uniqueId);
- jpf.removeNode(this.oExt);
- this.oCalendar = null;
- };
-}).implement(
- jpf.DataBinding,
- jpf.Validation,
- jpf.Presentation
-);
-
- - -/*FILEHEAD(/var/lib/jpf/src/elements/spinner.js)SIZE(-1077090856)TIME(1238944817)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-/**
- * This element is used to choosing number by plus/minus buttons.
- * When plus button is clicked longer, number growing up faster. The same
- * situation is for minus button. It's possible to increment and decrement
- * value by moving mouse cursor up or down with clicked input. Max and
- * min attributes define range with allowed values.
- *
- * Example:
- * Spinner element with start value equal 6 and allowed values from range
- * (-100, 200)
- *
- * <code>
- * <j:spinner value="6" min="-99" max="199"></j:spinner>
- * </code>
- *
- * @attribute {Number} max maximal allowed value, default is 64000
- * @attribute {Number} min minimal allowed value, default is -64000
- * @attribute {Number} value actual value displayed in component
- *
- * @classDescription This class creates a new spinner
- * @return {Spinner} Returns a new spinner
- *
- * @author
- * @version %I%, %G%
- *
- * @inherits jpf.Presentation
- * @inherits jpf.DataBinding
- * @inherits jpf.Validation
- * @inherits jpf.XForms
- *
- * @binding value Determines the way the value for the element is retrieved
- * from the bound data.
- * Example:
- * Sets the value based on data loaded into this component.
- * <code>
- * <j:spinner>
- * <j:bindings>
- * <j:value select="@value" />
- * </j:bindings>
- * </j:spinner>
- * </code>
- * Example:
- * A shorter way to write this is:
- * <code>
- * <j:spinner ref="@value" />
- * </code>
- */
-jpf.spinner = jpf.component(jpf.NODE_VISIBLE, function() {
- this.max = 64000;
- this.min = -64000;
- this.focused = false;
- this.value = 0;
-
- var lastvalue = 0;
- var _self = this;
-
- this.$supportedProperties.push("width", "value", "max", "min", "caption");
-
- this.$propHandlers["value"] = function(value) {
- value = parseInt(value) || 0;
-
- if (/^(0|[\-]?[1-9][0-9]*)$/.test(value) &&
- (value || value == 0) && value <= _self.max && value >= _self.min) {
- this.value = this.oInput.value = lastvalue = value;
- }
- else {
- this.value = this.oInput.value = lastvalue;
- }
- };
-
- this.$propHandlers["min"] = function(value) {
- if (parseInt(value)) {
- this.min = parseInt(value);
- if (value > this.value) {
- this.change(value);
- }
- }
- };
-
- this.$propHandlers["max"] = function(value) {
- if (parseInt(value)) {
- this.max = parseInt(value);
- if(value < this.value) {
- this.change(value);
- }
- }
- };
-
- /* ********************************************************************
- PUBLIC METHODS
- *********************************************************************/
-
- this.setValue = function(value) {
- this.setProperty("value", value);
- };
-
- this.getValue = function() {
- return this.value;
- };
-
- this.$enable = function() {
- this.oInput.disabled = false;
- this.$setStyleClass(this.oInput, "", ["inputDisabled"]);
- };
-
- this.$disable = function() {
- this.oInput.disabled = true;
- this.$setStyleClass(this.oInput, "inputDisabled");
- };
-
- this.$focus = function(e) {
- if (!this.oExt || this.disabled || this.focused)
- return;
-
- if (jpf.hasFocusBug)
- jpf.sanitizeTextbox(this.oInput);
-
- this.focused = true;
- this.$setStyleClass(this.oInput, "focus");
- this.$setStyleClass(this.oButtonPlus, "plusFocus");
- this.$setStyleClass(this.oButtonMinus, "minusFocus");
- };
-
- this.$blur = function(e) {
- if (!this.oExt && !this.focused)
- return;
-
- this.$setStyleClass(this.oInput, "", ["focus"]);
- this.$setStyleClass(this.oButtonPlus, "", ["plusFocus"]);
- this.$setStyleClass(this.oButtonMinus, "", ["minusFocus"]);
- this.focused = false;
- }
-
- /* ***********************
- Keyboard Support
- ************************/
- this.addEventListener("keydown", function(e) {
- var key = e.keyCode;
-
- var keyAccess = (key < 8 || (key > 8 && key < 37 && key !== 12)
- || (key > 40 && key < 46) || (key > 46 && key < 48)
- || (key > 57 && key < 96) || (key > 105 && key < 109)
- || (key > 109 && key !== 189));
-
- if (keyAccess)
- return false;
-
- }, true);
-
- this.addEventListener("keyup", function(e) {
- this.setValue(this.oInput.value);
- }, true);
-
- /**
- * @event click Fires when the user presses a mousebutton while over this element and then let's the mousebutton go.
- * @event mouseup Fires when the user lets go of a mousebutton while over this element.
- * @event mousedown Fires when the user presses a mousebutton while over this element.
- */
- this.$draw = function() {
- //Build Main Skin
- this.oExt = this.$getExternal(null, null, function(oExt) {
- oExt.setAttribute("onmousedown",
- 'this.host.dispatchEvent("mousedown", {htmlEvent : event});');
- oExt.setAttribute("onmouseup",
- 'this.host.dispatchEvent("mouseup", {htmlEvent : event});');
- oExt.setAttribute("onclick",
- 'this.host.dispatchEvent("click", {htmlEvent : event});');
- });
-
- this.oInt = this.$getLayoutNode("main", "container", this.oExt);
- this.oInput = this.$getLayoutNode("main", "input", this.oExt);
- this.oButtonPlus = this.$getLayoutNode("main", "buttonplus", this.oExt);
- this.oButtonMinus = this.$getLayoutNode("main", "buttonminus", this.oExt);
-
- jpf.sanitizeTextbox(this.oInput);
-
- var timer, z = 0;
-
- /* Setting start value */
- this.oInput.value = this.value;
-
- this.oInput.onmousedown = function(e) {
- if (_self.disabled)
- return;
-
- e = e || window.event;
-
- var value = parseInt(this.value) || 0, step = 0,
- cy = e.clientY, cx = e.clientX,
- ot = _self.oInt.offsetTop, ol = _self.oInt.offsetLeft,
- ow = _self.oInt.offsetWidth, oh = _self.oInt.offsetHeight;
-
- clearInterval(timer);
- timer = setInterval(function() {
- if (!step)
- return;
-
- if (value + step <= _self.max
- && value + step >= _self.min) {
- value += step;
- _self.oInput.value= Math.round(value);
- }
- else {
- _self.oInput.value = step < 0
- ? _self.min
- : _self.max;
- }
- }, 10);
-
- document.onmousemove = function(e) {
- e = e || window.event;
- var y = e.clientY, x = e.clientX, nrOfPixels = cy - y;
-
- if ((y > ot && x > ol) && (y < ot + oh && x < ol + ow)) {
- step = 0;
- return;
- }
-
- step = Math.pow(Math.min(200, Math.abs(nrOfPixels)) / 10, 2) / 10;
- if (nrOfPixels < 0)
- step = -1 * step;
- };
-
- document.onmouseup = function(e) {
- clearInterval(timer);
-
- var value = parseInt(_self.oInput.value);
-
- if (value != _self.value) {
- _self.change(value);
- }
- document.onmousemove = null;
- };
- };
-
- /* Fix for mousedown for IE */
- var buttonDown = false;
- this.oButtonPlus.onmousedown = function(e) {
- if (_self.disabled)
- return;
-
- e = e || window.event;
- buttonDown = true;
-
- var value = (parseInt(_self.oInput.value) || 0) + 1;
-
- jpf.setStyleClass(_self.oButtonPlus, "plusDown", ["plusHover"]);
-
- clearInterval(timer);
- timer = setInterval(function() {
- z++;
- value += Math.pow(Math.min(200, z) / 10, 2) / 10;
- value = Math.round(value);
-
- _self.oInput.value = value <= _self.max
- ? value
- : _self.max;
- }, 50);
- };
-
- this.oButtonMinus.onmousedown = function(e) {
- if (_self.disabled)
- return;
-
- e = e || window.event;
- buttonDown = true;
-
- var value = (parseInt(_self.oInput.value) || 0) - 1;
-
- jpf.setStyleClass(_self.oButtonMinus, "minusDown", ["minusHover"]);
-
- clearInterval(timer);
- timer = setInterval(function() {
- z++;
- value -= Math.pow(Math.min(200, z) / 10, 2) / 10;
- value = Math.round(value);
-
- _self.oInput.value = value >= _self.min
- ? value
- : _self.min;
- }, 50);
- };
-
- this.oButtonMinus.onmouseout = function(e) {
- if (_self.disabled)
- return;
-
- window.clearInterval(timer);
- z = 0;
-
- var value = parseInt(_self.oInput.value);
-
- if (value != _self.value) {
- _self.change(value);
- }
- jpf.setStyleClass(_self.oButtonMinus, "", ["minusHover"]);
-
- if (!_self.focused) {
- _self.$blur(e);
- }
- };
-
- this.oButtonPlus.onmouseout = function(e) {
- if (_self.disabled)
- return;
-
- window.clearInterval(timer);
- z = 0;
-
- var value = parseInt(_self.oInput.value);
-
- if (value != _self.value) {
- _self.change(value);
- }
- jpf.setStyleClass(_self.oButtonPlus, "", ["plusHover"]);
-
- if (!_self.focused) {
- _self.$blur(e);
- }
- };
-
- this.oButtonMinus.onmouseover = function(e) {
- if (_self.disabled)
- return;
-
- jpf.setStyleClass(_self.oButtonMinus, "minusHover");
- };
-
- this.oButtonPlus.onmouseover = function(e) {
- if (_self.disabled)
- return;
-
- jpf.setStyleClass(_self.oButtonPlus, "plusHover");
- };
-
- this.oButtonPlus.onmouseup = function(e) {
- if (_self.disabled)
- return;
-
- e = e || event;
- e.cancelBubble = true;
-
- jpf.setStyleClass(_self.oButtonPlus, "plusHover", ["plusDown"]);
-
- window.clearInterval(timer);
- z = 0;
-
- var value = parseInt(_self.oInput.value);
-
- if (!buttonDown) {
- value++;
- _self.oInput.value = value;
- }
- else {
- buttonDown = false;
- }
-
- if (value != _self.value) {
- _self.change(value);
- }
- };
-
- this.oButtonMinus.onmouseup = function(e) {
- if (_self.disabled)
- return;
-
- e = e || event;
- e.cancelBubble = true;
-
- jpf.setStyleClass(_self.oButtonMinus, "minusHover", ["minusDown"]);
-
- window.clearInterval(timer);
- z = 0;
-
- var value = parseInt(_self.oInput.value);
-
- if (!buttonDown) {
- value--;
- _self.oInput.value = value;
- }
- else {
- buttonDown = false;
- }
-
-
- if (value != _self.value) {
- _self.change(value);
- }
- };
-
- this.oInput.onselectstart = function(e) {
- e = e || event;
- e.cancelBubble = true;
- };
-
- this.oInput.host = this;
- };
-
- this.$loadJml = function(x) {
- jpf.JmlParser.parseChildren(this.$jml, null, this);
- };
-
- this.$destroy = function() {
- this.oInput.onkeypress =
- this.oInput.onmousedown =
- this.oInput.onkeydown =
- this.oInput.onkeyup =
- this.oInput.onselectstart =
- this.oButtonPlus.onmouseover =
- this.oButtonPlus.onmouseout =
- this.oButtonPlus.onmousedown =
- this.oButtonPlus.onmouseup =
- this.oButtonMinus.onmouseover =
- this.oButtonMinus.onmouseout =
- this.oButtonMinus.onmousedown =
- this.oButtonMinus.onmouseup = null;
- };
-}).implement(
- jpf.DataBinding,
- jpf.Validation,
- jpf.Presentation
-);
-
- - -/*FILEHEAD(/var/lib/jpf/src/elements/htmlwrapper.js)SIZE(-1077090856)TIME(1225628613)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-/**
- * @private
- * @constructor
- */
-
-jpf.HtmlWrapper = function(pHtmlNode, htmlNode, namespace){
- this.uniqueId = jpf.all.push(this) - 1;
- this.inherit = jpf.inherit;
- this.oExt = htmlNode;
- this.pHtmlDoc = document;
- this.pHtmlNode = pHtmlNode;
-
- this.inherit(jpf.Anchoring); /** @inherits jpf.Anchoring */
-
- this.inherit(jpf.Alignment); /** @inherits jpf.Alignment */
-
- var copy = htmlNode.cloneNode();
-
- // @todo : check this code, it looks disfuncional to me.
- this.enableAlignment = function(purge){
- var l = jpf.layout.get(this.pHtmlNode); // , (x.parentNode.getAttribute("margin") || "").split(/,\s*/)might be optimized by splitting only once
- if (!this.aData) {
- if (x.getAttribute(namespace + ":align"))
- x.setAttribute("align", x.getAttribute(namespace + ":align"));
- if (x.getAttribute(namespace + ":lean"))
- x.setAttribute("lean", x.getAttribute(namespace + ":lean"));
- if (x.getAttribute(namespace + ":edge"))
- x.setAttribute("edge", x.getAttribute(namespace + ":edge"));
- if (x.getAttribute(namespace + ":weight"))
- x.setAttribute("weight", x.getAttribute(namespace + ":weight"));
- if (x.getAttribute(namespace + ":splitter"))
- x.setAttribute("splitter", x.getAttribute(namespace + ":splitter"));
- if (x.getAttribute(namespace + ":width"))
- x.setAttribute("width", x.getAttribute(namespace + ":width"));
- if (x.getAttribute(namespace + ":height"))
- x.setAttribute("height", x.getAttribute(namespace + ":height"));
- if (x.getAttribute(namespace + ":min-width"))
- x.setAttribute("min-width", x.getAttribute(namespace + ":min-width"));
- if (x.getAttribute(namespace + ":min-height"))
- x.setAttribute("min-height", x.getAttribute(namespace + ":min-height"));
-
- this.aData = jpf.layout.parseXml(x, l, this);
- this.aData.stackId = this.parentNode.aData.children.push(this.aData) - 1;
- this.aData.parent = this.parentNode;
- }
- else {
- //put aData back here
- }
-
- if (purge)
- this.purgeAlignment();
- };
-}
-
- - -/*FILEHEAD(/var/lib/jpf/src/elements/collection.js)SIZE(-1077090856)TIME(1225628613)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * Virtual element acting as a parent for a set of child elements
- * but only draws it's children. It doesn't have any representation itself.
- *
- * @constructor
- * @allowchild {elements}, {anyjml}
- *
- * @define collection
- * @addnode elements
- *
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.4
- */
-
-jpf.collection = jpf.component(jpf.NODE_VISIBLE, function(){
- this.canHaveChildren = true;
- this.$focussable = false;
-
- this.$draw = function(pHtmlNode){
- this.oExt = pHtmlNode;
- this.oInt = pHtmlNode;
- jpf.JmlParser.parseChildren(this.$jml, this.oInt, this);
- };
-
- this.$loadJml = function(x){};
-});
-
- -/*FILEHEAD(/var/lib/jpf/src/elements/remote.js)SIZE(-1077090856)TIME(1239018216)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * Element allowing data synchronization between multiple clients using the same
- * application or application part. This element is designed as thecore of
- * collaborative application logic for Javeline PlatForm. The children of this
- * element specify how the uniqueness of data elements is determined. By pointing
- * models to this element, all changes to their data will be streamed through
- * this element to all listening client over a choosen protocol.
- * Example:
- * This example shows a small application which is editable by all clients that
- * have started it. Any change to the data is synchronized to all participants.
- * <code>
- * <j:teleport> - * <j:xmpp id="myXMPP" - * url = "http://javeline.com:5280/http-bind" - * model = "mdlRoster" - * connection = "bosh" - * </j:teleport> - * - * <j:remote transport="myXMPP" id="rmtPersons"> - * <j:person unique="@id" /> - * </j:remote> - * - * <j:model id="mdlPersons" remote="rmtPersons"> - * <persons> - * <person id="1">mike</person> - * <person id="2">ruben</person> - * </persons> - * </j:model>
- *
- * <j:list id="lstPersons" model="mdlPersons" width="200" height="100"> - * <j:bindings> - * <j:traverse select="person" /> - * <j:caption select="text()" /> - * <j:icon value="icoUsers.gif" /> - * </j:bindings>
- * </j:list>
- *
- * <j:button action="remove" target="lstPersons">Remove</j:button>
- * <j:button action="rename" target="lstPersons">Rename</j:button>
- *
- * <j:button onclick="myXMPP.connect('testuser@javeline.com', 'testpass')">
- * Login
- * </j:button>
- * </code>
- * Remarks:
- * Although locking is solved in smartbindings it is directly connected
- * to remote smartbindings. When multiple people are working within the same
- * application it's important to have a system that prevents corruption of data
- * and data loss by either user overwriting records edited during the same period.
- * Javeline PlatForm has built in support for optimistic and pessimistic locking
- * in smartbindings. For more information please see {@link term.locking}.
- *
- * Advanced Remarks:
- * There is a very small theoretical risk that a user initiates and finishes an
- * action during the latency period of the rsb communication. Usually this
- * latency is no more than 100 to 300ms which is near impossible for such action
- * to be performed. Therefor this is deemed acceptable.
- *
- * Working in a multi user environment could imply that data has a high
- * probability of changing. This might be a problem when syncing offline
- * changes after several hours. This should be a consideration for the
- * application architect.
- *
- * Another concern for offline use is the offline messaging feature of certain
- * collaborative protocols (i.e. xmpp). In many cases offline rsb messages should
- * not be stored after the user has been offline for longer then a certain time.
- * For instance 10 minutes. An accumulation of change messages would create a
- * serious scaling problem and is not preferred. jpf.offline has built in support
- * for this type of timeout. By setting the rsb-timeout attribute it is aware
- * of when the server has timed out. When this timeout is reached the application
- * will reload all it's data from the server and discard all offline rsb
- * messages before reconnecting to the server.
- *
- * @see element.auth
- *
- * @define remote
- * @allowchild unique, {any}
- * @addnode elements
- *
- * @define unique Element defining what is unique about a set of data
- * elements. This enables remote smartbindings to point to xml data in
- * the same way on all clients. This way changes that happen to these
- * elements are described non-ambiguously. The tagName can be replaced
- * by the tagName of the data element for which the uniqueness is specified.
- * Example:
- * This example shows a complex data set and a remote smartbinding that
- * specifies the uniqueness of all nodes concerned.
- * <code>
- * <j:model id="mdlPersons" remote="rmtPersons"> - * <universe>
- * <galaxy name="milkyway">
- * <planet id="ALS-3947">
- * <species>3564</species> - * <species>8104</species>
- * </planet>
- * <planet id="Earth">
- * <person number="802354897">Mike</person> - * <person number="836114798">Rik</person>
- * </planet>
- * </galaxy>
- * </universe> - * </j:model>
- *
- * <j:remote transport="myXMPP" id="rmtPersons"> - * <j:person unique="@number" />
- * <j:unique select="self::galaxy" unique="@name" />
- * <j:planet unique="@id" />
- * <j:species unique="text()" />
- * </j:remote>
- * </code>
- * @attribute {String} select the xpath that selects the set of data elements that share a similar uniqueness trait.
- * @attribute {String} unique the xpath that retrieves the unique value for a specific data element.
- */
-/**
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.983
- *
- * @default_private
- * @constructor
- *
- * @todo Think about wrapping multiple messages in a single call
- * @todo Make RSB support different encoding protocols (think REX)
- */
-jpf.remote = function(name, xmlNode, parentNode){
- this.name = name;
- this.lookup = {};
- this.select = [];
- this.models = [];
-
- this.parentNode = parentNode;
- jpf.inherit.call(this, jpf.JmlDom); /** @inherits jpf.JmlDom */
-
- this.discardBefore = null;
-
- var _self = this;
-
- this.sendChange = function(args, model){
- if (!jpf.xmldb.disableRSB)
- return;
-
- var message = [this.buildMessage(args, model)];
-
- jpf.console.info('Sending RSB message\n' + jpf.serialize(message));
-
- this.transport.sendMessage(null, jpf.serialize(message),
- null, jpf.xmpp.MSG_NORMAL); //@todo hmmm xmpp here? thats not good
- };
-
- this.buildMessage = function(args, model){
- for (var i = 0; i < args.length; i++)
- if(args[i] && args[i].nodeType)
- args[i] = this.xmlToXpath(args[i], model.data);
-
- return {
- model : model.name,
- args : args,
- timestamp : new Date().toGMTString()
- }
- };
-
- this.queueMessage = function(args, model, qHost){
- if (!qHost.rsbQueue) {
- qHost.rsbQueue = [];
- qHost.rsbModel = model;
- }
-
- qHost.rsbQueue.push(this.buildMessage(args, model));
- };
-
- this.processQueue = function(qHost){
- if (!jpf.xmldb.disableRSB || !qHost.rsbQueue || !qHost.rsbQueue.length)
- return;
-
- jpf.console.info('Sending RSB message\n' + jpf.serialize(qHost.rsbQueue));
-
- this.transport.sendMessage(null, jpf.serialize(qHost.rsbQueue),
- null, jpf.xmpp.MSG_NORMAL); //@todo hmmm xmpp here? thats not good
-
- qHost.rsbQueue = [];
- };
-
- if (jpf.offline.enabled) {
- var queue = [];
- jpf.offline.addEventListener("afteronline", function(){
- for (var i = 0; i < queue.length; i++) {
- _self.receiveChange(queue[i]);
- }
-
- queue.length = 0;
- });
- }
-
- this.receiveChange = function(message){
- if (jpf.xmldb.disableRSB)
- return;
-
- if (jpf.offline.inProcess == 2) { //We're coming online, let's queue until after sync
- queue.push(message);
- return;
- }
-
- //this.lastTime = new Date().getTime();
- if (message.timestamp < this.discardBefore)
- return;
-
- var model = jpf.nameserver.get("model", message.model);
- var q = message.args;
-
- if (!model) {
- //Maybe make this a warning?
- throw new Error(jpf.formatErrorString(0, this,
- "Remote Smartbinding Received", "Could not find model when \
- receiving data for it with name '" + message.model + "'"));
- }
-
- //Maybe make this an error?
- var xmlNode = this.xpathToXml(q[1], model.data);
- if (!xmlNode) return;
-
- var disableRSB = jpf.xmldb.disableRSB;
- jpf.xmldb.disableRSB = 2; //Feedback prevention
-
- switch (q[0]) {
- case "setTextNode":
- jpf.xmldb.setTextNode(xmlNode, q[2], q[3]);
- break;
- case "setAttribute":
- jpf.xmldb.setAttribute(xmlNode, q[2], q[3], q[4]);
- break;
- case "addChildNode":
- jpf.xmldb.addChildNode(xmlNode, q[2], q[3],
- this.xpathToXml(q[4], model.data), q[5]);
- break;
- case "appendChild":
- var beforeNode = (q[3] ? this.xpathToXml(q[3], model.data) : null);
- jpf.xmldb.appendChild(xmlNode, //@todo check why there's clearConnections here
- jpf.xmldb.clearConnections(q[2]), beforeNode, q[4], q[5]);
- break;
- case "moveNode":
- var beforeNode = (q[3] ? this.xpathToXml(q[3], model.data) : null);
- var sNode = this.xpathToXml(q[2], model.data);
- jpf.xmldb.appendChild(xmlNode, sNode, beforeNode,
- q[4], q[5]);
- break;
- case "removeNode":
- jpf.xmldb.removeNode(xmlNode, q[2]);
- break;
- }
-
- jpf.xmldb.disableRSB = disableRSB;
- };
-
- this.xmlToXpath = jpf.remote.xmlToXpath;
- this.xpathToXml = jpf.remote.xpathToXml;
-
- jpf.console.info(name
- ? "Creating remote [" + name + "]"
- : "Creating implicitly assigned remote");
-
- this.loadJml = function(x){
- this.name = x.getAttribute("id");
- this.$jml = x;
-
- /**
- * @attribute {String} transport the id of the teleport module instance
- * that provides a means to sent change messages to other clients.
- */
- this.transport = self[x.getAttribute("transport")];
- this.transport.addEventListener('datachange', function(e){
- var data = jpf.unserialize(e.data); //@todo error check here.. invalid message
- for (var i = 0; i < data.length; i++)
- _self.receiveChange(data[i]);
- });
-
- var nodes = x.childNodes;
- for (var i = 0; i < nodes.length; i++) {
- if (nodes[i].nodeType != 1) continue;
-
- if (nodes[i].getAttribute("select"))
- this.select.push(nodes[i].getAttribute("select"),
- nodes[i].getAttribute("unique"));
- else
- this.lookup[nodes[i][jpf.TAGNAME]] = nodes[i].getAttribute("unique");
- }
- };
-
- if (xmlNode)
- this.loadJml(xmlNode);
-}
-
-//@todo this function needs to be 100% proof, it's the core of the system
-//for RSB: xmlNode --> Xpath statement
-jpf.remote.xmlToXpath = function(xmlNode, xmlContext, useJid){
- if (useJid) {
- if (!xmlNode.getAttribute(jpf.xmldb.xmlIdTag)) {
- throw new Error(jpf.formatErrorString(0, null,
- "Converting XML to Xpath",
- "Error xml node without j_id found whilst \
- trying to use it.", xmlNode));
- }
-
- return "//node()[@" + jpf.xmldb.xmlIdTag + "='"
- + xmlNode.getAttribute(jpf.xmldb.xmlIdTag) + "']";
- }
-
- if (this.lookup && this.select) {
- var def = this.lookup[xmlNode.tagName];
- if (def) {
- //unique should not have ' in it... -- can be fixed...
- var unique = xmlNode.selectSingleNode(def).nodeValue;
- return "//" + xmlNode.tagName + "[" + def + "='" + unique + "']";
- }
-
- for (var i = 0; i < this.select.length; i++) {
- if (xmlNode.selectSingleNode(this.select[i][0])) {
- var unique = xmlNode.selectSingleNode(this.select[i][1]).nodeValue;
- return "//" + this.select[i][0] + "[" + this.select[i][1]
- + "='" + unique + "']";
- }
- }
- }
-
- if (xmlNode == xmlContext)
- return ".";
-
- if (!xmlNode.parentNode) {
- throw new Error(jpf.formatErrorString(0, null,
- "Converting XML to Xpath",
- "Error xml node without parent and non matching context cannot\
- be converted to xml.", xmlNode));
-
- return false;
- }
-
- var str = [], lNode = xmlNode;
- do {
- str.unshift(lNode.tagName);
- lNode = lNode.parentNode;
- } while(lNode && lNode.nodeType == 1 && lNode != xmlContext);
-
- return str.join("/") + "[" + (jpf.xmldb.getChildNumber(xmlNode) + 1) + "]";
-};
-
-//for RSB: Xpath statement --> xmlNode
-jpf.remote.xpathToXml = function(xpath, xmlNode){
- if (!xmlNode) {
- throw new Error(jpf.formatErrorString(0, null,
- "Converting Xpath to XML",
- "Error context xml node is empty, thus xml node cannot \
- be found for '" + xpath + "'"));
-
- return false;
- }
-
- return xmlNode.selectSingleNode(xpath);
-};
-
- - -/*FILEHEAD(/var/lib/jpf/src/elements/img.js)SIZE(-1077090856)TIME(1238944817)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -/** - * Element displaying a picture. This element can read databound resources. - * Example: - * This example shows a list with pictures. When one is selected its displayed - * in the img element. - * <code> - * <j:model id="mdlPictures"> - * <pictures> - * <picture title="Landscape" src="http://example.com/landscape.jpg" /> - * <picture title="Animal" src="http://example.com/animal.jpg" /> - * <picture title="River" src="http://example.com/river.jpg" /> - * </pictures> - * </j:model> - * - * <j:list id="lstPics" - * traverse = "picture" - * name = "@title" - * model = "mdlPictures" /> - * - * <j:img ref="@src" model="#lstPics" /> - * </code> - * - * @constructor - * @define img - * @allowchild {smartbinding} - * @addnode elements - * - * @inherits jpf.BaseSimple - * - * @author Ruben Daniels - * @version %I%, %G% - * @since 0.4 - * - * @event click Fires when a user presses a mouse button while over this element. - * - * @binding value Determines the way the value for the element is retrieved - * from the bound data. - * Example: - * Sets the image source based on data loaded into this component. - * <code> - * <j:img> - * <j:bindings> - * <j:value select="@src" /> - * </j:bindings> - * </j:img> - * </code> - * Example: - * A shorter way to write this is: - * <code> - * <j:img ref="@src" /> - * </code> - */ - -jpf.img = jpf.component(jpf.NODE_VISIBLE, function(){ - this.editableParts = {"main" : [["image","@src"]]}; - - var _self = this; - - /** - * @copy Widget#setValue - */ - this.setValue = function(value){ - this.setProperty("value", value); - }; - - /** - * @copy Widget#getValue - */ - this.getValue = function(value){ - return this.value; - }; - - this.$supportedProperties.push("value"); - /** - * @attribute {String} value the url location of the image displayed. - */ - this.$propHandlers["value"] = function(value){ - if (this.oImage.nodeType == 1) - this.oImage.style.backgroundImage = "url(" + value + ")"; - else - this.oImage.nodeValue = value; - - //@todo resize should become a generic thing - if (this.oImage.nodeType == 2 && !this.$resize.done) { - this.oImg = this.oInt.getElementsByTagName("img")[0]; - - jpf.layout.setRules(this.pHtmlNode, this.uniqueId + "_image", - "jpf.all[" + this.uniqueId + "].$resize()"); - jpf.layout.activateRules(this.pHtmlNode); - - this.oImg.onload = function(){ - jpf.layout.forceResize(_self.pHtmlNode); - } - - this.$resize.done = true; - } - - if (this.oImg) - this.oImg.style.display = value ? "block" : "none"; - }; - - this.$clear = function(){ - if (this.oImg) - this.oImg.style.display = "none"; - } - - /**** Init ****/ - - this.$draw = function(){ - //Build Main Skin - this.oInt = this.oExt = this.$getExternal(); - this.oExt.onclick = function(e){ - this.host.dispatchEvent("click", {htmlEvent: e || event}); - }; - this.oImage = this.$getLayoutNode("main", "image", this.oExt); - }; - - this.$resize = function(){ - var diff = jpf.getDiff(this.oExt); - var wratio = 1, hratio = 1; - - this.oImg.style.width = ""; - this.oImg.style.height = ""; - - if (this.oImg.offsetWidth > this.oExt.offsetWidth) - wratio = this.oImg.offsetWidth / (this.oExt.offsetWidth - diff[0]); - if (this.oImg.offsetHeight > this.oExt.offsetHeight) - hratio = this.oImg.offsetHeight / (this.oExt.offsetHeight - diff[1]); - - if (wratio > hratio && wratio > 1) - this.oImg.style.width = "100%"; - else if (hratio > wratio && hratio > 1) - this.oImg.style.height = "100%"; - - this.oImg.style.top = ((this.oExt.offsetHeight - jpf.getHeightDiff(this.oExt) - - this.oImg.offsetHeight) / 2) + "px"; - } - - this.$loadJml = function(x){ - if(x.getAttribute("src")) - this.setProperty("value", x.getAttribute("src")); - - this.$makeEditable("main", this.oExt, this.$jml); - - jpf.JmlParser.parseChildren(x, null, this); - }; -}).implement( - jpf.BaseSimple -); - - - -/*FILEHEAD(/var/lib/jpf/src/elements/hbox.js)SIZE(-1077090856)TIME(1238950356)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-/**
- * @define vbox Container that stacks it's children vertically.
- * @see element.hbox
- * @define hbox Container that stacks it's children horizontally.
- * Example:
- * <code>
- * <j:hbox>
- * <j:vbox>
- * <j:bar caption="Some Window"/>
- * <j:bar caption="Another Window"/>
- * <j:hbox>
- * <j:bar caption="Redmond Window"/>
- * <j:vbox>
- * <j:bar caption="Ping Window"/>
- * <j:bar caption="YAW window"/>
- * </j:vbox>
- * </j:hbox>
- * </j:vbox>
- * <j:bar caption="Down Window"/>
- * </j:hbox>
- * </code>
- * Remarks:
- * The layouting engine of Javeline PlatForm lets you store layouts and set them
- * dynamically. It's very easy to make a layout manager this way. For more
- * information see {@link object.layout}
- * @addnode elements
- * @constructor
- *
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.9
- */
-jpf.hbox =
-jpf.vbox = jpf.component(jpf.NODE_HIDDEN, function(){
- this.canHaveChildren = true;
- this.$focussable = false;
-
- /**** DOM Hooks ****/
-
- this.$domHandlers["removechild"].push(function(jmlNode, doOnlyAdmin){
- if (doOnlyAdmin)
- return;
-
- jmlNode.disableAlignment();
-
- if (jmlNode.enableAnchoring)
- jmlNode.enableAnchoring();
- });
-
- this.$domHandlers["insert"].push(function(jmlNode, bNode, withinParent){
- if (withinParent)
- return;
-
- if (!jmlNode.hasFeature(__ALIGNMENT__)) {
- jmlNode.inherit(jpf.Alignment);
- if (jmlNode.hasFeature(__ANCHORING__))
- jmlNode.disableAnchoring();
- }
-
- jmlNode.enableAlignment();
- });
-
- this.$domHandlers["reparent"].push(
- function(bNode, pNode, withinParent, oldParentHtmlNode){
- if (withinParent)
- return;
-
- if (oldParentHtmlNode == this.oExt) {
- pNode.oInt.insertBefofore(
- document.createElement("div"),
- bNode && bNode.oExt || null
- );
- }
- });
-
- this.$domHandlers["remove"].push(function(doOnlyAdmin){
- if (!doOnlyAdmin)
-
- if (this.pHtmlNode != this.oExt)
- this.oExt.parentNode.removeChild(this.oExt);
- });
-
- /**** Init ****/
-
- this.$loadJml = function(x){
- var isParentOfChain = !this.parentNode.tagName
- || "vbox|hbox".indexOf(this.parentNode.tagName) == -1;
-
- if (isParentOfChain) {
- this.oInt =
- this.oExt = jpf.isParsing && jpf.xmldb.isOnlyChild(x)
- ? this.pHtmlNode
- : this.pHtmlNode.appendChild(document.createElement("div"));
- }
-
- var l = jpf.layout.get(this.pHtmlNode, jpf.getBox(this.margin || ""));
- var aData = jpf.layout.parseXml(x, l, null, true);
-
- if (isParentOfChain) {
- this.pData = aData;
- l.root = this.pData;
-
- jpf.JmlParser.parseChildren(x, this.pHtmlNode, this);
-
- if (this.pData.children.length && !jpf.isParsing)
- jpf.layout.compileAlignment(this.pData);
- //if(jpf.JmlParser.loaded)
- //jpf.layout.activateRules(pHtmlNode);
- }
- else {
- var pData = this.parentNode.aData || this.parentNode.pData;
- this.aData = aData;
- this.aData.stackId = pData.children.push(this.aData) - 1;
- this.aData.parent = pData;
-
- jpf.JmlParser.parseChildren(x, this.pHtmlNode, this);
- }
- };
-});
-
- - -/*FILEHEAD(/var/lib/jpf/src/elements/progressbar.js)SIZE(-1077090856)TIME(1238944817)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * Element graphically representing a percentage value which time based
- * increases automatically. This element is ofter used to show the progress
- * of a process. The progress can be either indicative or exact.
- * Example:
- * This example shows a progress bar that is only visible when an application is
- * synchronizing it's offline changes. When in this process it shows the exact
- * progress of the sync process.
- * <code>
- * <j:progressbar
- * value="{jpf.offline.progress}"
- * visible="{jpf.offline.syncing}" />
- * </code>
- *
- * @constructor
- * @allowchild {smartbinding}
- * @addnode elements:progressbar
- *
- * @inherits jpf.Presentation
- * @inherits jpf.DataBinding
- *
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.9
- *
- * @binding value Determines the way the value for the element is retrieved
- * from the bound data.
- * Example:
- * Sets the progress position based on data loaded into this component.
- * <code>
- * <j:progressbar>
- * <j:bindings>
- * <j:value select="@progress" />
- * </j:bindings>
- * </j:progressbar>
- * </code>
- * Example:
- * A shorter way to write this is:
- * <code>
- * <j:progressbar ref="@progress" />
- * </code>
- */
-jpf.progressbar = jpf.component(jpf.NODE_VISIBLE, function(){
- this.$focussable = false; // This object can get the focus
-
- /**** Properties and Attributes ****/
-
- this.value = 0;
- this.min = 0;
- this.max = 100;
-
- this.$booleanProperties["autostart"] = true;
- this.$booleanProperties["autohide"] = true;
-
- this.$supportedProperties.push("value", "min", "max", "autostart", "autohide");
-
- /**
- * @attribute {String} value the position of the progressbar stated between
- * the min and max value.
- */
- this.$propHandlers["value"] = function(value){
- this.value = parseInt(value) || this.min;
-
- if (this.value >= this.max)
- jpf.setStyleClass(this.oExt, this.baseCSSname + "Complete", [this.baseCSSname + "Running"]);
- else
- jpf.setStyleClass(this.oExt, "", [this.baseCSSname + "Complete"]);
-
- this.oSlider.style.width = (this.value * 100 / (this.max - this.min)) + "%"
-
- /*Math.max(0,
- Math.round((this.oExt.offsetWidth - 5)
- * (this.value / (this.max - this.min)))) + "px";*/
-
- this.oCaption.nodeValue =
- Math.round((this.value / (this.max - this.min)) * 100) + "%";
- };
-
- /**
- * @attribute {Number} min the minimal value the progressbar can have. This is
- * the value that the progressbar has when it's at it's begin position.
- */
- this.$propHandlers["min"] = function(value){
- this.min = parseFloat(value);
- }
-
- /**
- * @attribute {Number} max the maximal value the progressbar can have. This is
- * the value that the progressbar has when it's at it's end position.
- */
- this.$propHandlers["max"] = function(value){
- this.max = parseFloat(value);
- }
-
- /**** Public Methods ****/
-
- /** - * @copy Widget#setValue - */ - this.setValue = function(value){ - this.setProperty("value", value); - }; - - /** - * @copy Widget#getValue - */
- this.getValue = function(){
- return this.value;
- };
-
- /**
- * Resets the progress indicator.
- * @param {Boolean} restart whether a timer should start with a new indicative progress indicator.
- */
- this.clear = function(restart, restart_time){
- clearInterval(this.timer);
- this.setValue(this.min);
- //this.oSlider.style.display = "none";
- jpf.setStyleClass(this.oExt, "", [this.baseCSSname + "Running", this.baseCSSname + "Complete"]);
-
- if(restart)
- this.timer = setInterval("jpf.lookup(" + this.uniqueId
- + ").start(" + restart_time + ")");
- if (this.autohide)
- this.hide();
- };
-
- /**
- * Starts the progress indicator.
- * @param {Number} start the time between each step in milliseconds.
- */
- this.start = function(time){
- if (this.autohide)
- this.show();
-
- clearInterval(this.timer);
-
- //if (this.value == this.max)
- //this.setValue(this.min + (this.max - this.min) * 0.5);
-
- //this.oSlider.style.display = "block";
- this.timer = setInterval("jpf.lookup(" + this.uniqueId + ").$step()",
- time || 1000);
- this.$setStyleClass(this.oExt, this.baseCSSname + "Running");
- };
-
- /**
- * Pauses the progress indicator.
- */
- this.pause = function(){
- clearInterval(this.timer);
- };
-
- /**
- * Stops the progress indicator.
- * @param {Boolean} restart whether a timer should start with a new indicative progress indicator.
- */
- this.stop = function(restart, time, restart_time){
- clearInterval(this.timer);
- this.setValue(this.max);
- this.timer = setTimeout("jpf.lookup(" + this.uniqueId + ").clear("
- + restart + ", " + (restart_time || 0) + ")", time || 500);
- };
-
- /**** Private methods ****/
-
- this.$step = function(){
- if (this.value == this.max)
- return;
-
- this.setValue(this.value + 1);
- };
-
- /**** Init ****/
-
- this.$draw = function(clear, parentNode, Node, transform){
- //Build Main Skin
- this.oExt = this.$getExternal();
- this.oSlider = this.$getLayoutNode("main", "progress", this.oExt);
- this.oCaption = this.$getLayoutNode("main", "caption", this.oExt);
- };
-
- this.$loadJml = function(x){
- if (this.autostart)
- this.start();
-
- if (this.autohide)
- this.hide();
- };
-}).implement(
- jpf.DataBinding,
- jpf.Presentation
-);
-
- - -/*FILEHEAD(/var/lib/jpf/src/elements/repeat.js)SIZE(-1077090856)TIME(1238944817)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-/**
- * Element that defines a template of jml which is repeated for a list of
- * selected xml data elements. Each template instance is databound to the
- * xml data element.
- * Example:
- * Simple example of some jml which is repeated. The button removes an item
- * from the model when pressed.
- * <code>
- * <j:model id="mdlExample"> - * <data> - * <item>test1</item> - * <item>test2</item> - * <item>test3</item> - * <item>test4</item> - * <item>test5</item> - * <item>test6</item> - * </data> - * </j:model> - * - * <j:repeat id="rpExample" model="mdlExample" nodeset="item"> - * <j:label ref="text()" /> - * <j:button>ok</j:button> - * </j:repeat>
- *
- * <j:button onclick="
- * jpf.xmldb.removeNode(mdlExample.data.childNodes[1]);
- * ">remove item</j:button>
- * </code>
- *
- * @constructor
- * @define repeat
- * @allowchild {anyjml}
- * @addnode elements
- *
- * @inherits jpf.DataBinding
- *
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.9
- */
-
-jpf.repeat = jpf.component(jpf.NODE_VISIBLE, function(){
- this.$focussable = false; // This object can get the focus
- this.canHaveChildren = true;
-
- this.caching = true;
- this.traverse = "node()";
-
- /** - * @attribute {String} nodeset the xpath querey which selects the nodes for each which the template is rendered. - */
- this.$propHandlers["nodeset"] = function(value){ - this.traverse = value;
- };
-
- /**** Private methods ****/
-
- /**
- * @private
- */
- var nodes = {};
- this.addItem = function(xmlNode, beforeNode, nr){
- var Lid = jpf.xmldb.nodeConnect(this.documentId, xmlNode, null, this);
- var htmlNode = this.oExt.insertBefore(document.createElement("div"), beforeNode || null);
- var oItem = nodes[Lid] = {
- childNodes: [],
- hasFeature: function(){
- return 0
- },
- dispatchEvent : jpf.K,
- oExt: htmlNode
- };
-
- //Create JML Nodes
- var jmlNode = this.template.cloneNode(true);
- jmlNode.setAttribute("model", "#" + this.name + ":select:(" + this.traverse + ")[" + (nr + 1) + "]");
- jpf.JmlParser.parseChildren(jmlNode, htmlNode, oItem);
- };
-
- /**
- * @private
- */
- this.removeItem = function(Lid){
- Lid += "|" + this.uniqueId;
- var oItem = nodes[Lid];
- var children = oItem.childNodes;
- for (var i = children.length - 1; i >= 0; i--) {
- children[i].destroy(true);
- }
- jpf.removeNode(oItem.oExt);
- delete nodes[Lid];
- };
-
- /**
- * Clears the loaded data from this element.
- */
- this.clear = function(){
- var Lid;
- for (Lid in nodes) {
- this.removeItem(Lid);
- }
- };
-
- /**** Databinding ****/
-
- /**
- * @private
- */
- this.getCache = function(){
- return false;
- };
-
- this.$load = function(XMLRoot){
- //Add listener to XMLRoot Node
- jpf.xmldb.addNodeListener(XMLRoot, this);
-
- var children = XMLRoot.selectNodes(this.traverse);
- for (var i = 0; i < children.length; i++) {
- this.addItem(children[i], null, i);
- }
-
- jpf.JmlParser.parseLastPass();
- };
-
- /**
- * @private
- */
- this.isTraverseNode = function(xmlNode){
- var nodes = this.xmlRoot.selectNodes(this.traverse);
- for (var i = 0; i < nodes.length; i++)
- if (nodes[i] == xmlNode)
- return true;
-
- return false;
- }
-
- this.$xmlUpdate = function(action, xmlNode, listenNode, UndoObj){
- var Lid = xmlNode.getAttribute(jpf.xmldb.xmlIdTag);
- if (!this.isTraverseNode(xmlNode))
- return;
-
- var htmlNode = nodes[Lid];
-
- //Check Move -- if value node isn't the node that was moved then only perform a normal update
- if (action == "move" && foundNode == startNode) {
- var isInThis = jpf.xmldb.isChildOf(this.xmlRoot, xmlNode.parentNode, true);
- var wasInThis = jpf.xmldb.isChildOf(this.xmlRoot, UndoObj.pNode, true);
-
- //Move if both previous and current position is within this object
- if (isInThis && wasInThis) {
- //xmlNode, htmlNode
- //Not supported right now
- }
-
- //Add if only current position is within this object
- else if (isInThis)
- action = "add";
-
- //Remove if only previous position is within this object
- else if (wasInThis)
- action = "remove";
- }
- else if (action == "move-away") {
- var goesToThis = jpf.xmldb.isChildOf(this.xmlRoot, UndoObj.parent, true);
- if (!goesToThis)
- action = "remove";
- }
-
- if (action == "remove") {
- this.removeItem(Lid);
- }
- else if (action.match(add / insert)) {
- this.addItem(xmlNode, null, 5); //HACK, please determine number by position of xmlnode
- jpf.JmlParser.parseLastPass();
- }
- else if (action == "synchronize") {
-
- }
- };
-
- /**** Init ****/
-
- this.$draw = function(){
- this.oExt = this.pHtmlNode.appendChild(this.oExt
- || document.createElement("div"));
- this.oInt = this.oExt;
- };
-
- this.$loadJml = function(x){
- this.template = x;
-
- if (!this.name) {
- this.name = "repeat" + this.uniqueId;
- jpf.setReference(this.name, this);
- }
- };
-
- this.$destroy = function(){};
-}).implement(
- jpf.DataBinding
-);
-
- - -/*FILEHEAD(/var/lib/jpf/src/elements/smartbinding.js)SIZE(-1077090856)TIME(1238950356)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * Element containing information on how databound elements should deal with
- * data. The smartbinding element specifies how data is transformed and rendered
- * in databound elements. It also specifies how changes on the bound data are
- * send to their original data source (actions) and which data elements can be
- * dragged and dropped (dragdrop).
- * Example:
- * A simple example of a smartbinding transforming data into representation
- * <code>
- * <j:smartbinding id="sbUsers">
- * <j:bindings>
- * <j:caption select="text()" />
- * <j:icon value="icoUser.png" />
- * <j:traverse select="user" />
- * </j:bindings>
- * </j:smartbinding>
- *
- * <j:list smartbinding="sbUsers" />
- * </code>
- * Example:
- * This is an elaborate example showing how to create a filesystem tree with
- * files and folders in a tree. The smartbinding element describes how the
- * files and folders are transformed to tree elements and how actions within
- * the tree are sent to the data source. In this case webdav is used. The drag
- * and drop rules specify which elements can be dragged and where they can be
- * dropped.
- * <code>
- * <j:smartbinding id="sbFilesystem" model="webdav:getRoot()">
- * <j:bindings>
- * <j:insert select="self::folder" get="webdav:readdir({@path})" />
- * <j:traverse select="file|folder" sort="@name" sort-method="filesort" />
- * <j:caption select="@name" />
- * <j:icon select="self::folder" value="icoFolder.png" />
- * <j:icon select="self::file" method="getIcon" />
- * </j:bindings>
- * <j:actions>
- * <j:add type="folder" get="webdav:mkdir({@id}, 'New Folder')" />
- * <j:add type="file" get="webdav:create({@id}, 'New File', '')" />
- * <j:rename set="webdav:move(oldValue, {@name}, {@id})"/>
- * <j:copy select="." set="webdav:copy({@id}, {../@id})"/>
- * <j:move select="." set="webdav:move()"/>
- * <j:remove select="." set="webdav:remove({@path})"/>
- * </j:actions>
- * <j:dragdrop>
- * <j:allow-drag select="folder|file" />
- * <j:allow-drop select="folder|file" target="folder"
- * operation="tree-append" copy-condition="event.ctrlKey" />
- * </j:dragdrop>
- * </j:smartbinding>
- *
- * <j:tree model="mdlFilesystem" smartbinding="sbFilesystem" />
- *
- * <j:script>
- * function filesort(value, args, xmlNode) {
- * return (xmlNode.tagName == "folder" ? 0 : 1) + value;
- * }
- *
- * function getIcon(xmlNode){
- * xmlNode.getAttribute('name').match(/\.([^\.]*)$/);
- *
- * var ext = RegExp.$1;
- * return (SupportedIcons[ext.toUpperCase()]
- * ? SupportedIcons[ext.toUpperCase()] + ".png"
- * : "unknown.png");
- * }
- * </j:script>
- * </code>
- * Remarks:
- * Each element has it's own set of binding rules it uses to render the data
- * elements. The same goes for it's actions. To give an example, a slider has
- * one action called 'change'. This action is called when then value of the
- * slider changes. A tree elements has several actions amongs others 'add',
- * 'remove', 'move', 'copy' and 'rename'.
- *
- * Smartbindings give rise to many other features in a Javeline PlatForm
- * application. Actions done by the user can be undone by calling
- * {@link element.actiontracker.method.undo} of the element. The
- * remote smartbinding element can send changes to data to other clients.
- *
- * This element is created especially for reuse. Multiple elements can reference
- * this elements by setting the smartbinding attribute. If an element is sonly
- * used to for a single element it can be set as it's child. Moreover each of
- * the children of the smartbinding element can exist outside the smartbinding
- * element and referenced indepently.
- * Example:
- * This example shows a smartbinding element which references it's children as
- * stand alone elements.
- * <code>
- * <j:bindings id="bndExample">
- * ...
- * </j:bindings>
- * <j:actions id="actExample">
- * ...
- * </j:actions>
- * <j:dragdrop id="ddExample">
- * ...
- * </j:dragdrop>
- * <j:model id="mdlExample" />
- *
- * <j:smartbinding id="sbExample"
- * actions = "actExample"
- * bindings = "bndExample"
- * dragdrop = "ddExample"
- * model = "mdlExample" />
- *
- * <j:list smartbinding="sbExample" />
- * <j:tree binding="bndExample" action="actExample" model="url:example.php" />
- * </code>
- * Example:
- * This example shows the children of the smartbinding directly as a child of
- * the element that they apply on.
- * <code>
- * <j:tree>
- * <j:bindings>
- * ...
- * </j:bindings>
- * <j:actions>
- * ...
- * </j:actions>
- * <j:dragdrop>
- * ...
- * </j:dragdrop>
- * </j:tree>
- * </code>
- * Example:
- * The shortest way to add binding rules to an element is as follows:
- * <code>
- * <j:tree traverse="file|folder" caption="@name" icon="@icon" />
- * </code>
- *
- * @define smartbinding
- * @allowchild bindings, actions, ref, action, dragdrop, model
- * @addnode smartbinding, global
- *
- * @constructor
- * @jpfclass
- *
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.8
- *
- * @default_private
- */
-jpf.smartbinding = function(name, xmlNode, parentNode){
- this.xmlbindings = null;
- this.xmlactions = null;
- this.xmldragdrop = null;
- this.bindings = null;
- this.actions = null;
- this.dragdrop = null;
-
- this.jmlNodes = {};
- this.$modelXpath = {};
- this.name = name;
- var _self = this;
- //this.uniqueId = jpf.all.push(this) - 1;
-
- this.tagName = "smartbinding";
- this.nodeFunc = jpf.NODE_HIDDEN;
- this.parentNode = parentNode;
- jpf.inherit.call(this, jpf.JmlDom); /** @inherits jpf.JmlDom */
-
- var parts = {
- bindings: 'loadBindings',
- actions : 'loadActions',
- dragdrop: 'loadDragDrop'
- };
-
- jpf.console.info(name
- ? "Creating SmartBinding [" + name + "]"
- : "Creating implicitly assigned SmartBinding");
-
- /**
- * @private
- */
- this.initialize = function(jmlNode, part){
- //register element
- this.jmlNodes[jmlNode.uniqueId] = jmlNode;
-
- if (part)
- return jmlNode[parts[part]](this[part], this["xml" + part]);
-
- if (jmlNode.$jml && this.name) //@todo is this still relevant?
- jmlNode.$jml.setAttribute("smartbinding", this.name);
-
- for (part in parts) {
- if (typeof parts[part] != "string") continue;
-
- if (!this[part]) continue;
-
- if (!jmlNode[parts[part]]) {
- throw new Error(jpf.formatErrorString(1035, jmlNode,
- "initializing smartBinding",
- "Could not find handler for '" + part + "'."));
- }
-
- jmlNode[parts[part]](this[part], this["xml" + part]);
- }
-
- if (this.$model) {
- this.$model.register(jmlNode, this.$modelXpath[jmlNode.getHost
- ? jmlNode.getHost().uniqueId
- : jmlNode.uniqueId] || this.modelBaseXpath); //this is a hack.. by making MOdels with links to other models possible, this should not be needed
- }
- else if (jmlNode.$model && (jmlNode.smartBinding && jmlNode.smartBinding != this))
- jmlNode.$model.reloadJmlNode(jmlNode.uniqueId);//.load(jmlNode.model.data.selectSingleNode("Accounts/Account[1]"));
-
- return this;
- };
-
- /**
- * @private
- */
- this.deinitialize = function(jmlNode){
- //unregister element
- this.jmlNodes[jmlNode.uniqueId] = null;
- delete this.jmlNodes[jmlNode.uniqueId];
-
- for (part in parts) {
- if (typeof parts[part] != "string") continue;
-
- if (!this[part]) continue;
-
- if (!jmlNode["un" + parts[part]]) {
- throw new Error(jpf.formatErrorString(1035, jmlNode,
- "deinitializing smartBinding",
- "Could not find handler for '" + part + "'."));
- }
-
- jmlNode["un" + parts[part]]();
- }
-
- if (this.model)
- this.model.unregister(jmlNode);
- };
-
- var timer, queue = {};
- this.markForUpdate = function(jmlNode, part){
- (queue[jmlNode.uniqueId]
- || (queue[jmlNode.uniqueId] = {}))[part || "all"] = jmlNode;
-
- if (!this.jmlNodes[jmlNode.uniqueId])
- this.jmlNodes[jmlNode.uniqueId] = jmlNode;
-
- if (!timer) {
- timer = setTimeout(function(){
- _self.$updateMarkedItems();
- });
- }
-
- return this;
- };
-
- this.$isMarkedForUpdate = function(jmlNode){
- return queue[jmlNode.uniqueId] ? true : false;
- }
-
- this.$updateMarkedItems = function(){
- clearTimeout(timer);
-
- var jmlNode, model, q = queue; timer = null; queue = {}
- for (var id in q) {
- //We're only processing nodes that are registered here
- if (!this.jmlNodes[id])
- continue;
-
- if (q[id]["all"]) {
- jmlNode = q[id]["all"];
- //model isn't done here
- for (part in parts) {
- if (!this[part]) continue;
- jmlNode[parts[part]](this[part], this["xml" + part]);
- }
-
- model = jmlNode.getModel();
- if (model)
- model.reloadJmlNode(jmlNode.uniqueId);
- else
- jmlNode.reload();
- }
- else {
- for (part in q[id]) {
- jmlNode = q[id][part];
- if (part == "model") {
- jmlNode.getModel().reloadJmlNode(jmlNode.uniqueId);
- continue;
- }
-
- jmlNode[parts[part]](this[part], this["xml" + part]);
- if (part == "bindings")
- jmlNode.reload();
- }
- }
- }
- };
-
- /**
- * @private
- */
- this.addBindRule = function(xmlNode, jmlParent){
- var str = xmlNode[jpf.TAGNAME] == "ref"
- ? jmlParent ? jmlParent.mainBind : "value"
- : xmlNode.tagName;
- if (!this.bindings)
- this.bindings = {};
- if (!this.bindings[str])
- this.bindings[str] = [xmlNode];
- else
- this.bindings[str].push(xmlNode);
- };
-
- /**
- * @private
- */
- this.addBindings = function(rules){
- this.bindings = rules;//jpf.getRules(xmlNode);
- this.xmlbindings = xmlNode;
-
- if (!jpf.isParsing) {
- //@todo, dynamically update part
- }
-
- if (!jpf.isParsing)
- this.markForUpdate(null, "bindings");
- };
-
- /**
- * @private
- */
- this.addActionRule = function(xmlNode){
- var str = xmlNode[jpf.TAGNAME] == "action" ? "Change" : xmlNode.tagName;
- if (!this.actions)
- this.actions = {};
- if (!this.actions[str])
- this.actions[str] = [xmlNode];
- else
- this.actions[str].push(xmlNode);
- };
-
- /**
- * @private
- */
- this.addActions = function(rules, xmlNode){
- this.actions = rules;//jpf.getRules(xmlNode);
- this.xmlactions = xmlNode;
-
- if (!jpf.isParsing)
- this.markForUpdate(null, "bindings");
- };
-
- /**
- * @private
- */
- this.addDropRule =
- this.addDragRule = function(xmlNode){
- if (!this.dragdrop)
- this.dragdrop = {};
- if (!this.dragdrop[xmlNode[jpf.TAGNAME]])
- this.dragdrop[xmlNode[jpf.TAGNAME]] = [xmlNode];
- else
- this.dragdrop[xmlNode[jpf.TAGNAME]].push(xmlNode);
- };
-
- /**
- * @private
- */
- this.addDragDrop = function(rules, xmlNode){
- this.dragdrop = rules;//jpf.getRules(xmlNode);
- this.xmldragdrop = xmlNode;
-
- if (!jpf.isParsing)
- this.markForUpdate(null, "dragdrop");
- };
-
- /**
- * @private
- */
- this.setModel = function(model, xpath){
- if (typeof model == "string")
- model = jpf.nameserver.get("model", model);
-
- this.model = jpf.nameserver.register("model", this.name, model);
- this.modelBaseXpath = xpath;
-
- for (var uniqueId in this.jmlNodes) {
- this.model.unregister(this.jmlNodes[uniqueId]);
- this.model.register(jmlNode, this.$modelXpath[jmlNode.getHost
- ? jmlNode.getHost().uniqueId
- : jmlNode.uniqueId] || this.modelBaseXpath); //this is a hack.. by making Models with links to other models possible, this should not be needed
- //this.jmlNodes[uniqueId].load(this.model);
- }
- };
-
- /**
- * Loads xml data in the model of this smartbinding element.
- *
- * @param {mixed} xmlNode
- * Possible values:
- * {XMLElement} the xml data element loaded in the model of this smartbinding element.
- * {String} the serialized xml which is loaded in the model of this smartbinding element.
- * {null} clears this element.
- */
- this.load = function(xmlNode){
- this.setModel(new jpf.model().load(xmlNode));
- };
-
- /**
- * @private
- *
- * @attribute {String} bindings the id of the bindings element that provides the binding rules for all elements connected to this smartbinding element
- * @attribute {String} actions the id of the actions element that provides the action rules for all elements connected to this smartbinding element
- * @attribute {String} dragdrop the id of the dragdrop element that provides the drag and drop rules for all elements connected to this smartbinding element
- * @attribute {String} model the id of the model element that provides the data for all elements connected to this smartbinding element.
- * @define bindings element containing all the binding rules for the data
- * bound elements referencing this element.
- * Example:
- * <code>
- * <j:bindings id="bndFolders" >
- * <j:caption select="@name" />
- * <j:icon select="@icon" />
- * <j:traverse select="folder" sort="@name" />
- * </j:bindings>
- *
- * <j:tree bindings="bndFolders" />
- * </code>
- * @see element.smartbinding
- * @allowchild {bindings}
- * @addnode smartbinding, global
- * @define actions element containing all the action rules for the data
- * bound elements referencing this element.
- * Example:
- * <code>
- * <j:actions id="actPerson" >
- * <j:add set="rpc:comm.addPerson({.})">
- * <person name="New person" />
- * </j:add
- * <j:rename set="rpc.comm.renamePerson({@id}, {@name})" />
- * <j:remove select="@new" set="rpc:comm.removePerson({@id})"/>
- * </j:actions>
- *
- * <j:tree actions="actPerson" />
- * </code>
- * @allowchild {actions}
- * @addnode smartbinding, global
- * @define dragdrop element containing all the dragdrop rules for the data
- * bound elements referencing this element.
- * Example:
- * This example shows drag and drop rules for a tree with person and
- * office elements. A person can be dragged to an office. An office can be
- * dragged but not dropped within this element. Possible an other element
- * does allow receiving an office element.
- * <code>
- * <j:dragdrop>
- * <j:allow-drag select="person|office" />
- * <j:allow-drop select="person" target="office"
- * operation="tree-append" copy-condition="event.ctrlKey" />
- * </j:dragdrop>
- * </code>
- * @allowchild allow-drag, allow-drop
- * @addnode smartbinding, global
- * @define ref shorthand for the default binding rule
- * @addnode smartbinding
- * @define action shorthand for the default action rule.
- * @addnode smartbinding
- */
- var known = {
- actions : "addActions",
- bindings : "addBindings",
- dragdrop : "addDragDrop"
- };
-
- this.loadJml = function(xmlNode){
- this.name = xmlNode.getAttribute("id");
- this.$jml = xmlNode;
-
- var name, attr = xmlNode.attributes, l = attr.length;
- for (var i = 0; i < l; i++) {
- name = attr[i].nodeName;
- if (name == "model")
- continue;
-
- if (!known[name])
- continue;
-
- if (!jpf.nameserver.get(name, attr[i].nodeValue))
- throw new Error(jpf.formatErrorString(1036, this,
- "Connecting " + name,
- "Could not find " + name + " by name '"
- + attr[i].nodeValue + "'"));
-
- var cNode = jpf.nameserver.get(name, attr[i].nodeValue);
- this[known[name]](jpf.getRules(cNode), cNode);
- }
-
- var data_node, nodes = xmlNode.childNodes;
- for (var i = 0; i < nodes.length; i++) {
- if (nodes[i].nodeType != 1) continue;
-
- switch (nodes[i][jpf.TAGNAME]) {
- case "model":
- data_node = nodes[i];
- break;
- case "bindings":
- this.addBindings(jpf.getRules(nodes[i]), nodes[i]);
- break;
- case "actions":
- this.addActions(jpf.getRules(nodes[i]), nodes[i]);
- break;
- case "dragdrop":
- this.addDragDrop(jpf.getRules(nodes[i]), nodes[i]);
- break;
- case "ref":
- this.addBindRule(nodes[i]);
- break;
- case "action":
- this.addActionRule(nodes[i]);
- break;
- default:
- throw new Error(jpf.formatErrorString(1039, this,
- "setSmartBinding Method",
- "Could not find handler for '"
- + nodes[i].tagName + "' node."));
- break;
- }
- }
-
- //Set Model
- if (data_node)
- this.setModel(new jpf.model().loadJml(data_node));
- else if (xmlNode.getAttribute("model"))
- jpf.setModel(xmlNode.getAttribute("model"), this);
- };
-
- if (xmlNode)
- this.loadJml(xmlNode);
-};
-
-
- - -/*FILEHEAD(/var/lib/jpf/src/elements/lineselect.js)SIZE(-1077090856)TIME(1225628613)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * Element displaying text with each line being selectable. This is especially
- * useful for log messages.
- * @experimental
- * @todo test this
- */
-jpf.lineselect = jpf.component(jpf.NODE_VISIBLE, function(){
- this.deselect = function(){
- this.value = this.selected = null;
- }
-
- this.select = function(node){
- if(this.selected) this.selected.className = this.skin.clsItem;
-
- node.className = this.skin.clsSelected;
- this.selected = node;
-
- this.dispatchEvent("afterselect", node.innerHTML);
- }
-
- this.$focus = function(){
- if(this.selected) this.selected.className = this.skin.clsSelected;
- }
-
- this.$blur = function(){
- if(this.selected) this.selected.className = this.skin.clsBlur;
- }
-
- this.$focussable = true;
-
- this.getHTML = function(t){
- t = t.replace(/</g, "<");
- t = t.replace(/>/g, ">");
- t = t.replace(/(^|\n)[^\(]*\(/g, "\n(");
- return t;
- }
-
- this.loadText = function(text){
- //this.parentNode.style.width = this.parentNode.offsetWidth;
-
- var ar = this.getHTML(text).split("\n");
-
- for(var i=0;i<ar.length;i++){
- if(ar[i].match(/error \E/)) var clr = "red";
- else if(ar[i].match(/warning \P/)) var clr = "yellow";
- else var clr = "white";
-
- ar[i] = "<div style='color:" + clr + "' onmousedown='" + 'jpf.lookup(' + this.uniqueId + ').select(this)' + "' ondblclick=\"" + 'jpf.lookup(' + this.uniqueId + ').dispatchEvent(\'onchoose\', this.innerHTML)' + "\" class='" + this.skin.clsItem + "'>" + ar[i] + "</div>";
- }
-
- this.oExt.innerHTML = "<div style='color:white' class='" + this.skin.clsItem + "'>Javeline Script Encoder</div><div nowrap style='color:white' class='" + this.skin.clsItem + "'>(c) 2001-2003 All Rights Reserved.</div><br>" + ar.join("");
- //this.parentNode.style.width = "100%";
- }
-
- this.addEventListener("keydown", function(e){
- var key = e.keyCode;
-
- if(this.renaming){
- if(key == 27 || key == 13){
- this.stopRename();
- if(key == 13) this.stopRename();
- }
-
- return;
- }
-
- if(!this.selected) return;
-
- switch(key){
- case 13:
- this.dispatchEvent("choose");
- break;
- case 38:
- //UP
- if(!this.value) return;
- var node = this.value;
-
- if(node.previousSibling) node = node.previousSibling;
- if(node && node.nodeType == 1) this.select(document.getElementById(node.getAttribute("id")));
-
- //this.selected.scrollIntoView();
- return false;
- break;
- case 40:
- //DOWN
- if(!this.value) return;
- var node = this.value;
-
- if(node.nextSibling) node = node.nextSibling;
- if(node && node.nodeType == 1) this.select(document.getElementById(node.getAttribute("id")));
-
- //this.selected.scrollIntoView();
- return false;
- break;
- }
- }, true);
-
- /**** Init ****/
-
- this.$draw = function(clear, parentNode){
- this.oExt = this.$getExternal();
- this.oInt = this.oExt;
- }
-}).implement(
- jpf.Presentation
-);
- - -/*FILEHEAD(/var/lib/jpf/src/elements/modalwindow.js)SIZE(-1077090856)TIME(1239027647)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -/** - * @private - */ -jpf.WinServer = { - count : 9000, - wins : [], - - setTop : function(win){ - this.count += 2; - - win.setProperty("zindex", this.count); - this.wins.remove(win); - this.wins.push(win); - return win; - }, - - setNext : function(){ - if (this.wins.length < 2) return; - var nwin, start = this.wins.shift(); - do { - if (this.setTop(nwin || start).visible) - break; - nwin = this.wins.shift(); - } while (start != nwin); - }, - - setPrevious : function(){ - if (this.wins.length < 2) return; - this.wins.unshift(this.wins.pop()); - var nwin, start = this.wins.pop(); - do { - if (this.setTop(nwin || start).visible) - break; - nwin = this.wins.pop(); - } while (start != nwin); - }, - - remove : function(win){ - this.wins.remove(win); - } -} - -/** - * Element displaying a skinnable, draggable window with optionally - * a min, max, edit and close button. This element is also used - * as a portal widget container. Furthermore this element supports - * docking in an alignment layout. - * Example: - * <code> - * <j:window id="winMail" - * modal = "false" - * buttons = "min|max|close" - * title = "Mail message" - * icon = "icoMail.gif" - * visible = "true" - * resizable = "true" - * minwidth = "300" - * minheight = "290"> - * ... - * </j:window> - * </code> - * - * @constructor - * @define modalwindow - * @allowchild {elements}, {smartbinding}, {anyjml} - * @addnode elements - * - * @author Ruben Daniels - * @version %I%, %G% - * @since 0.4 - * - * @inherits jpf.Presentation - * @inherits jpf.DelayedRender - * @inherits jpf.Docking - * - * @event display Fires when the window is displayed. - * @event close Fires when the window is closed. - * @event editstart Fires before the user edits the properties of this window. Used mostly for when this window is part of the {@link element.portal}. - * @event editstop Fires after the user edited the properties of this window. Used mostly for when this window is part of the {@link element.portal}. - * cancellable: Prevents the edit panel from being closed. - * @event statechange Fires after the state of this window changed. - * object: - * {Boolean} minimized wether the window is minimized. - * {Boolean} maximized wether the window is maximized. - * {Boolean} normal wether the window has it's normal size and position. - * {Boolean} edit wether the window is in the edit state. - * {Boolean} closed wether the window is closed. - */ -jpf.modalwindow = jpf.component(jpf.NODE_VISIBLE, function(){ - this.isWindowContainer = true; - this.canHaveChildren = 2; - this.animate = true;//!jpf.hasSingleRszEvent; // experimental - this.visible = false; - this.showdragging = false; - this.buttons = "min|max|close"; - this.$focussable = jpf.KEYBOARD; - this.state = "normal"; - this.edit = false; - var _self = this; - - this.editableParts = {"main" : [["title","@title"]]}; - - /**** Public Methods ****/ - - /** - * Sets the title of the window. - * @param {String} caption the text of the title. - */ - this.setTitle = function(caption){ - this.setProperty("title", caption); - }; - - /** - * Sets the icon of the window. - * @param {String} icon the location of the image. - */ - this.setIcon = function(icon){ - this.setProperty("icon", icon); - }; - - /** - * Close the window. It can be reopened by using {@link baseclass.jmlelement.method.show} - * @todo show should unset closed - */ - this.close = function(){ - this.setProperty("state", this.state.split("|") - .pushUnique("closed").join("|")); - }; - - /** - * Minimize the window. The window will become the height of the title of - * the window. - */ - this.minimize = function(){ - this.setProperty("state", this.state.split("|") - .remove("maximized") - .remove("normal") - .pushUnique("minimized").join("|")); - }; - - /** - * Maximize the window. The window will become the width and height of the - * browser window. - */ - this.maximize = function(){ - this.setProperty("state", this.state.split("|") - .remove("minimized") - .remove("normal") - .pushUnique("maximized").join("|")); - }; - - /** - * Restore the size of the window. The window will become the width and - * height it had before it was minimized or maximized. - */ - this.restore = function(){ - this.setProperty("state", this.state.split("|") - .remove("minimized") - .remove("maximized") - .pushUnique("normal").join("|")); - }; - - /** - * Set the window into edit state. The configuration panel is shown. - */ - this.edit = function(value){ - this.setProperty("state", this.state.split("|") - .pushUnique("edit").join("|")); - }; - - /** - * Removes the edit state of this window. The configuration panel is hidden. - */ - this.closeedit = function(value){ - this.setProperty("state", this.state.split("|") - .remove("edit").join("|")); - }; - - this.bringToFront = function(){ - jpf.WinServer.setTop(this); - }; - - var actions = { - "min" : ["minimized", "minimize", "restore"], - "max" : ["maximized", "maximize", "restore"], - "edit" : ["edit", "edit", "closeedit"], - "close" : ["closed", "close", "show"] - }; - - this.$toggle = function(type){ - var c = actions[type][0]; - this[actions[type][this.state.indexOf(c) > -1 ? 2 : 1]](); - }; - - /** - * @todo change this to use setProperty - * @private - */ - this.syncAlignment = function(oItem){ - if (oItem.hidden == 3) - jpf.WinServer.setTop(this); - - if (oItem.state > 0) { - this.$setStyleClass(this.oExt, this.baseCSSname + "Min", - [this.baseCSSname + "Edit", this.baseCSSname + "Max"]); - } - else { - this.$setStyleClass(this.oExt, "", [this.baseCSSname + "Min", - this.baseCSSname + "Edit", this.baseCSSname + "Max"]); - } - }; - - /**** Properties and Attributes ****/ - - this.$booleanProperties["modal"] = true; - this.$booleanProperties["center"] = true; - this.$booleanProperties["transaction"] = true; - this.$booleanProperties["hideselects"] = true; - this.$booleanProperties["animate"] = true; - this.$booleanProperties["showdragging"] = true; - this.$supportedProperties.push("title", "icon", "modal", "minwidth", - "minheight", "hideselects", "center", "buttons", "state", - "maxwidth", "maxheight", "animate", "showdragging", "transaction"); - - /** - * @attribute {Boolean} modal whether the window prevents access to the - * layout below it. - */ - this.$propHandlers["modal"] = function(value){ - if (value && !this.oCover) { - var oCover = this.$getLayoutNode("cover"); - if (oCover) { - this.oCover = jpf.xmldb.htmlImport(oCover, this.pHtmlNode); - - if (!this.visible) - this.oCover.style.display = "none"; - - this.oCover.style.zIndex = this.zindex; - } - } - - if (!value && this.oCover) { - this.oCover.style.display = "none"; - } - }; - - /** - * @attribute {Boolean} center centers the window relative to it's parent's - * containing rect when shown. - */ - this.$propHandlers["center"] = function(value){ - this.oExt.style.position = "absolute"; //@todo no unset - }; - - /** - * @attribute {String} title the text of the title. - */ - this.$propHandlers["title"] = function(value){ - this.oTitle.nodeValue = value; - }; - - /** - * @attribute {String} icon the location of the image. - */ - this.$propHandlers["icon"] = function(value){ - if (!this.oIcon) return; - - this.oIcon.style.display = value ? "block" : "none"; - jpf.skins.setIcon(this.oIcon, value, this.iconPath); - }; - - var hEls = [], wasVisible; - this.$propHandlers["visible"] = function(value){ - if (jpf.isTrue(value)){ - //if (!x && !y && !center) center = true; - - this.$render(); - - if (this.oCover){ - /*this.oCover.style.height = Math.max(document.body.scrollHeight, - document.documentElement.offsetHeight) + 'px'; - this.oCover.style.width = Math.max(document.body.scrollWidth, - document.documentElement.offsetWidth) + 'px';*/ - this.oCover.style.display = "block"; - } - - this.state = this.state.split("|").remove("closed").join("|"); - - this.oExt.style.display = "block"; //Some form of inheritance detection - - //!jpf.isIE && - if (jpf.layout && this.oInt) - jpf.layout.forceResize(this.oInt); //this should be recursive down - - if (this.center) { - this.oExt.style.left = Math.max(0, (( - (jpf.isIE - ? this.oExt.offsetParent.offsetWidth - : window.innerWidth) - - this.oExt.offsetWidth)/2)) + "px"; - this.oExt.style.top = Math.max(0, (( - (jpf.isIE - ? this.oExt.offsetParent.offsetHeight - : window.innerHeight) - - this.oExt.offsetHeight)/3)) + "px"; - } - - if (!this.isRendered) { - this.addEventListener("afterrender", function(){ - this.dispatchEvent("display"); - this.removeEventListener("display", arguments.callee); - }); - } - else - this.dispatchEvent("display"); - - if (!jpf.canHaveHtmlOverSelects && this.hideselects) { - hEls = []; - var nodes = document.getElementsByTagName("select"); - for (var i = 0; i < nodes.length; i++) { - var oStyle = jpf.getStyle(nodes[i], "display"); - hEls.push([nodes[i], oStyle]); - nodes[i].style.display = "none"; - } - } - - if (wasVisible != true && this.$show) - this.$show(); - - if (this.modal) { - this.bringToFront(); - if (!jpf.isParsing) - this.focus(false, {mouse:true}); - } - - if (jpf.isIE) { - var cls = this.oExt.className; - this.oExt.className = "rnd" + Math.random(); - this.oExt.className = cls; - } - } - else if (jpf.isFalse(value)) { - //this.setProperty("visible", false); - if (this.oCover) - this.oCover.style.display = "none"; - - this.oExt.style.display = "none"; - - if (!jpf.canHaveHtmlOverSelects && this.hideselects) { - for (var i = 0; i < hEls.length; i++) { - hEls[i][0].style.display = hEls[i][1]; - } - } - - if (this.$hide) - this.$hide(); - - if (this.hasFocus()) - jpf.window.moveNext(null, this, true) - - this.dispatchEvent("close"); - } - - wasVisible = value; - }; - - this.$propHandlers["zindex"] = function(value){ - this.oExt.style.zIndex = value + 1; - if (this.oCover) - this.oCover.style.zIndex = value; - }; - - var lastheight = null; - var lastpos = null; - var lastzindex = null; - var lastState = {"normal":1}; - - /** - * @attribute {String} state the state of the window. The state can be a - * combination of multiple states seperated by a pipe '|' character. - * Possible values: - * minimized The window is minimized. - * maximized The window is maximized. - * normal The window has it's normal size and position. - * edit The window is in the edit state. - * closed The window is closed. - */ - this.$propHandlers["state"] = function(value, noanim){ - var i, o = {}, s = value.split("|"); - for (i = 0; i < s.length; i++) - o[s[i]] = true; - - var styleClass = []; - - if (!o.maximized && !o.minimized) - o.normal = true; - - //Closed state - if (o.closed == this.visible) {//change detected - this.setProperty("visible", !o["closed"]); - //@todo difference is, we're not clearing the other states, check the docking example - } - - //Restore state - if (o.normal != lastState.normal - || !o.normal && (o.minimized != lastState.minimized - || o.maximized != lastState.maximized)) { - - if (lastheight) { // this.aData && this.aData.hidden == 3 ?? - this.oExt.style.height = (lastheight - - jpf.getHeightDiff(this.oExt)) + "px"; - } - - if (lastpos) { - if (this.animate && !noanim) { - //Pre remove paused event because of not having onresize - //if (jpf.hasSingleRszEvent) - //delete jpf.layout.onresize[jpf.layout.getHtmlId(this.pHtmlNode)]; - - _self.animstate = 1; - jpf.tween.multi(this.oExt, { - steps : 5, - interval : 10, - tweens : [ - {type: "left", from: this.oExt.offsetLeft, to: lastpos[0]}, - {type: "top", from: this.oExt.offsetTop, to: lastpos[1]}, - {type: "width", from: this.oExt.offsetWidth, to: lastpos[2]}, - {type: "height", from: this.oExt.offsetHeight, to: lastpos[3]} - ], - oneach : function(){ - if (jpf.hasSingleRszEvent) - jpf.layout.forceResize(_self.oInt); - }, - onfinish : function(){ - _self.$propHandlers["state"].call(_self, value, true); - } - }); - - return; - } - - this.oExt.style.left = lastpos[0] + "px"; - this.oExt.style.top = lastpos[1] + "px"; - this.oExt.style.width = lastpos[2] + "px"; - this.oExt.style.height = lastpos[3] + "px"; - - var pNode = (this.oExt.parentNode == document.body - ? this.oExt.offsetParent || document.documentElement - : this.oExt.offsetParent); - pNode.style.overflow = lastpos[4]; - } - - if (this.aData && this.aData.restore) - this.aData.restore(); - - if (jpf.layout) - jpf.layout.play(this.pHtmlNode); - - if (lastzindex) { - this.oExt.style.zIndex = lastzindex[0]; - if (this.oCover) - this.oCover.style.zIndex = lastzindex[1]; - } - - lastheight = lastpos = lastzindex = null; - - if (o.normal) - styleClass.push("", - this.baseCSSname + "Max", - this.baseCSSname + "Min"); - } - - if (o.minimized != lastState.minimized) { - if (o.minimized) { - styleClass.unshift( - this.baseCSSname + "Min", - this.baseCSSname + "Max", - this.baseCSSname + "Edit"); - - if (this.aData && this.aData.minimize) - this.aData.minimize(this.collapsedHeight); - - if (!this.aData || !this.aData.minimize) { - lastheight = this.oExt.offsetHeight; - - this.oExt.style.height = Math.max(0, this.collapsedHeight - - jpf.getHeightDiff(this.oExt)) + "px"; - } - - if (this.hasFocus()) - jpf.window.moveNext(null, this, true); - //else if(jpf.window.focussed) - //jpf.window.focussed.$focus({mouse: true}); - } - else { - styleClass.push(this.baseCSSname + "Min"); - - setTimeout(function(){ - jpf.window.$focusLast(_self); - }); - } - } - - if (o.maximized != lastState.maximized) { - if (o.maximized) { - styleClass.unshift( - this.baseCSSname + "Max", - this.baseCSSname + "Min", - this.baseCSSname + "Edit"); - - var pNode = (this.oExt.parentNode == document.body - ? this.oExt.offsetParent || document.documentElement - : this.oExt.parentNode); - - lastpos = [this.oExt.offsetLeft, this.oExt.offsetTop, - this.oExt.offsetWidth - hordiff, this.oExt.offsetHeight - verdiff, - pNode.style.overflow]; - - pNode.style.overflow = "hidden"; - - _self.animstate = 0; - var hasAnimated = false, htmlNode = this.oExt; - function setMax(){ - var w = !jpf.isIE && pNode == document.documentElement - ? window.innerWidth - : pNode.offsetWidth; - - var h = !jpf.isIE && pNode == document.documentElement - ? window.innerHeight - : pNode.offsetHeight; - - if (_self.animate && !hasAnimated) { - _self.animstate = 1; - hasAnimated = true; - jpf.tween.multi(htmlNode, { - steps : 5, - interval : 10, - tweens : [ - {type: "left", from: htmlNode.offsetLeft, to: -1 * marginBox[3]}, - {type: "top", from: htmlNode.offsetTop, to: -1 * marginBox[0]}, - {type: "width", from: htmlNode.offsetWidth, to: (w - hordiff + marginBox[1] + marginBox[3])}, - {type: "height", from: htmlNode.offsetHeight, to: (h - verdiff + marginBox[0] + marginBox[2])} - ], - oneach : function(){ - if (jpf.hasSingleRszEvent) - jpf.layout.forceResize(_self.oInt); - }, - onfinish : function(){ - _self.animstate = 0; - } - }); - } - else if (!_self.animstate) { - htmlNode.style.left = (-1 * marginBox[3]) + "px"; - htmlNode.style.top = (-1 * marginBox[0]) + "px"; - - htmlNode.style.width = (w - - hordiff + marginBox[1] + marginBox[3]) + "px"; - htmlNode.style.height = (h - - verdiff + marginBox[0] + marginBox[2]) + "px"; - } - } - - if (jpf.layout) - jpf.layout.pause(this.pHtmlNode, setMax); - - lastzindex = [ - this.oExt.style.zIndex || 1, - this.oCover && this.oCover.style.zIndex || 1 - ]; - if (this.oCover) - this.oCover.style.zIndex = jpf.WinServer.count + 1; - this.oExt.style.zIndex = jpf.WinServer.count + 2; - } - else { - styleClass.push(this.baseCSSname + "Max"); - } - } - - if (o.edit != lastState.edit) { - if (o.edit) { - styleClass.unshift( - this.baseCSSname + "Edit", - this.baseCSSname + "Max", - this.baseCSSname + "Min"); - - if (this.btnedit) - oButtons.edit.innerHTML = "close"; //hack - - this.dispatchEvent('editstart'); - } - else { - if (this.dispatchEvent('editstop') === false) - return false; - - styleClass.push(this.baseCSSname + "Edit"); - if (styleClass.length == 1) - styleClass.unshift(""); - - if (this.btnedit) - oButtons.edit.innerHTML = "edit"; //hack - } - } - - if (styleClass.length) { - this.$setStyleClass(this.oExt, styleClass.shift(), styleClass); - - this.dispatchEvent('statechange', o); - lastState = o; - - if (this.aData && !o.maximized) { //@todo is this the most optimal position? - this.purgeAlignment(); - } - - if (!this.animate && jpf.hasSingleRszEvent && jpf.layout) - jpf.layout.forceResize(_self.oInt); - } - }; - - var oButtons = {} - /** - * @attribute {String} buttons the buttons that the window displays. This - * can be multiple values seperated by a pipe '|' character. - * Possible values: - * min The button that minimizes the window. - * max The button that maximizes the window. - * close The button that closes the window. - * edit The button that puts the window into the edit state. - */ - this.$propHandlers["buttons"] = function(value){ - var buttons = value.split("|"); - var nodes = this.oButtons.childNodes; - var re = new RegExp("(" + value + ")"); - var found = {}; - - //Check if we can 'remove' buttons - var idleNodes = []; - for (var i = 0; i < nodes.length; i++) { - if (nodes[i].nodeType != 1 || nodes[i].tagName != "DIV") //@todo temp hack - continue; - - if (!nodes[i].className || !nodes[i].className.match(re)) { - nodes[i].style.display = "none"; - this.$setStyleClass(nodes[i], "", ["min", "max", "close", "edit"]); - idleNodes.push(nodes[i]); - } - else - found[RegExp.$1] = nodes[i]; - } - - //Create new buttons if needed - for (i = 0; i < buttons.length; i++) { - if (found[buttons[i]]) { - this.oButtons.insertBefore(found[buttons[i]], this.oButtons.firstChild); - continue; - } - - var btn = idleNodes.pop(); - if (!btn) { - this.$getNewContext("button"); - btn = this.$getLayoutNode("button"); - setButtonEvents(btn); - btn = jpf.xmldb.htmlImport(btn, this.oButtons); - } - - this.$setStyleClass(btn, buttons[i], ["min", "max", "close", "edit"]); - btn.onclick = new Function("jpf.lookup(" + this.uniqueId + ").$toggle('" - + buttons[i] + "')"); - btn.style.display = "block"; - oButtons[buttons[i]] = btn; - this.oButtons.insertBefore(btn, this.oButtons.firstChild); - } - }; - - /**** Keyboard ****/ - - this.addEventListener("keydown", function(e){ - var key = e.keyCode; - var ctrlKey = e.ctrlKey; - var shiftKey = e.shiftKey; - - if (key > 36 && key < 41) { - if (_self.hasFeature && _self.hasFeature(__ANCHORING__)) - _self.disableAnchoring(); - } - - switch (key) { - case 27: - if (this.buttons.indexOf("close") > -1 && !this.aData) - this.close(); - return; - /*case 9: - break; - case 13: - break; - case 32: - break;*/ - case 38: - //UP - if (shiftKey && this.resizable) - this.setProperty("height", Math.max(this.minheight || 0, - this.oExt.offsetHeight - (ctrlKey ? 50 : 10))); - else if (this.draggable) - this.setProperty("top", - this.oExt.offsetTop - (ctrlKey ? 50 : 10)); - break; - case 37: - //LEFT - if (shiftKey && this.resizable) - this.setProperty("width", Math.max(this.minwidth || 0, - this.oExt.offsetWidth - (ctrlKey ? 50 : 10))); - else if (this.draggable) - this.setProperty("left", - this.oExt.offsetLeft - (ctrlKey ? 50 : 10)); - break; - case 39: - //RIGHT - if (shiftKey && this.resizable) - this.setProperty("width", Math.min(this.maxwidth || 10000, - this.oExt.offsetWidth + (ctrlKey ? 50 : 10))); - else if (this.draggable) - this.setProperty("left", - this.oExt.offsetLeft + (ctrlKey ? 50 : 10)); - break; - case 40: - //DOWN - if (shiftKey && this.resizable) - this.setProperty("height", Math.min(this.maxheight || 10000, - this.oExt.offsetHeight + (ctrlKey ? 50 : 10))); - else if (this.draggable) - this.setProperty("top", - this.oExt.offsetTop + (ctrlKey ? 50 : 10)); - break; - default: - return; - } - - if (jpf.hasSingleRszEvent) - jpf.layout.forceResize(this.oInt); - }, true); - - function setButtonEvents(btn){ - btn.setAttribute("onmousedown", - "jpf.setStyleClass(this, 'down');\ - event.cancelBubble = true; \ - jpf.findHost(this).oExt.onmousedown(event);\ - document.onmousedown(event);"); - btn.setAttribute("onmouseup", - "jpf.setStyleClass(this, '', ['down'])"); - btn.setAttribute("onmouseover", - "jpf.setStyleClass(this, 'hover')"); - btn.setAttribute("onmouseout", - "jpf.setStyleClass(this, '', ['hover', 'down'])"); - } - - /**** Init ****/ - - var marginBox, hordiff, verdiff; - this.$draw = function(){ - this.popout = jpf.isTrue(this.$jml.getAttribute("popout")); - if (this.popout) - this.pHtmlNode = document.body; - - this.oExt = this.$getExternal(null, null, function(oExt){ - var oButtons = this.$getLayoutNode("main", "buttons", oExt); - if (!oButtons) - return; - - var len = (this.$jml.getAttribute("buttons") || "").split("|").length; - for (var btn, i = 0; i < len; i++) { - this.$getNewContext("button"); - btn = oButtons.appendChild(this.$getLayoutNode("button")); - setButtonEvents(btn); - } - }); - this.oTitle = this.$getLayoutNode("main", "title", this.oExt); - this.oIcon = this.$getLayoutNode("main", "icon", this.oExt); - this.oDrag = this.$getLayoutNode("main", "drag", this.oExt); - this.oButtons = this.$getLayoutNode("main", "buttons", this.oExt); - this.oDrag.host = this; - - if (this.oIcon) - this.oIcon.style.display = "none"; - - this.oDrag.onmousedown = function(e){ - if (!e) e = event; - - //because of some issue I don't understand oExt.onmousedown is not called - if (!_self.isWidget && (!_self.aData || !_self.dockable || _self.aData.hidden == 3)) - jpf.WinServer.setTop(_self); - - if (lastState.maximized) - return false; - - if (_self.aData && _self.dockable) { - if (lastState.normal) //@todo - _self.startDocking(e); - return false; - } - }; - - this.oExt.onmousedown = function(){ - //Set ZIndex on oExt mousedown - if (!_self.isWidget && (!_self.aData || !_self.dockable || _self.aData.hidden == 3)) - jpf.WinServer.setTop(_self); - - if (!lastState.normal) - return false; - } - this.oExt.onmousemove = function(){ - if (!lastState.normal) - return false; - } - - var diff = jpf.getDiff(this.oExt); - hordiff = diff[0]; - verdiff = diff[1]; - marginBox = jpf.getBox(jpf.getStyle(this.oExt, "borderWidth")); - - if (this.hasFeature(__MULTILANG__)) - this.$makeEditable("main", this.oExt, this.$jml); - - /*var v; - if (!jpf.dynPropMatch.test(v = this.$jml.getAttribute("visible"))) { - this.$jml.setAttribute("visible", "{" + jpf.isTrue(v) + "}"); - }*/ - }; - - this.$loadJml = function(x){ - jpf.WinServer.setTop(this); - - var oInt = this.$getLayoutNode("main", "container", this.oExt); - - this.oInt = this.oInt - ? jpf.JmlParser.replaceNode(oInt, this.oInt) - : jpf.JmlParser.parseChildren(this.$jml, oInt, this, true); - - (this.oTitle.nodeType != 1 - ? this.oTitle.parentNode - : this.oTitle).ondblclick = function(e){ - if (_self.state.indexOf("normal") == -1) - _self.restore(); - else if (_self.buttons.indexOf("max") > -1) - _self.maximize(); - else if (_self.buttons.indexOf("min") > -1) - _self.minimize(); - } - - if (this.draggable === undefined) { - (this.$propHandlers.draggable - || jpf.JmlElement.propHandlers.draggable).call(this, true); - this.draggable = true; - } - - if (this.modal === undefined && this.oCover) { - this.$propHandlers.modal.call(this, true); - this.modal = true; - } - - //Set default visible hidden - if (!this.visible) { - this.oExt.style.display = "none"; - - if (this.oCover) - this.oCover.style.display = "none"; - } - else if (this.modal) - this.focus(false, {mouse:true}); - - this.collapsedHeight = this.$getOption("Main", "collapsed-height"); - - if (this.minwidth === undefined) - this.minwidth = this.$getOption("Main", "min-width"); - if (this.minheight === undefined) - this.minheight = this.$getOption("Main", "min-height"); - if (this.maxwidth === undefined) - this.maxwidth = this.$getOption("Main", "max-width"); - if (this.maxheight === undefined) - this.maxheight = this.$getOption("Main", "max-height"); - - if (this.center && this.visible) { - this.visible = false; - this.oExt.style.display = "none"; /* @todo temp done for project */ - jpf.JmlParser.stateStack.push({ - node : this, - name : "visible", - value : "true" - }); - } - }; - - this.$skinchange = function(){ - if (this.title) - this.$propHandlers["title"].call(this, this.title); - - if (this.icon) - this.$propHandlers["icon"].call(this, this.icon); - } - - this.$destroy = function(skinChange){ - if (this.oDrag) { - this.oDrag.host = null; - this.oDrag.onmousedown = null; - jpf.removeNode(this.oDrag); - this.oDrag = null; - } - - this.oTitle = this.oIcon = this.oCover = null; - - for (var name in oButtons) { - oButtons[name].onclick = null; - } - - if (this.oExt && !skinChange) { - this.oExt.onmousedown = null; - this.oExt.onmousemove = null; - } - }; -}).implement( - jpf.DelayedRender, - jpf.Docking, - jpf.Presentation -); - - -/*FILEHEAD(/var/lib/jpf/src/elements/video.js)SIZE(-1077090856)TIME(1238933683)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -/** - * @classDescription This class creates a new video - * @return {Video} Returns a new video - * @type {Video} - * @inherits jpf.Presentation - * @inherits jpf.Media - * @constructor - * @allowchild {text} - * @addnode elements:video - * @link http://www.whatwg.org/specs/web-apps/current-work/#video - * - * @author Mike de Boer - * @version %I%, %G% - * @since 1.0 - */ - -jpf.video = jpf.component(jpf.NODE_VISIBLE, function(){ - this.$booleanProperties["fullscreen"] = true; - - var oldStyle = null; //will hold old style of the media elements' parentNode on fullscreen - //var placeHolder = null; - this.$propHandlers["fullscreen"] = function(value) { - if (!this.player) return; - // only go fullscreen when the feature is supported by the active player - if (typeof this.player.setFullscreen == "function") - this.player.setFullscreen(value); - else if (this.parentNode && this.parentNode.tagName != "application" - && this.parentNode.setWidth) { - // we're going into fullscreen mode... - var i, node, oParent = this.parentNode.oExt; - if (value) { - oldStyle = { - width : this.parentNode.getWidth(), - height : this.parentNode.getHeight(), - top : this.parentNode.getTop(), - left : this.parentNode.getLeft(), - position : jpf.getStyle(oParent, 'position'), - zIndex : jpf.getStyle(oParent, 'z-index'), - resizable: this.parentNode.resizable, - nodes : [] - } - - if (oParent != document.body) { - while (oParent.parentNode != document.body) { - var node = oParent.parentNode; - i = oldStyle.nodes.push({ - pos: jpf.getSyle(node, 'position') || "", - top: jpf.getSyle(node, 'top') || node.offsetTop + "px", - left: jpf.getSyle(node, 'left') || node.offsetLeft + "px", - node: node - }) - 1; - node.style.position = "absolute"; - node.style.top = "0"; - node.style.left = "0"; - /*window.console.log('still reparenting!'); - window.console.dir(oParent.parentNode); - placeHolder = document.createElement('div'); - placeHolder.setAttribute('id', '__jpf_video_placeholder__'); - placeHolder.style.display = "none"; - oParent.parentNode.insertBefore(placeHolder, oParent); - - document.body.appendChild(oParent);*/ - } - } - - this.parentNode.oExt.style.position = "absolute"; - this.parentNode.oExt.style.zIndex = "1000000"; - this.parentNode.setWidth('100%'); - this.parentNode.setHeight('100%'); - this.parentNode.setTop('0'); - this.parentNode.setLeft('0'); - - if (this.parentNode.resizable) - this.parentNode.setAttribute("resizable", false); - } - // we're going back to normal mode... - else if (oldStyle) { - var coll; - if (oldStyle.nodes.length) { - for (i = oldStyle.nodes.length - 1; i >= 0; i--) { - coll = oldStyle.nodes[i]; - node = coll.node; - node.style.position = coll.pos; - node.style.top = coll.top; - node.style.left = coll.left; - } - } - /*if (placeHolder) { - window.console.log('still reparenting!'); - placeHolder.parentNode.insertBefore(oParent, placeHolder); - placeHolder.parentNode.removeChild(placeHolder); - placeHolder = null; - }*/ - - this.parentNode.oExt.style.zIndex = oldStyle.zIndex; - this.parentNode.oExt.style.position = oldStyle.position; - this.parentNode.setWidth(oldStyle.width); - this.parentNode.setHeight(oldStyle.height); - this.parentNode.setTop(oldStyle.top); - this.parentNode.setLeft(oldStyle.left); - - if (oldStyle.resizable) - this.parentNode.setAttribute("resizable", true); - - oldStyle = null; - delete oldStyle; - } - - if (this.player.onAfterFullscreen) - this.player.onAfterFullscreen(value); - - var _self = this; - window.setTimeout(function() { - jpf.layout.forceResize(_self.parentNode.oExt); - }, 100) - } - }; - - /**** Event listeners ****/ - - this.addEventListener("keydown", function(e){ - switch (e.keyCode) { - case 13 && (e.ctrlKey || e.altKey): //(CTRL | ALT) + RETURN - case 70: //f - this.setPropery("fullscreen", true); - return false; - break; - case 80: - this.setProperty("paused", !this.paused); - return false; - break; - case 27: //ESC - this.setProperty("fullscreen", false); - return false; - break; - default: - break; - }; - }, true); - - this.mainBind = "src"; - - /** - * Load a video by setting the URL pointer to a different video file - * - * @param {String} sVideo - * @type {Object} - */ - //var dbLoad = this.load; - this.loadMedia = function() { - if (!arguments.length) { - if (this.player) { - this.setProperty('currentSrc', this.src); - this.setProperty('networkState', jpf.Media.NETWORK_LOADING); - this.player.load(this.src); - } - } - else { - dbLoad.apply(this, arguments); - } - - return this; - }; - - /** - * Seek the video to a specific position. - * - * @param {Number} iTo The number of seconds to seek the playhead to. - * @type {Object} - */ - this.seek = function(iTo) { - if (this.player && iTo >= 0 && iTo <= this.duration) - this.player.seek(iTo); - }; - - /** - * Set the volume of the video to a specific range (0 - 100) - * - * @param {Number} iVolume - * @type {Object} - */ - this.setVolume = function(iVolume) { - if (this.player) { - this.player.setVolume(iVolume); - } - }; - - /** - * Guess the mime-type of a video file, based on its filename/ extension. - * - * @param {String} path - * @type {String} - */ - this.$guessType = function(path) { - // make a best-guess, based on the extension of the src attribute (file name) - var ext = path.substr(path.lastIndexOf('.') + 1); - var type = ""; - switch (ext) { - case "mov": - type = "video/quicktime"; - break; - case "flv": - type = "video/flv"; - break; - case "asf": - case "asx": - case "avi": - case "wmv": - type = "video/wmv"; - break; - case "3gp" : - case "3gpp" : - case "3g2" : - case "3gpp2": - case "divx" : - case "mp4" : - case "mpg4" : - case "mpg" : - case "mpeg" : - case "mpe" : - case "ogg" : - case "vob" : - type = "video/vlc"; - break; - } - // mpeg video is better to be played by native players - if (ext == "mpg" || ext == "mpeg" || ext == "mpe") - type = jpf.isMac ? "video/quicktime" : "video/wmv"; - // default to VLC on *NIX machines - if (!jpf.isWin && !jpf.isMac && type == "video/wmv") - type = "video/vlc"; - - return type; - }; - - /** - * Find the correct video player type that will be able to playback the video - * file with a specific mime-type provided. - * - * @param {String} mimeType - * @type {String} - */ - this.$getPlayerType = function(mimeType) { - if (!mimeType) return null; - - var playerType = null; - - var aMimeTypes = mimeType.splitSafe(','); - if (aMimeTypes.length == 1) - aMimeTypes = aMimeTypes[0].splitSafe(';'); - for (var i = 0; i < aMimeTypes.length; i++) { - mimeType = aMimeTypes[i]; - - if (mimeType.indexOf('flv') > -1) - playerType = "TypeFlv"; - else if (mimeType.indexOf('quicktime') > -1) - playerType = "TypeQT"; - else if (mimeType.indexOf('wmv') > -1) - playerType = "TypeWmp"; - else if (mimeType.indexOf('silverlight') > -1) - playerType = "TypeSilverlight"; - else if (mimeType.indexOf('vlc') > -1) - playerType = "TypeVlc"; - - if (playerType == "TypeWmp") { - if (!jpf.isIE && typeof jpf.video.TypeVlc != "undefined" - && jpf.video.TypeVlc.isSupported()) - playerType = "TypeVlc"; - else if (jpf.isMac) - playerType = "TypeQT"; - } - - if (playerType && jpf.video[playerType] && - jpf.video[playerType].isSupported()) { - this.$lastMimeType = i; - return playerType; - } - } - - this.$lastMimeType = -1; - return null;//playerType; - }; - - /** - * Checks if a specified playerType is supported by JPF or not... - * - * @type {Boolean} - */ - this.$isSupported = function(sType) { - sType = sType || this.playerType; - return (jpf.video[sType] && jpf.video[sType].isSupported()); - }; - - /** - * Initialize and instantiate the video player provided by getPlayerType() - * - * @type {Object} - */ - this.$initPlayer = function() { - this.player = new jpf.video[this.playerType](this, this.oExt, { - src : this.src.splitSafe(",")[this.$lastMimeType] || this.src, - width : this.width, - height : this.height, - autoLoad : true, - autoPlay : this.autoplay, - showControls: this.controls, - volume : this.volume, - mimeType : this.type - }); - return this; - }; - - /** - * The 'init' event hook is called when the player control has been initialized; - * usually that means that the active control (flash, QT or WMP) has been loaded - * and is ready to load a file. - * - * @ignore - * @type {void} - */ - this.$initHook = function() { - this.loadMedia(); - }; - - /** - * The 'cuePoint' event hook is called when the player has set a cue point in - * the video file. - * - * @ignore - * @type {void} - */ - this.$cuePointHook = function() {}; //ignored - - /** - * The 'playheadUpdate' event hook is called when the position of the playhead - * that is currently active (or 'playing') is updated. - * This feature is currently handled by {@link element.video.method.$changeHook} - * - * @ignore - * @type {void} - */ - this.$playheadUpdateHook = function() {}; //ignored - - /** - * The 'error' event hook is called when an error occurs within the internals - * of the player control. - * - * @param {Object} e Event data, specific to this hook, containing player data. - * @type {void} - */ - this.$errorHook = function(e) { - jpf.console.error(e.error); - }; - - /** - * The 'progress' event hook is called when the progress of the loading sequence - * of an video file is updated. The control signals us on how many bytes are - * loaded and how many still remain. - * - * @param {Object} e Event data, specific to this hook, containing player data. - * @type {void} - */ - this.$progressHook = function(e) { - this.setProperty('bufferedBytes', {start: 0, end: e.bytesLoaded}); - this.setProperty('totalBytes', e.totalBytes); - var iDiff = Math.abs(e.bytesLoaded - e.totalBytes); - if (iDiff <= 20) - this.setProperty('readyState', jpf.Media.HAVE_ENOUGH_DATA); - }; - - /** - * The 'stateChange' event hook is called when the internal state of a control - * changes. The state of internal properties of an video control may be - * propagated through this function. - * - * @param {Object} e Event data, specific to this hook, containing player data. - * @type {void} - */ - this.$stateChangeHook = function(e) { - //loading, playing, seeking, paused, stopped, connectionError - if (e.state == "loading") - this.setProperty('networkState', this.networkState = jpf.Media.NETWORK_LOADING); - else if (e.state == "connectionError") - this.$propHandlers["readyState"].call(this, this.networkState = jpf.Media.HAVE_NOTHING); - else if (e.state == "playing" || e.state == "paused") { - if (e.state == "playing") - this.$readyHook({type: 'ready'}); - this.paused = Boolean(e.state == "paused"); - this.setProperty('paused', this.paused); - } - else if (e.state == "seeking") { - this.seeking = true; - this.setProperty('seeking', true); - } - }; - - /** - * The 'change' event hook is called when a) the volume level changes or - * b) when the playhead position changes. - * - * @param {Object} e Event data, specific to this hook, containing player data. - * @type {void} - */ - this.$changeHook = function(e) { - if (typeof e.volume != "undefined") { - this.volume = e.volume; - if (!this.muted) - this.setProperty("volume", this.volume); - } - else { - this.duration = this.player.getTotalTime(); - this.position = e.playheadTime / this.duration; - if (isNaN(this.position)) return; - this.setProperty('position', this.position); - this.currentTime = e.playheadTime; - this.setProperty('currentTime', this.currentTime); - } - }; - - /** - * The 'complete' event hook is called when a control has finished playing - * an video file completely, i.e. the progress is at 100%. - * - * @param {Object} e Event data, specific to this hook, containing player data. - * @type {void} - */ - this.$completeHook = function(e) { - this.paused = true; - this.setProperty('paused', true); - }; - - /** - * When a video player signals that is has initialized properly and is ready - * to play, this function sets all the flags and behaviors properly. - * - * @type {Object} - */ - this.$readyHook = function(e) { - this.setProperty('networkState', jpf.Media.NETWORK_LOADED); - this.setProperty('readyState', jpf.Media.HAVE_FUTURE_DATA); - this.setProperty('duration', this.player.getTotalTime()); - this.seeking = false; - this.seekable = true; - this.setProperty('seeking', false); - return this; - }; - - /** - * The 'metadata' event hook is called when a control receives metadata of an - * video file. - * - * @ignore - * @type {void} - */ - this.$metadataHook = function(e) { - this.oVideo.setProperty('readyState', jpf.Media.HAVE_METADATA); - }; - - /** - * Unsubscribe from all the events that we have subscribed to with - * startListening() - * - * @type {Object} - */ - this.stopListening = function() { - if (!this.player) return this; - - return this; - }; - - /** - * Build Main Skin - * - * @type {void} - */ - this.$draw = function(){ - this.oExt = this.$getExternal(); - }; - - /** - * Parse the block of JML that constructs the HTML5 compatible <VIDEO> tag - * for arguments like URL of the video, width, height, etc. - * - * @param {XMLRootElement} x - * @type {void} - */ - this.$loadJml = function(x){ - this.oInt = this.$getLayoutNode("main", "container", this.oExt); - - this.width = parseInt(this.width) || null; - this.height = parseInt(this.height) || null; - - if (this.setSource()) - this.$propHandlers["type"].call(this, this.type); - else - jpf.JmlParser.parseChildren(this.$jml, null, this); - }; - - this.$destroy = function(bRuntime) { - if (this.player && this.player.$destroy) - this.player.$destroy(); - delete this.player; - this.player = null; - - if (bRuntime) - this.oExt.innerHTML = ""; - }; -}).implement( - jpf.DataBinding, - jpf.Presentation, - jpf.Media -); - -jpf.video.TypeInterface = { - properties: ["src", "width", "height", "volume", "showControls", - "autoPlay", "totalTime", "mimeType"], - - /** - * Set and/or override the properties of this object to the values - * specified in the opions argument. - * - * @param {Object} options - * @type {Object} - */ - setOptions: function(options) { - if (options == null) return this; - // Create a hash of acceptable properties - var hash = this.properties; - for (var i = 0; i < hash.length; i++) { - var prop = hash[i]; - if (options[prop] == null) continue; - this[prop] = options[prop]; - } - return this; - }, - - /** - * Utility method; get an element from the browser's document object, by ID. - * - * @param {Object} id - * @type {HTMLDomElement} - */ - getElement: function(id) { - var elem; - - if (typeof id == "object") - return id; - if (jpf.isIE) - return window[id]; - else { - elem = document[id] ? document[id] : document.getElementById(id); - if (!elem) - elem = jpf.lookup(id); - return elem; - } - } -}; - - - -/*FILEHEAD(/var/lib/jpf/src/elements/toc.js)SIZE(-1077090856)TIME(1238933683)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * Element acting as the navigational instrument for any
- * element based on BaseTab. This element displays buttons
- * which can be used to navigate the different pages of for instance
- * a submitform or pages element. This element is page validation
- * aware and can display current page progress when connected to
- * a submitform.
- *
- * @constructor
- * @define toc
- * @addnode elements
- *
- * @inherits jpf.Presentation
- * @todo test if this element still works with the refactored basetab
- *
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.8
- */
-jpf.toc = jpf.component(jpf.NODE_VISIBLE, function(){
- this.editableParts = {"Page" : [["caption","@caption"]]};
-
- var _self = this;
-
- /**** Properties and Attributes ****/
-
- this.$supportedProperties.push("represent");
-
- /**
- * @attribute {String} represent the id of the element to display
- * navigation for.
- */
- this.$propHandlers["represent"] = function(value){
- setTimeout(function(){
- var jmlNode = _self.$represent = self[value];
-
- jmlNode.addEventListener("afterswitch", function(e){
- _self.$setActivePage(e.pageId);
- });
-
- if (jmlNode.$drawn) {
- _self.$createReflection();
- }
- else {
- jmlNode.$jmlLoaders.push(function(){
- toc.$createReflection();
- });
- }
- });
- }
-
- /**** Public methods ****/
-
- /**
- * Navigates to a page of the represented element.
- * @param {Number} nr the child number of the page to activate.
- */
- this.gotoPage = function(nr){
- if (this.disabled) return false;
-
- if (this.$represent.isValid && !this.$represent.testing) {
- var pages = this.$represent.getPages();
- var activepagenr = this.$represent.activepagenr;
- for (var i = activepagenr; i < nr; i++) {
- pages[i].oExt.style.position = "absolute"; //hack
- pages[i].oExt.style.top = "-10000px"; //hack
- pages[i].oExt.style.display = "block"; //hack
- var test = !this.$represent.isValid || this.$represent
- .isValid(i < activepagenr, i < activepagenr, pages[i]);//false, activepagenr == i, pages[i], true);
- pages[i].oExt.style.display = ""; //hack
- pages[i].oExt.style.position = ""; //hack
- pages[i].oExt.style.top = ""; //hack
- pages[i].oExt.style.left = ""; //hack
- pages[i].oExt.style.width = "1px";
- pages[i].oExt.style.width = "";
-
- if (!test)
- return this.$represent.set(i);
- }
- }
-
- if (this.$represent.showLoader)
- this.$represent.showLoader(true, nr);
-
- setTimeout(function(){
- _self.$represent.set(nr);
- }, 1);
- //setTimeout("jpf.lookup(" + this.$represent.uniqueId + ").set(" + nr + ");", 1);
- };
-
- /**** Private Methods ****/
-
- this.$setActivePage = function(active){
- if (this.disabled) return false;
-
- //Find previous known index and make sure it has known indexes after
- if (!this.pagelookup[active]) {
- var page, last, is_between;
- for (page in this.pagelookup) {
- if (page < active)
- last = page;
- if (page > active)
- is_between = true;
- }
- if (!last || !is_between) return; //exit if there are no known indexes
- active = last;
- }
-
- for (var isPast = true, i = 0; i < this.pages.length; i++) {
- if (this.pagelookup[active] == this.pages[i]) {
- this.$setStyleClass(this.pages[i], "present", ["future", "past"]);
- isPast = false;
- }
- else
- if (isPast)
- this.$setStyleClass(this.pages[i], "past", ["future", "present"]);
- else
- this.$setStyleClass(this.pages[i], "future", ["past", "present"]);
-
- if (i == this.pages.length-1)
- this.$setStyleClass(this.pages[i], "last");
- }
- };
-
- this.$createReflection = function(){
- var pages = this.$represent.getPages();
-
- for (var l = {}, p = [], i = 0; i < pages.length; i++) {
- this.$getNewContext("page");
- var oCaption = this.$getLayoutNode("page", "caption");
- var oPage = this.$getLayoutNode("page");
- this.$setStyleClass(oPage, "page" + i);
-
- oPage.setAttribute("onmouseover", 'jpf.lookup(' + this.uniqueId
- + ').$setStyleClass(this, "hover", null);');
- oPage.setAttribute("onmouseout", 'jpf.lookup(' + this.uniqueId
- + ').$setStyleClass(this, "", ["hover"]);');
-
- if(!pages[i].$jml.getAttribute("caption")){
- jpf.console.warn("Page element without caption found.");
- //continue;
- }
- else {
- jpf.xmldb.setNodeValue(oCaption,
- pages[i].$jml.getAttribute("caption") || "");
- }
-
- oPage.setAttribute("onmousedown", "setTimeout(function(){\
- jpf.lookup(" + this.uniqueId + ").gotoPage(" + i + ");\
- });");
- p.push(jpf.xmldb.htmlImport(oPage, this.oInt));
- l[i] = p[p.length - 1];
-
- this.$makeEditable("page", p[i], pages[i].$jml);
- }
-
- //xmldb.htmlImport(p, this.oInt);
- this.pages = p;
- this.pagelookup = l;
-
- this.$setActivePage(0);
-
- if (jpf.isGecko) {
- var tocNode = this;
- setTimeout(function(){
- tocNode.oExt.style.height = tocNode.oExt.offsetHeight + 1 + "px";
- tocNode.oExt.style.height = tocNode.oExt.offsetHeight - 1 + "px";
- }, 10);
- }
- };
-
- /**** Init ****/
-
- this.$draw = function(){
- //Build Main Skin
- this.oExt = this.$getExternal();
- this.oCaption = this.$getLayoutNode("main", "caption", this.oExt);
- this.oInt = this.$getLayoutNode("main", "container", this.oExt);
- };
-
- this.$loadJml = function(x){
- if (!this.represent)
- throw new Error(jpf.formatErrorString(1013, this,
- "Find representation",
- "Could not find representation for the Toc: '"
- + this.name + "'", x))
- };
-}).implement(
- jpf.Presentation
-);
- - -/*FILEHEAD(/var/lib/jpf/src/elements/toolbar.js)SIZE(-1077090856)TIME(1238944817)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-/**
- * Element displaying a bar containing buttons and other jml elements.
- * This element is usually positioned in the top of an application allowing
- * the user to choose from grouped buttons.
- * Example:
- * <code>
- * <j:toolbar>
- * <j:menubar> - * <j:button submenu="mnuFile">File</j:button> - * <j:button submenu="mnuEdit">Edit</j:button> - * </j:menubar> - * <j:bar> - * <j:button>Questions</j:button> - * <j:divider /> - * <j:button icon="icoEmail.gif">e-mail</j:button> - * <j:button id="btnTest" - * icon = "icoPhone.gif" - * caption = "Change Skin" />
- * <j:divider />
- * <j:progressbar value="jpf.offline.position" /> - * </j:bar> - * </j:toolbar>
- *
- * <j:menu id="mnuFile">
- * ... - * </j:menu> - * - * <j:menu id="mnuEdit">
- * ...
- * </j:menu> - * </code>
- *
- * @constructor
- * @define toolbar
- * @addnode elements
- * @allowchild bar, menubar
- *
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.4
- *
- * @inherits jpf.Presentation
- */
-
-jpf.toolbar = jpf.component(jpf.NODE_VISIBLE, function(){
- this.canHaveChildren = true;
- this.$focussable = false;
-
- /**** DOM Hooks ****/
-
-
- /**** Init ****/
-
- this.$draw = function(){
- //Build Main Skin
- this.oExt = this.$getExternal();
- this.oInt = this.$getLayoutNode("main", "container", this.oExt);
- };
-
- this.$loadJml = function(x){
- var bar, tagName, i, l, node, nodes = this.$jml.childNodes;
-
- //Let's not parse our children, when we've already have them
- if (!this.oInt && this.childNodes.length)
- return;
-
- //@todo Skin switching here...
-
- for (i = 0, l = nodes.length; i < l; i++) {
- node = nodes[i];
- if (node.nodeType != 1)
- continue;
-
- tagName = node[jpf.TAGNAME];
- if ("bar|menubar".indexOf(tagName) > -1) {
- bar = new jpf.bar(this.oInt, tagName);
- bar.skinName = this.skinName
- bar.loadJml(node, this);
-
- if (tagName == "menubar") {
- this.$setStyleClass(bar.oExt, "menubar");
-
- bar.$domHandlers["insert"].push(function(jmlNode){
- if (jmlNode.tagName != "button") {
- throw new Error(jpf.formatErrorStrin(0, this,
- "Appending a child",
- "A menubar can only contain j:button elements"));
- }
- });
- }
- }
- }
- };
-}).implement(jpf.Presentation);
-
- - -/*FILEHEAD(/var/lib/jpf/src/elements/presenter.js)SIZE(-1077090856)TIME(1225628613)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - -//info mouse wheel function is from http://adomas.org/javascript-mouse-wheel/ - - -/** - * Element displaying a skinnable rectangle which can contain other JML elements. - * - * @classDescription This class creates a new presenter - * @return {Presenter} Returns a new presenter - * @type {Presenter} - * @constructor - * @allowchild {elements}, {anyjml} - * @addnode elements:bar - * - * @author Ruben Daniels - * @version %I%, %G% - * @since 0.4 - */ - -jpf.presenter = jpf.component(jpf.NODE_VISIBLE, function(){ - - //var space = { x:1000000, w:-2000000, y:1000000, h:-2000000}; - var timer = null; - var _self = this; - var engine; - - this.drawSheets = function(){ - for(var i = 0;i<this.childNodes.length;i++){ - this.childNodes[i].drawSheet(); - } - } - - this.$draw = function(){ - //Build Main Skin - this.oExt = this.$getExternal(); - } - - - this.$loadJml = function(x){ - var oInt = this.$getLayoutNode("main", "container", this.oExt); - this.oInt = oInt;/* - ? jpf.JmlParser.replaceNode(oInt, this.oInt) - : jpf.JmlParser.parseChildren(x, oInt, this);*/ - //this.engine = jpf.chart.canvasDraw.init(this); - this.engine = (jpf.supportVML?jpf.draw.vml:jpf.draw.canvas).init(this); - - //var dt = new Date().getTime(); - for (var o, i = 0, j = 0; i < x.childNodes.length; i++){ - if (x.childNodes[i].nodeType != 1) - continue; - - if (x.childNodes[i][jpf.TAGNAME] == "sheet") { - o = new jpf.presenter.sheet(this.oExt, "sheet"); - o.parentNode = this; - o.engine = this.engine; - o.$loadJml(x.childNodes[i], this, j++); - this.childNodes.push(o); - } - } - //lert( (new Date()).getTime() - dt); - var ox, oy, lx, ly, bt, stack = [], interact = false; - iebt = [0,1,2,3,3], ffbt = [1,3,2,0,0]; - - this.oExt.onmousedown = function(e){ - if (!e) e = event; - if(e.button>4 || e.button<0)return; - bt = (_self.canvas)?ffbt[e.button]:iebt[e.button]; - if(!bt)return; - interact = true; - lx = e.clientX, ly = e.clientY; - ox = lx - _self.oExt.offsetLeft, oy = ly - _self.oExt.offsetTop; - // we need to check if our mousedown was in the axis, ifso send it a mousedown and keep it on our eventstack - for(var t, i = _self.childNodes.length-1;i>=0;i--){ - t = _self.childNodes[i]; - if( ox >= t.left && ox <= t.left+t.width && - oy >= t.top && oy <= t.top+t.height ){ - t.mouseDown(ox - t.left,oy - t.top,bt); - stack.push( t ); - } - } - } - - this.oExt.oncontextmenu = function(){ - return false; - } - - this.oExt.onmouseup = - function(e){ - if (!e) e = event; - interact = false; - var x = e.clientX - _self.oExt.offsetLeft, - y = e.clientY - _self.oExt.offsetTop; - for(var i = stack.length-1;i>=0;i--) - (t=stack[i]).mouseUp(x - t.left, y - t.top); - stack.length = 0; - } - - this.oExt.onmousemove = function(e){ - if (!interact) return; - if (!e) e = event; - var dx = (-lx + (lx=e.clientX)),dy = (-ly + (ly=e.clientY)); - for(var t, i = stack.length-1;i>=0;i--) - (t = stack[i]).mouseMove(dx,dy,bt,ox-t.left,oy-t.top); - } - - wheelEvent = function(e) { - if(!e) e = window.event; - - var d = e.wheelDelta? - (window.opera ?-1:1) * e.wheelDelta / 120 : - (e.detail ? -e.detail / 3 : 0); - - if(d){ - // lets find if we are over a graph - var x = e.clientX - _self.oExt.offsetLeft, - y = e.clientY - _self.oExt.offsetTop; - for(var t, i = 0;i<_self.childNodes.length;i++){ - t = _self.childNodes[i]; - if( x >= t.left && x <= t.left+t.width && - y >= t.top && y <= t.top+t.height ){ - t.mouseWheel(x - t.left,y - t.top,d); - } - } - } - if(event.preventDefault) event.preventDefault(); - event.returnValue = false; - } - if (this.canvas && this.oExt.addEventListener){ - this.oExt.addEventListener('DOMMouseScroll', wheelEvent, false); - } - this.oExt.onmousewheel = wheelEvent; - - // animation stuff for now - window.setInterval(function(){ - _self.drawLayers(); - //alert((new Date()).getTime()-dt); - },20); - } -}).implement(jpf.Presentation); - -jpf.presenter.sheet = jpf.subnode(jpf.NODE_HIDDEN, function(){ - this.$supportedProperties = [ - "left","top","width","height","type","viewport", - "zoom","zoomx", "zoomy","movex", "movey", - "orbitx", "orbity", "distance", - ]; - - this.$draw = 0; - this.style = {}; - var _self = this; - var timer; - - // 2D mouse interaction - this.zoomx = 1; - this.zoomy = 1; - this.movex = 0; - this.movey = 0; - // 3D mouse interaction - this.orbitx = -1.2; - this.orbity = -1.2; - this.distance = 4; - - // domains - this.x1 = -1; - this.y1 = -1; - this.x2 = 1; - this.y2 = 1; - this.t1 = 0; - this.t2 = 1; - this.animreset = 1; - - this.resetView = function(){ - if(!this.animreset){ - _self.setProperty("movex", 0 ); _self.setProperty("movey", 0 ); - _self.setProperty("zoomx", 1 ); _self.setProperty("zoomy", 1 ); - _self.setProperty("orbitx", 0 ); _self.setProperty("orbity", -1.2 ); - _self.setProperty("distance", 4 ); - } - var step = 0; - var iid = window.setInterval(function(){ - var s1 = 0.7, s2 = 1 - s1; - if( step++ > 20 ) window.clearInterval( iid ), iid = 0; - _self.setProperty("movex", !iid?0:s1*_self.movex ); - _self.setProperty("movey", !iid?0:s1*_self.movey ); - _self.setProperty("zoomx", !iid?1:s2+s1*_self.zoomx ); - _self.setProperty("zoomy", !iid?1:s2+s1*_self.zoomy ); - _self.setProperty("orbitx", !iid?-1.2:s2*-1.2+s1*_self.orbitx ); - _self.setProperty("orbity", !iid?-1.2:s2*-1.2+s1*_self.orbity ); - _self.setProperty("distance", !iid?4:s2*4+s1*_self.distance); - },20); - } - - this.mouseDown = function(x,y,bt){ - if(bt == 3) this.resetView(); - } - - this.mouseUp = function(x,y){ - } - - this.mouseMove = function(dx,dy,bt,ox,oy){ - // we need to - dx = dx / this.cwidth, dy = dy / this.cheight; - var zx = this.zoomx, zy = this.zoomy; -// document.title = dx+" "+this.movex+" "+this.zoomx; - if(bt == 1){ - if(ox<this.cleft)dx = 0; - if(oy>this.ctop+this.cheight)dy = 0; - this.setProperty("orbitx", this.orbitx - 2*dx ); - this.setProperty("orbity", this.orbity + 2*dy ); - this.setProperty("movex", this.movex + dx * this.zoomx ); - this.setProperty("movey", this.movey + dy * this.zoomy ); - }else if(bt==2){ - var tx = (ox - this.cleft)/this.cwidth, - ty = (oy - this.ctop)/this.cheight; - this.setProperty("distance", Math.min(Math.max( this.distance * - (1 - 4*dy), 3 ),100) ); - this.setProperty("zoomx", this.zoomx * (1 - 4*dx) ); - this.setProperty("zoomy", this.zoomy * (1 - 4*dy) ); - this.setProperty("movex", this.movex - (zx-this.zoomx)*tx ); - this.setProperty("movey", this.movey - (zy-this.zoomy)*ty ); - } - //this.drawAxis(); - } - - this.mouseWheel = function(x,y,d){ - var zx = this.zoomx, zy = this.zoomy, - tx = (x - this.cleft)/this.cwidth, - ty = (y - this.ctop)/this.cheight; - - this.setProperty("distance", Math.min(Math.max( this.distance * - (1 - 0.1*d), 3 ),100) ); - this.setProperty("zoomx", this.zoomx * (1 - 0.1*d) ); - this.setProperty("zoomy", this.zoomy * (1 - 0.1*d) ); - this.setProperty("movex", this.movex - (zx-this.zoomx)*tx ); - this.setProperty("movey", this.movey - (zy-this.zoomy)*ty ); - } - - this.handlePropSet = function(prop, value, force) { - switch(prop){ - case "top": - case "height": - case "left": - case "width": - if (!timer) { - timer = setTimeout(function(){ - _self.resize(); - timer = null; - }); - } - break; - } - this[prop] = value; - } - - this.resize = function(){ - //this.width this.left - } - - this.drawSheet = function () { - var p = this, - l = this, - x1 = l.x1, y1 = l.y1, - x2 = l.x2, y2 = l.y2, - w = x2 - x1, h = y2 - y1, tx ,ty; - - if( l.is3d ) { - // lets put in the orbit and distance - l.rx = p.orbity, l.ry = 0, l.rz = p.orbitx; - l.tx = 0, l.ty = 0, l.tz = -p.distance; - } else { - // lets calculate the new x1/y1 from our zoom and move - tx = p.movex * -w, ty = p.movey * -h; - x1 = x1 + tx, x2 = x1 + w*p.zoomx; - y1 = y1 + ty, y2 = y1 + h*p.zoomy; - } - l.vx1 = x1, l.vy1 = y1, l.vx2 = x2, l.vy2 = y2; - - //var dt=(new Date()).getTime(); - //for(var j = 0;j<100;j++) - l.griddraw( l, l ); - //document.title = ((new Date()).getTime()-dt)/100; - - for(var i = 0, d = this.childNodes, len = d.length, n;i<len;){ - (n = d[i++]).$draw(n, l); - } - } - - this.$loadJml = function(x, obj, order){ - this.$jml = x; - - if (x.getAttribute("id")) - jpf.setReference(x.getAttribute("id"), this); - - // just stuff attributes in properties - for (var attr = x.attributes, i = attr.length-1, a; i>=0; i--){ - a = attr[i]; this[a.nodeName] = a.nodeValue; - } - - if(order==0)this.firstlayer = 1; - // overload /joinparent style string - this.stylestr = (this.parentNode.style || "")+" "+ this.style; - - // coordinates scaled to parent for now - this.left = (this.left || 0) * this.parentNode.oExt.offsetWidth; - this.top = (this.top || 0) * this.parentNode.oExt.offsetHeight; - this.width = (this.width || 1) * (this.parentNode.oExt.offsetWidth); - this.height = (this.height || 1) * (this.parentNode.oExt.offsetHeight); - // our grid is styled with margins, we need to setup our childlayers to be clipped to it - this.type = this.type || "2D"; - this.is3d = this.type.match( "3D" ); - - this.engine.initLayer(this, this); - this.style = jpf.draw.parseStyle( (a=jpf.visualize.defaultstyles), - a['grid'+this.type], this.stylestr ); - - this.cleft = this.left+(this.style.margin? - this.style.margin.left:0); - this.ctop = this.top+(this.style.margin? - this.style.margin.top:0); - this.cwidth = this.width - (this.style.margin? - (this.style.margin.right+this.style.margin.left):0); - this.cheight = this.height - (this.style.margin? - (this.style.margin.bottom+this.style.margin.top):0); - // initialize drawing function - var dt = (new Date()).getTime(); - this.griddraw = jpf.visualize['grid'+this.type]( this, - this.engine, this.style ); - - // init graph layers with proper drawing viewport - // after each draw, we should have the lines x and y positions in an array ready to be drawn in text, or looked up to text. - - for (var o, i = 0; i < x.childNodes.length; i++){ - if (x.childNodes[i].nodeType != 1) - continue; - if (x.childNodes[i][jpf.TAGNAME] == "layer") { - o = new jpf.presenter.layer(this.oExt, "layer"); - o.parentNode = this; - o.engine = this.engine; - // add some margins for the childnodes - o.left = this.cleft, o.top = this.ctop, - o.width = this.cwidth,o.height = this.cheight; - o.$loadJml(x.childNodes[i]); - // expand our viewport - if( o.x1 !== undefined && o.x1 < this.x1 ) this.x1 = o.x1; - if( o.y1 !== undefined && o.y1 < this.y1 ) this.y1 = o.y1; - if( o.x2 !== undefined && o.x2 > this.x2 ) this.x2 = o.x2; - if( o.y2 !== undefined && o.y2 > this.y2 ) this.y2 = o.y2; - this.childNodes.push(o); - } - } - // lets calculate the viewport, if none given - if(this.viewport || this.x2<this.x1){ - this.viewport = this.viewport || "-1,-1,1,1"; - i = this.viewport.split(","); - this.x1 = parseFloat(i[0]), this.y1 = parseFloat(i[1]), - this.x2 = parseFloat(i[2]), this.y2 = parseFloat(i[3]); - } - } -}); - -jpf.presenter.layer = jpf.subnode(jpf.NODE_HIDDEN, function(){ - - this.$supportedProperties = ["type","series","formula"]; - - this.data = 0; - this.style = {}; - - this.handlePropSet = function(prop, value, force) { - this[prop] = value; - } - - this.$loadJml = function(x,obj){ - this.$jml = x; - - if (x.getAttribute("id")) - jpf.setReference(x.getAttribute("id"), this); - - this.engine = this.parentNode.engine; - this.perspective = this.parentNode.perspective; - - // just stuff attributes in properties - for (var attr = x.attributes, i = attr.length-1, a; i>=0; i--){ - a = attr[i]; this[ a.nodeName ] = a.nodeValue; - } - - // overload /joinparent style string - this.stylestr = (this.parentNode.parentNode.style || "")+" "+ this.style; - // check the sourcetype - this.source='mathX'; - this.type += this.parentNode.type; - - this.engine.initLayer(this, this); - this.style = jpf.draw.parseStyle((a=jpf.visualize.defaultstyles), - a[this.type], this.stylestr ); - this.datasource = jpf.visualize.datasource[this.source]( this ); - this.$draw = jpf.visualize[this.type](this, - this.engine, this.datasource); - } -}); - - - - - -/*FILEHEAD(/var/lib/jpf/src/elements/jslt.js)SIZE(-1077090856)TIME(1238944817)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-/**
- * Element displaying the contents of a jslt transformation on
- * the bound dataset. For more information on jslt see
- * {@link object.jsltimplementation}.
- * Example:
- * <code>
- * <j:jslt model="mdlChat"><![CDATA[
- * [foreach('message'){]
- * <strong>[%$'@from'.split("@")[0]] says:</strong> <br />
- * {text()}<br />
- * [}]
- * ]]></j:jslt>
- * </code>
- *
- * @constructor
- * @allowchild [cdata]
- * @addnode elements:jslt
- *
- * @inherits jpf.DataBinding
- *
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.9
- */
-jpf.jslt = jpf.component(jpf.NODE_VISIBLE, function(){
- this.$hasStateMessages = true;
- this.mainBind = "contents";
- this.focussable = false;
-
- this.parse = function(code){
- this.setProperty("value", code);
- };
-
- /**** Focus ****/
- this.$focus = function(){
- if (!this.oExt)
- return;
-
- jpf.setStyleClass(this.oExt, this.baseCSSname + "Focus");
- };
-
- this.$blur = function(){
- if (!this.oExt)
- return;
-
- jpf.setStyleClass(this.oExt, "", [this.baseCSSname + "Focus"]);
- };
-
- this.getValue = function(){
- return this.value;
- }
-
- /**
- * @todo please test this.
- */
- this.$clear = function(a, b){
- this.setProperty("value", "");
- };
-
- var lastMsg;
- this.$setClearMessage = this.$updateClearMessage = function(msg){
- jpf.setStyleClass(this.oExt, this.baseCSSname + "Empty");
-
- if (msg) {
- this.oInt.innerHTML = msg;
- lastMsg = this.oInt.innerHTML;
- }
- };
-
- this.$removeClearMessage = function(){
- jpf.setStyleClass(this.oExt, "", [this.baseCSSname + "Empty"]);
-
- if (this.oInt.innerHTML == lastMsg)
- this.oInt.innerHTML = ""; //clear if no empty message is supported
- };
-
- this.$booleanProperties["selectable"] = true;
- this.$supportedProperties.push("value");
- this.$propHandlers["value"] = function(value){
- if (value)
- this.$removeClearMessage();
-
- if (this.createJml) {
- if (typeof code == "string")
- code = jpf.xmldb.getXml(code);
- // To really make it dynamic, the objects created should be
- // deconstructed and the xml should be attached and detached
- // of the this.$jml xml.
- jpf.JmlParser.parseChildren(value, this.oInt, this);
- if (jpf.JmlParser.inited)
- jpf.JmlParser.parseLastPass();
- }
- else {
- this.oInt.innerHTML = value;
- }
- };
-
- this.$propHandlers["selectable"] = function(value){
- this.oExt.onselectstart = value
- ? function(){
- event.cancelBubble = true;
- }
- : null;
- };
-
- this.$draw = function(){
- //Build Main Skin
- this.oInt = this.oExt = jpf.isParsing && jpf.xmldb.isOnlyChild(this.$jml)
- ? this.pHtmlNode
- : this.pHtmlNode.appendChild(document.createElement("div"));
- this.oExt.host = this;
-
- if (this.$jml.getAttribute("class"))
- this.oExt.className = this.$jml.getAttribute("class");
- };
-
- this.$loadJml = function(x){
- this.createJml = jpf.isTrue(x.getAttribute("jml"));
-
- //Events
- var a, i, attr = x.attributes;
- for (i = 0; i < attr.length; i++) {
- a = attr[i];
- if (a.nodeName.indexOf("on") == 0)
- this.addEventListener(a.nodeName, new Function(a.nodeValue));
- }
-
- if (x.firstChild) {
- var bind = x.getAttribute("ref") || ".";
- x.removeAttribute("ref");
- var strBind = "<smartbinding>\
- <bindings>\
- <value select='" + bind + "'>\
- <![CDATA[" + x.firstChild.nodeValue + "]]>\
- </value>\
- </bindings>\
- </smartbinding>";
-
- jpf.JmlParser.addToSbStack(this.uniqueId,
- new jpf.smartbinding(null, jpf.xmldb.getXml(strBind)));
- }
- };
-}).implement(
- jpf.DataBinding
-);
-
- - -/*FILEHEAD(/var/lib/jpf/src/elements/container.js)SIZE(-1077090856)TIME(1238933683)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -/** - * Element containing other elements that are hidden by default. - * - * @constructor - * @allowchild {elements}, {anyjml} - * @define container - * @addnode elements - * - * @author Ruben Daniels - * @version %I%, %G% - * @since 0.4 - * - * @inherits jpf.Presentation - * @inherits jpf.DelayedRender - * @inherits jpf.Validation - */ -jpf.container = jpf.component(jpf.NODE_VISIBLE, function(pHtmlNode){ - this.canHaveChildren = true; - this.$focussable = false; - - this.$show = function(){ - this.$render(); - } - - this.$draw = function(){ - //Build Main Skin - this.oExt = this.$getExternal(); - - this.setProperty("visible", false); - } - - this.$loadJml = function(x){ - var oInt = this.$getLayoutNode("main", "container", this.oExt) - || this.oExt; - - this.oInt = this.oInt - ? jpf.JmlParser.replaceNode(oInt, this.oInt) - : jpf.JmlParser.parseChildren(this.$jml, oInt, this, true); - - this.hide(); - } -}).implement( - jpf.DelayedRender, - jpf.Validation, - jpf.Presentation -); - - -/*FILEHEAD(/var/lib/jpf/src/elements/radiobutton.js)SIZE(-1077090856)TIME(1239027647)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - -/** - * @constructor - * @private - * - * @inherits jpf.DataBinding - * @inherits jpf.Validation - * @inherits jpf.XForms - */ -jpf.radiogroup = jpf.component(jpf.NODE_HIDDEN, function(){ - this.radiobuttons = []; - this.visible = true; - - this.$supportedProperties.push("value", "visible", "zindex", "disabled"); - this.$propHandlers["value"] = function(value){ - for (var i = 0; i < this.radiobuttons.length; i++) { - if (this.radiobuttons[i].value == value) - return this.setCurrent(this.radiobuttons[i]); - } - }; - - this.$propHandlers["zindex"] = function(value){ - for (var i = 0; i < this.radiobuttons.length; i++) { - this.radiobuttons[i].setZIndex(value); - } - }; - - this.$propHandlers["visible"] = function(value){ - if (value) { - for (var i = 0; i < this.radiobuttons.length; i++) { - this.radiobuttons[i].show(); - } - } - else { - for (var i = 0; i < this.radiobuttons.length; i++) { - this.radiobuttons[i].hide(); - } - }; - } - - this.$propHandlers["disabled"] = function(value){ - this.disabled = value; - - if (value) { - for (var i = 0; i < this.radiobuttons.length; i++) { - this.radiobuttons[i].disable(); - } - } - else { - for (var i = 0; i < this.radiobuttons.length; i++) { - this.radiobuttons[i].enable(); - } - } - } - - /** - * @private - */ - this.addRadio = function(oRB){ - var id = this.radiobuttons.push(oRB) - 1; - if (!this.visible) { - oRB.hide(); - //if(oRB.tNode) - //oRB.tNode.style.display = "none"; - } - - if (!oRB.value) - oRB.value = String(id); - - if (this.value && oRB.value == this.value) - this.setCurrent(oRB); - }; - - /** - * @private - */ - this.removeRadio = function(oRB){ - this.radiobuttons.remove(oRB); - } - - /** - * @copy Widget#setValue - */ - this.setValue = function(value){ - for (var i = 0; i < this.radiobuttons.length; i++) { - if (this.radiobuttons[i].value == value) { - var oRB = this.radiobuttons[i]; - if (this.current && this.current != oRB) - this.current.$uncheck(); - oRB.check(true); - this.current = oRB; - break; - } - } - - return this.setProperty("value", value); - //return false; - }; - - /** - * @private - */ - this.setCurrent = function(oRB){ - if (this.current && this.current != oRB) - this.current.$uncheck(); - this.value = oRB.value; - oRB.check(true); - this.current = oRB; - }; - - /** - * @copy Widget#getValue - */ - this.getValue = function(){ - return this.current ? this.current.value : ""; - }; -}).implement( - jpf.DataBinding - ,jpf.Validation -); - -/** - * Element displaying a two state button which is one of a grouped set. - * Only one of these buttons in the set can be checked at the same time. - * Example: - * <code> - * <j:frame title="Options"> - * <j:radiobutton>Option 1</j:radiobutton> - * <j:radiobutton>Option 2</j:radiobutton> - * <j:radiobutton>Option 3</j:radiobutton> - * <j:radiobutton>Option 4</j:radiobutton> - * </j:frame> - * </code> - * Example: - * This example shows radio buttons with an explicit group set: - * <code> - * <j:label>Options</j:label> - * <j:radiobutton group="g1">Option 1</j:radiobutton> - * <j:radiobutton group="g1">Option 2</j:radiobutton> - * - * <j:label>Choices</j:label> - * <j:radiobutton group="g2">Choice 1</j:radiobutton> - * <j:radiobutton group="g2">Choice 2</j:radiobutton> - * </code> - * - * @constructor - * @define radiobutton - * @allowchild {smartbinding} - * @addnode elements - * - * @inherits jpf.Presentation - * - * @author Ruben Daniels - * @version %I%, %G% - * @since 0.4 - * - * @binding value Determines the way the value for the element is retrieved - * from the bound data. - * Example: - * Sets the selection based on data loaded into this component. - * <code> - * <j:radiobutton group="g2" bindings="bndExample" value="1">Choice 1</j:radiobutton> - * <j:radiobutton group="g2" value="2">Choice 2</j:radiobutton> - * - * <j:bindings id="bndExample"> - * <j:value select="@value" /> - * </j:bindings> - * </code> - * Example: - * A shorter way to write this is: - * <code> - * <j:radiobutton group="g2" ref="@value" value="1">Choice 1</j:radiobutton> - * <j:radiobutton group="g2" value="2">Choice 2</j:radiobutton> - * </code> - * - * @event click Fires when the user presses a mousebutton while over this element and then let's the mousebutton go. - * @see baseclass.jmlnode.event.afterchange - */ -jpf.radiobutton = jpf.component(jpf.NODE_VISIBLE, function(){ - this.editableParts = { - "main": [["label", "text()"]] - }; - - this.$focussable = true; // This object can get the focus - var _self = this; - - /**** Properties and Attributes ****/ - - this.$booleanProperties["checked"] = true; - this.$supportedProperties.push("value", "background", "group", - "label", "checked", "tooltip", "icon"); - - /** - * @attribute {String} group the name of the group to which this radio - * button belongs. Only one item in the group can be checked at the same - * time. When no group is specified the parent container functions as the - * group; only one radiobutton within that parent can be checked. - */ - this.$propHandlers["group"] = function(value){ - if (this.radiogroup) - this.radiogroup.removeRadio(this); - - this.radiogroup = jpf.nameserver.get("radiogroup", value); - if (!this.radiogroup) { - var rg = new jpf.radiogroup(this.pHtmlNode, "radiogroup"); - - rg.errBox = this.errBox; - rg.parentNode = this.parentNode; //is this one needed? - - jpf.nameserver.register("radiogroup", value, rg); - jpf.setReference(value, rg); - - //x = oRB.$jml; - //rg.oExt = oRB.oExt; - rg.$jml = this.$jml; - rg.loadJml(this.$jml); - - this.radiogroup = rg; - } - - if (this.oInput) { - this.oInput.setAttribute("name", this.group - || "radio" + this.radiogroup.uniqueId); - } - - if (!this.value && this.$jml) - this.value = this.$jml.getAttribute("value"); - - this.radiogroup.addRadio(this); - - if (this.checked) - this.radiogroup.setValue(this.value); - }; - - /** - * @attribute {String} tooltip the tooltip of this radio button. - */ - this.$propHandlers["tooltip"] = function(value){ - this.oExt.setAttribute("title", value); - }; - - /** - * @attribute {String} icon the icon for this radiobutton - */ - this.$propHandlers["icon"] = function(value){ - if (!this.oIcon) - return jpf.console.warn("No icon defined in the Button skin", "button"); - - if (value) - this.$setStyleClass(this.oExt, this.baseCSSname + "Icon"); - else - this.$setStyleClass(this.oExt, "", [this.baseCSSname + "Icon"]); - - jpf.skins.setIcon(this.oIcon, value, this.iconPath); - }; - - /** - * @attribute {String} label the label for this radiobutton - */ - this.$propHandlers["label"] = function(value){ - if (value) - this.$setStyleClass(this.oExt, "", [this.baseCSSname + "Empty"]); - else - this.$setStyleClass(this.oExt, this.baseCSSname + "Empty"); - - if (this.oLabel) - this.oLabel.innerHTML = value; - }; - - /** - * @attribute {String} checked wether this radiobutton is the checked one in the group it belongs to. - */ - this.$propHandlers["checked"] = function(value){ - if (!this.radiogroup) - return; - - if (value) - this.radiogroup.setValue(this.value); - else { - //uncheck... - } - }; - - /** - * @copy basebutton#background - */ - this.$propHandlers["background"] = function(value){ - var oNode = this.$getLayoutNode("main", "background", this.oExt); - if (value) { - var b = value.split("|"); - this.$background = b.concat(["vertical", 2, 16].slice(b.length - 1)); - - oNode.style.backgroundImage = "url(" + this.mediaPath + b[0] + ")"; - oNode.style.backgroundRepeat = "no-repeat"; - } - else { - oNode.style.backgroundImage = ""; - oNode.style.backgroundRepeat = ""; - this.$background = null; - } - } - - /**** Public methods ****/ - - /** - * @copy Widget#setValue - */ - this.setValue = function(value){ - this.setProperty("value", value); - }; - - /** - * @copy Widget#getValue - */ - this.getValue = function(){ - return this.value; - }; - - /** - * @copy validation#setError - */ - this.setError = function(value){ - this.$setStyleClass(this.oExt, this.baseCSSname + "Error"); - }; - - /** - * @copy validation#clearError - */ - this.clearError = function(value){ - this.$setStyleClass(this.oExt, "", [this.baseCSSname + "Error"]); - }; - - /** - * @copy checkbox#check - */ - this.check = function(visually){ - if (visually) { - this.$setStyleClass(this.oExt, this.baseCSSname + "Checked"); - this.checked = true; - if (this.oInput) - this.oInput.checked = true; - this.doBgSwitch(2); - } - else - this.radiogroup.change(this.value); - }; - - this.$uncheck = function(){ - this.$setStyleClass(this.oExt, "", [this.baseCSSname + "Checked"]); - this.checked = false; - if (this.oInput) - this.oInput.checked = false; - this.doBgSwitch(1); - }; - - /**** Private methods ****/ - - this.$enable = function(){ - if (this.oInput) - this.oInput.disabled = false; - - this.oExt.onclick = function(e){ - if (!e) e = event; - if ((e.srcElement || e.target) == this) - return; - - _self.dispatchEvent("click", { - htmlEvent: e - }); - _self.radiogroup.change(_self.value); - } - - this.oExt.onmousedown = function(e){ - if (!e) e = event; - if ((e.srcElement || e.target) == this) - return; - - jpf.setStyleClass(this, _self.baseCSSname + "Down"); - } - - this.oExt.onmouseover = function(e){ - if (!e) e = event; - if ((e.srcElement || e.target) == this) - return; - - jpf.setStyleClass(this, _self.baseCSSname + "Over"); - } - - this.oExt.onmouseout = - this.oExt.onmouseup = function(){ - jpf.setStyleClass(this, "", [_self.baseCSSname + "Down", _self.baseCSSname + "Over"]); - } - }; - - this.$disable = function(){ - if (this.oInput) - this.oInput.disabled = true; - this.oExt.onclick = null - this.oExt.onmousedown = null - }; - - /** - * @private - */ - this.doBgSwitch = function(nr){ - if (this.bgswitch && (this.bgoptions[1] >= nr || nr == 4)) { - if (nr == 4) - nr = this.bgoptions[1] + 1; - - var strBG = this.bgoptions[0] == "vertical" - ? "0 -" + (parseInt(this.bgoptions[2]) * (nr - 1)) + "px" - : "-" + (parseInt(this.bgoptions[2]) * (nr - 1)) + "px 0"; - - this.$getLayoutNode("main", "background", this.oExt) - .style.backgroundPosition = strBG; - } - }; - - this.$focus = function(){ - if (!this.oExt) - return; - if (this.oInput && this.oInput.disabled) - return false; - - this.$setStyleClass(this.oExt, this.baseCSSname + "Focus"); - }; - - this.$blur = function(){ - if (!this.oExt) - return; - this.$setStyleClass(this.oExt, "", [this.baseCSSname + "Focus"]); - }; - - /**** Keyboard support ****/ - - this.addEventListener("keydown", function(e){ - var key = e.keyCode; - - if (key == 13 || key == 32) { - //this.check(); - //this.radiogroup.current = this; - this.radiogroup.change(this.value); - return false; - } - //Up - else if (key == 38) { - var node = this; - while (node && node.previousSibling) { - node = node.previousSibling; - if (node.tagName == "radiobutton" && !node.disabled - && node.radiogroup == this.radiogroup) { - node.check(); - node.focus(); - return; - } - } - } - //Down - else if (key == 40) { - var node = this; - while (node && node.nextSibling) { - node = node.nextSibling; - if (node.tagName == "radiobutton" && !node.disabled - && node.radiogroup == this.radiogroup) { - node.check(); - node.focus(); - return; - } - } - } - }, true); - - /**** Init ****/ - - this.$draw = function(){ - //Build Main Skin - this.oExt = this.$getExternal(); - this.oInput = this.$getLayoutNode("main", "input", this.oExt); - this.oLabel = this.$getLayoutNode("main", "label", this.oExt); - this.oIcon = this.$getLayoutNode("main", "icon", this.oExt); - - this.$makeEditable("main", this.oExt, this.$jml); - - this.enable(); - }; - - this.$loadJml = function(x){ - if (x.firstChild) { - var content = x.innerHTML; - if (!content) { - content = (x.xml || x.serialize()) - .replace(/^<[^>]*>/, "") - .replace(/<\/\s*[^>]*>$/, ""); - } - - this.$handlePropSet("label", content); - } - - if (!this.radiogroup) { - this.$propHandlers["group"].call(this, - "radiogroup" + this.parentNode.uniqueId); - } - - if (this.checked && !this.radiogroup.value) - this.$propHandlers["checked"].call(this, this.checked); - }; -}).implement( - jpf.Presentation -); - - - -/*FILEHEAD(/var/lib/jpf/src/elements/editor.js)SIZE(-1077090856)TIME(1239018216)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - -/** - * Element displaying a Rich Text Editor, like M$ Office Word in a browser window. Even - * though this Editor does not offer the same amount of features as Word, we did try to - * make it behave that way, simply because it is considered to be the market leader among - * word-processors. - * Example: - * <code> - * <j:editor - * id="myEditor" - * left="100" - * width="50%" - * height="90%-10"> - * Default value... - * </j:editor> - * </code> - * - * @constructor - * @addnode elements:editor - * - * @author Mike de Boer - * @version %I%, %G% - * @since 1.0 - * - * @inherits jpf.Validation - * @inherits jpf.XForms - * @inherits jpf.DataBinding - * @inherits jpf.Presentation - * - * @binding value Determines the way the value for the element is retrieved - * from the bound data. - * Example: - * Sets the text based on data loaded into this component. - * <code> - * <j:editor> - * <j:bindings> - * <j:value select="body/text()" /> - * </j:bindings> - * </j:editor> - * </code> - * Example: - * A shorter way to write this is: - * <code> - * <j:colorpicker ref="body/text()" /> - * </code> - */ -jpf.editor = jpf.component(jpf.NODE_VISIBLE, function() { - var inited, complete, oButtons = {}; - - /**** Default Properties ****/ - - var commandQueue = []; - var _self = this; - - this.value = ""; - this.$value = ""; - this.state = jpf.editor.ON; - this.$buttons = ['Bold', 'Italic', 'Underline']; - this.$plugins = ['pasteword', 'tablewizard']; - this.$nativeCommands = ['bold', 'italic', 'underline', 'strikethrough', - 'justifyleft', 'justifycenter', 'justifyright', - 'justifyfull', 'removeformat', 'cut', 'copy', - 'paste', 'outdent', 'indent', 'undo', 'redo']; - this.$classToolbar = 'editor_Toolbar'; - this.language = 'en_GB';//'nl_NL'; - - this.oDoc = this.oWin = null; - - /**** Properties and Attributes ****/ - - this.isContentEditable = true; - this.output = 'text'; //can be 'text' or 'dom', if you want to retrieve an object. - - this.$booleanProperties["realtime"] = true; - this.$booleanProperties["imagehandles"] = true; - this.$booleanProperties["tablehandles"] = true; - this.$supportedProperties.push("value", "realtime", "imagehandles", - "tablehandles", "plugins", "output", "state", "language"); - - this.$propHandlers["value"] = function(html){ - if (!inited || !complete) - return; - - if (typeof html != "string")// || html == "" - html = "";//jpf.isIE ? "<br />" : - - // If the HTML string is the same as the contents of the iframe document, - // don't do anything... - if (this.$value.replace(/\r/g, "") == html) - return; - - this.$value = html; - - html = html.replace(/<p[^>]*>/gi, "").replace(/<\/p>/gi, - "<br _jpf_marker='1' /><br _jpf_marker='1' />"); - - html = this.prepareHtml(html); - - if (this.plugins.isActive('code')) { - this.plugins.get('code').update(this, html); - } - else { - this.oDoc.body.innerHTML = html; - - if (jpf.isGecko) { - var oNode, oParent = this.oDoc.body; - while (oParent.childNodes.length) { - oNode = oParent.firstChild; - if (oNode.nodeType == 1) { - if (oNode.nodeName == "BR" - && oNode.getAttribute('_moz_editor_bogus_node') == "TRUE") { - this.selection.selectNode(oNode); - this.selection.remove(); - this.selection.collapse(false); - break; - } - } - oParent = oNode; - } - } - else if (jpf.isSafari) { - this.oDoc.designMode = "on"; - } - else if (jpf.isIE) { - // yes, we fix hyperlinks...%&$#*@*! - var aLinks = this.oDoc.getElementsByTagName('a'); - for (var i = 0, j = aLinks.length; i < j; i++) { - if (aLinks[i].getAttribute('_jpf_href')) - aLinks[i].href = aLinks[i].getAttribute('_jpf_href') - } - } - } - - this.dispatchEvent('sethtml', {editor: this}); - - //this.$visualFocus(true); - }; - - this.$propHandlers["output"] = function(value){ - //@todo Update XML - }; - - this.$propHandlers["state"] = function(value){ - this.state = parseInt(value); // make sure it's an int - // the state has changed, update the button look/ feel - setTimeout(function() { - _self.notifyAll(value); - if (_self.plugins.isActive('code')) - _self.notify('code', jpf.editor.SELECTED); - }); - }; - - this.$propHandlers["plugins"] = function(value){ - this.$plugins = value && value.splitSafe(value) || null; - }; - - /** - * @attribute {Boolean} realtime whether the value of the bound data is - * updated as the user types it, or only when this element looses focus or - * the user presses enter. - */ - this.$propHandlers["realtime"] = function(value){ - this.realtime = typeof value == "boolean" - ? value - : jpf.xmldb.getInheritedAttribute(this.$jml, "realtime") || false; - }; - - this.$propHandlers["language"] = function(value){ - // @todo implement realtime language switching - }; - - /** - * Important function; tells the right <i>iframe</i> element that it may be - * edited by the user. - * - * @type void - */ - this.makeEditable = function() { - var justinited = false; - if (!inited) { - this.$addListeners(); - inited = justinited = true; - } - if (jpf.isIE) { - setTimeout(function() { - _self.oDoc.body.contentEditable = true; - }); - } - else { - try { - this.oDoc.designMode = 'on'; - if (jpf.isGecko) { - // Tell Gecko (Firefox 1.5+) to enable or not live resizing of objects - this.oDoc.execCommand('enableObjectResizing', false, this.imagehandles); - // Disable the standard table editing features of Firefox. - this.oDoc.execCommand('enableInlineTableEditing', false, this.tablehandles); - } - } - catch (e) {}; - } - if (justinited) { - //this.$propHandlers["value"].call(this, ""); - this.dispatchEvent('complete', {editor: this}); - complete = true; - } - }; - - /** - * Returns the viewport of the Editor window. - * - * @return {Object} Viewport object with fields x, y, w and h. - * @type {Object} - */ - this.getViewPort = function() { - var doc = (!this.oWin.document.compatMode - || this.oWin.document.compatMode == 'CSS1Compat') - ? this.oWin.document.html || this.oWin.document.documentElement //documentElement for an iframe - : this.oWin.document.body; - - // Returns viewport size excluding scrollbars - return { - x : this.oWin.pageXOffset || doc.scrollLeft, - y : this.oWin.pageYOffset || doc.scrollTop, - width : this.oWin.innerWidth || doc.clientWidth, - height: this.oWin.innerHeight || doc.clientHeight - }; - }; - - /** - * API; get the (X)HTML that's inside the Editor at any given time - * - * @param {String} output This may be left empty or set to 'dom' or 'text' - * @type {mixed} - */ - this.getXHTML = function(output) { - if (!output) - output = this.output; - if (output == "text") - return this.oDoc.body.innerHTML; - else - return this.oDoc.body; - }; - - /** - * API; processes the current state of the editor's content and outputs the result that - * can be used inside any other content or stored elsewhere. - * - * @return The string of (X)HTML that is inside the editor. - * @type {String} - */ - this.getValue = function(bStrict) { - var xhtml = (this.$value = this.exportHtml(this.getXHTML('text'), bStrict)); - if (this.output == "dom") { //@todo might need a bit more love... - var dom = jpf.getXml('<jpf_cool>' + xhtml + '</jpf_cool>'), - fragment = document.createDocumentFragment(); - for (var i = 0, j = dom.childNodes.length; i < j; i++) { - try { - fragment.appendChild(dom.childNodes[i]); - } - catch (ex) {} - } - - return fragment; - } - - return xhtml; - }; - - /** - * API; replace the (X)HTML that's inside the Editor with something else - * - * @param {String} html - * @type {void} - */ - this.setHTML = - this.setValue = function(value){ - return this.setProperty("value", value); - }; - - /** - * Invoked by the Databinding layer when a model is reset/ cleared. - * - * @type {void} - */ - this.$clear = function(nomsg) { - if (!nomsg) { - this.value = ""; - return this.$propHandlers["value"].call(this, ""); - } - }; - - /** - * API; insert any given text (or HTML) at cursor position into the Editor - * - * @param {String} html - * @param {Boolean} bNoParse Prevents parsing the HTML, which might alter the string - * @param {Boolean} bNoFocus Prevents setting the focus back to the editor area - * @type {void} - */ - this.insertHTML = function(html, bNoParse, bNoFocus) { - if (inited && complete) { - if (!bNoFocus) - this.selection.set(); - this.$visualFocus(true); - this.selection.setContent(bNoParse ? html : this.prepareHtml(html)); - // notify SmartBindings that we changed stuff... - this.change(this.getValue()); - - if (bNoFocus) return; - setTimeout(function() { - _self.selection.set(); - _self.$visualFocus(); - }); - } - }; - - var prepareRE = null, noMarginTags = {"table":1,"TABLE":1}; - /** - * Processes, sanitizes and cleanses a string of raw html that originates - * from outside a contentEditable area, so that the inner workings of the - * editor are less likely to be affected. - * - * @param {String} html - * @return The sanitized string, valid to store and use in the editor - * @type {String} - */ - this.prepareHtml = function(html, bNoEnclosing) { - if (prepareRE === null) { - // compile 'em regezz - prepareRE = [ - /<(\/?)strong>|<strong( [^>]+)>/gi, - /<(\/?)em>|<em( [^>]+)>/gi, - /'/g, - /* - Ruben: due to a bug in IE and FF this regexp won't fly: - /((?:[^<]*|<(?:span|strong|em|u|i|b)[^<]*))<br[^>]*?>/gi, //@todo Ruben: add here more inline html tag names - */ - /(<(\/?)(span|strong|em|u|i|b|a|strike|sup|sub|font|img)(?:\s+[\s\S]*?)?>)|(<br[\s\S]*?>)|(<(\/?)([\w\-]+)(?:\s+[\s\S]*?)?>)|([^<>]*)/gi, //expensive work around - /(<a[^>]*href=)([^\s^>]+)*([^>]*>)/gi, - /<p><\/p>/gi, - /<a( )([^>]+)\/>|<a\/>/gi - ]; - } - - // Convert strong and em to b and i in FF since it can't handle them - if (jpf.isGecko) {//@todo what about the other browsers? - html = html.replace(prepareRE[0], '<$1b$2>') - .replace(prepareRE[1], '<$1i$2>'); - } - else if (jpf.isIE) { - html = html.replace(prepareRE[2], ''') // IE can't handle apos - .replace(prepareRE[4], '$1$2 _jpf_href=$2$3'); - //.replace(prepareRE[5], '<p> </p>'); - - // <BR>'s need to be replaced to be properly handled as - // block elements by IE - because they're not converted - // when an editor command is executed - var str = [], capture = false, strP = [], depth = [], bdepth = [], lastBlockClosed = false; - html.replace(prepareRE[3], function(m, inline, close, tag, br, block, bclose, btag, any){ - if (inline) { - var id = strP.push(inline); - - tag = tag.toLowerCase(); - if (!selfClosing[tag]) { - if (close) { - if (!depth[depth.length-1] - || depth[depth.length-1][0] != tag) { - strP.length--; //ignore non matching tag - } - else { - depth.length--; - } - } - else { - depth.push([tag, id]); - } - } - - capture = true; - } - else if (any) { - strP.push(any); - capture = true; - } - else if (br) { - if (capture) { - if (depth.length) { - /*strP.push(jpf.editor.ALTP.start, - strP.splice(depth[depth.length-1][1], 1).join(""), - jpf.editor.ALTP.end);*/ - strP.push(br); - } - else { - str.push(jpf.editor.ALTP.start, - strP.join(""), - jpf.editor.ALTP.end); - strP = []; - } - - if (!depth.length) - capture = false; - } - else { - if ((bdepth.length || lastBlockClosed) && br.indexOf("_jpf_marker") > -1) { - //debugger; - //donothing - } - else - str.push("<p> </p>"); //jpf.editor.ALTP.start ... end - } - } - else if (block){ - if (bclose) { - if (bdepth[bdepth.length-1] != btag.toLowerCase()) { - return; - } - else { - bdepth.length--; - } - - if (strP.length) { //Never put P's inside block elements - str.push(strP.join("")); - strP = []; - } - - lastBlockClosed = 2; - } - else { - var useStrP = strP.length && strP.join("").trim(); - var last = useStrP ? strP : str; - if (!noMarginTags[btag]) { - if (last[last.length - 1] == "<p> </p>") - last[last.length - 1] = "<p></p>"; - else if(useStrP && !bdepth.length) - last.push("<p></p>"); - } - - if (strP.length) { - if (!useStrP || bdepth.length) { //Never put P's inside block elements - str.push(strP.join("")); - strP = []; - } - else { - str.push(jpf.editor.ALTP.start, - strP.join(""), - jpf.editor.ALTP.end); - strP = []; - } - } - - bdepth.push(btag.toLowerCase()); - } - - str.push(block); - capture = false; - } - - lastBlockClosed = lastBlockClosed == 2 ? 1 : false; - }); - var s; - if ((s = strP.join("")).trim()) - str.push(bNoEnclosing - ? s - : jpf.editor.ALTP.start + s + jpf.editor.ALTP.end); - html = str.join(""); - } - - // Fix some issues - html = html.replace(prepareRE[6], '<a$1$2></a>'); - - return html; - }; - - var exportRE = null, selfClosing = {"br":1,"img":1,"input":1,"hr":1}; - /** - * Description. - * - * @param {String} html - * @param {Boolean} bStrict - * @return The same string of html, but then formatted in such a way that it can embedded. - * @type {String} - */ - this.exportHtml = function(html, bStrict, noParagraph) { - if (exportRE === null) { - // compile 'em regezz - exportRE = [ - /<br[^>]*><\/li>/gi, - /<br[^>]*_jpf_placeholder="1"\/?>/gi, - /<(a|span|div|h1|h2|h3|h4|h5|h6|pre|address)>[\s\n\r\t]*<\/(a|span|div|h1|h2|h3|h4|h5|h6|pre|address)>/gi, - /<(tr|td)>[\s\n\r\t]*<\/(tr|td)>/gi, - /[\s]*_jpf_href="?[^\s^>]+"?/gi, - /(".*?"|'.*?')|(\w)=([^'"\s>]+)/gi, - /<((?:br|input|hr|img)(?:[^>]*[^\/]|))>/ig, // NO! do <br /> see selfClosing - /<p> $/mig, - /(<br[^>]*?>(?:[\r\n\s]| )*<br[^>]*?>)|(<(\/?)(span|strong|em|u|i|b|a|br|strike|sup|sub|font|img)(?:\s+.*?)?>)|(<(\/?)([\w\-]+)(?:\s+.*?)?>)|([^<>]*)/gi, - /<\/p>/gi, //<p> <\/p>| - /<p>/gi, - /<\s*\/?\s*(?:\w+:\s*)?[\w-]*[\s>\/]/g - ]; - } - - if (jpf.isIE) { - html = html.replace(exportRE[7], '<p></p>') - .replace(exportRE[9], '<br />') - .replace(exportRE[10], '') - } - - html = html.replace(exportRE[0], '</li>') - .replace(exportRE[1], '') - .replace(exportRE[2], '') - .replace(exportRE[3], '<$1> </$2>') - .replace(exportRE[4], '') - .replace(exportRE[6], '<$1 />') - .replace(exportRE[11], function(m){return m.toLowerCase();}); - - //@todo: Ruben: Maybe make this a setting (paragraphs="true") - //@todo might be able to unify this function with the one above. - if (jpf.isIE && !noParagraph) { - var str = [], capture = true, strP = [], depth = [], bdepth = []; - html.replace(exportRE[8], function(m, br, inline, close, tag, block, bclose, btag, any){ - if (inline) { - if (jpf.isIE) { - inline = inline.replace(exportRE[5], function(m, str, m, v){ - return str || m + "=\"" + v + "\""; - });//'$2="$3"') //quote un-quoted attributes - } - - var id = strP.push(inline); - - if (!selfClosing[tag]) { - if (close) { - if (!depth[depth.length-1] - || depth[depth.length-1][0] != tag) { - strP.length--; //ignore non matching tag - } - else { - depth.length--; - } - } - else { - depth.push([tag, id]); - } - } - - capture = true; - } - else if (any) { - strP.push(any); - capture = true; - } - else if (br) { - if (capture) { - if (depth.length) { - strP.push(br); - } - else { - str.push("<p>", strP.join("").trim() || " ", "</p>"); - strP = []; - capture = false; - } - } - else - str.push("<p> </p>"); //jpf.editor.ALTP.start ... end - } - else if (block){ - if (bclose) { - if (bdepth[bdepth.length-1] != btag) { - return; - } - else { - bdepth.length--; - } - - if (strP.length) { //Never put P's inside block elements - str.push(strP.join("")); - strP = []; - } - } - else { - if (jpf.isIE) { - block = block.replace(exportRE[5], function(m, str, m, v){ - return str || m + "=\"" + v + "\""; - });//'$2="$3"') //quote un-quoted attributes - } - - //@todo this section can be make similar to the one in the above function and vice verse - var last = strP.length ? strP : str; - if (last[last.length - 1] == "<p> </p>") - last.length--; - - if (strP.length) { - var s; - if (bdepth.length || (s = strP.join("").trim()).replace(/<.*?>/g,"").trim() == "") { //Never put P's inside block elements - str.push(s || strP.join("")); - strP = []; - } - else { - str.push("<p>", - (s || strP.join("").trim() || " ").replace(/<br \/>[\s\r\n]*$/, ""), - "</p>"); - strP = []; - } - } - - bdepth.push(btag); - } - - str.push(block); - capture = false; - } - }); - if (strP.length) - str.push("<p>" + strP.join("").replace(/<br \/>[\s\r\n]*$/, "") + "</p>"); - html = str.join(""); - } - else { - html = html.replace(/<br[^>]*_jpf_marker="1"[^>]*>/gi, '<br />'); - } - - // check for VALID XHTML in DEBUG mode... - try { - jpf.getXml('<source>' + html.replace(/&.{3,5};/g, "") + '</source>'); - } - catch(ex) { - jpf.console.error(ex.message + "\n" + html.escapeHTML()); - } - - return html; - }; - - /** - * Issue a command to the editable area. - * - * @param {String} cmdName - * @param {mixed} cmdParam - * @type {void} - */ - this.executeCommand = function(cmdName, cmdParam) { - if (!this.plugins.isPlugin(cmdName) && inited && complete - && this.state != jpf.editor.DISABLED) { - if (jpf.isIE) { - if (!this.oDoc.body.innerHTML) - return commandQueue.push([cmdName, cmdParam]); - else - this.selection.set(); - } - - this.$visualFocus(); - - if (cmdName.toLowerCase() == "removeformat") { - /*this.plugins.get('paragraph', 'fontstyle').forEach(function(plugin){ - if (plugin.queryState(_self) == jpf.editor.ON) { - plugin.submit(null, 'normal'); - } - });*/ - - var c = this.selection.getContent(); - var disallowed = {FONT:1, SPAN:1, H1:1, H2:1, H3:1, H4:1, H5:1, - H6:1, PRE:1, ADDRESS:1, BLOCKQUOTE:1, STRONG:1, B:1, U:1, - I:1, EM:1, LI:1, OL:1, UL:1, DD:1, DL:1, DT:1}; - c = c.replace(/<\/?(\w+)(?:\s.*?|)>/g, function(m, tag) { - return !disallowed[tag] ? m : ""; - }); - if (jpf.isIE) { - var htmlNode = this.selection.setContent("<div>" + c + "</div>"); - this.selection.selectNode(htmlNode); - htmlNode.removeNode(false); - return; - } - else { - this.selection.setContent(c); - } - } - - this.oDoc.execCommand(cmdName, false, cmdParam); - - // make sure that the command didn't leave any <P> tags behind (cleanup) - cmdName = cmdName.toLowerCase(); - var bNoSel = (cmdName == "SelectAll"); - if (jpf.isIE) { - if ((cmdName == "insertunorderedlist" || cmdName == "insertorderedlist") - && this.getCommandState(cmdName) == jpf.editor.OFF) { - bNoSel = true; - } - else if (cmdName == "outdent") { - bNoSel = true; - var pLists = this.plugins.get('bullist', 'numlist'); - if (pLists.length) { - if (pLists[0].queryState(_self) != jpf.editor.OFF - && pLists[1].queryState(_self) != jpf.editor.OFF) - bNoSel = false; - } - var oNode = this.selection.getSelectedNode(); - if (bNoSel && oNode && oNode.tagName == "BLOCKQUOTE") - bNoSel = false; - } - - if (bNoSel) - this.oDoc.body.innerHTML = this.prepareHtml(this.oDoc.body.innerHTML); - var r = this.selection.getRange(); - if (r) - r.scrollIntoView(); - } - - this.notifyAll(); - this.change(this.getValue()); - - setTimeout(function() { - //_self.notifyAll(); // @todo This causes pain, find out why - if (jpf.isIE && !bNoSel) - _self.selection.set(); - _self.$visualFocus(); - }); - } - }; - - /** - * Get the state of a command (on, off or disabled) - * - * @param {String} cmdName - * @type Number - */ - this.getCommandState = function(cmdName) { - if (jpf.isGecko && (cmdName == "paste" || cmdName == "copy" || cmdName == "cut")) - return jpf.editor.DISABLED; - try { - if (!this.oDoc.queryCommandEnabled(cmdName)) - return jpf.editor.DISABLED; - else - return this.oDoc.queryCommandState(cmdName) - ? jpf.editor.ON - : jpf.editor.OFF; - } - catch (e) { - return jpf.editor.OFF; - } - }; - - /** - * Make an instance of jpf.popup (identified with a pointer to the cached - * DOM node - sCacheId) visible to the user. - * - * @param {jpf.editor.plugin} oPlugin The plugin instance - * @param {String} sCacheId Pointer to the cached DOM node - * @param {DOMElement} oRef Button node to show popup below to - * @param {Number} iWidth New width of the popup - * @param {Number} iHeight New height of the popup - * @type {void} - */ - this.showPopup = function(oPlugin, sCacheId, oRef, iWidth, iHeight) { - if (jpf.popup.last && jpf.popup.last != sCacheId) { - var o = jpf.lookup(jpf.popup.last); - if (o) { - o.state = jpf.editor.OFF; - this.notify(o.name, o.state); - } - } - - //this.selection.cache(); - this.selection.set(); - this.$visualFocus(); - - oPlugin.state = jpf.editor.ON; - this.notify(oPlugin.name, jpf.editor.ON); - - if (jpf.popup.isShowing(sCacheId)) - return; - - // using setTimeout here, because I want the popup to be shown AFTER the - // event bubbling is complete. Another click handler further up the DOM - // tree may call a jpf.popup.forceHide(); - setTimeout(function() { - jpf.popup.show(sCacheId, { - x : 0, - y : 22, - animate : false, - ref : oRef, - width : iWidth, - height : iHeight, - callback : function(oPopup) { - if (oPopup.onkeydown) return; - oPopup.onkeydown = function(e) { - e = e || window.event; - var key = e.which || e.keyCode; - if (key == 13 && typeof oPlugin['submit'] == "function") //Enter - return oPlugin.submit(new jpf.AbstractEvent(e)); - } - } - }); - }); - }; - - /** - * Paste (clipboard) data into the Editor - * - * @see element.editor.method.inserthtml - * @param {Event} e - * @type {void} - * @private - */ - function onPaste(e) { - setTimeout(function() { - var s = _self.getXHTML('text'); - if (s.match(/mso[a-zA-Z]+/i)) { //check for Paste from Word - var o = _self.plugins.get('pasteword'); - if (o) - _self.$propHandlers['value'].call(_self, o.parse(s)); - } - if (_self.realtime) - _self.change(_self.getValue()); - }); - } - - var oBookmark; - /** - * Event handler; fired when the user clicked inside the editable area. - * - * @see object.abstractevent - * @param {Event} e - * @type void - * @private - */ - function onClick(e) { - if (oBookmark && jpf.isGecko) { - var oNewBm = _self.selection.getBookmark(); - if (typeof oNewBm.start == "undefined" && typeof oNewBm.end == "undefined") { - //this.selection.moveToBookmark(oBookmark); - //RAAAAAAAAAAH stoopid firefox, work with me here!! - } - } - - var which = e.which, button = e.button; - setTimeout(function() { - var rClick = ((which == 3) || (button == 2)); - if (jpf.window.focussed != this) { - //this.$visualFocus(true); - _self.focus({}); - } - else if (!rClick) - _self.$focus({}); - }); - - jpf.AbstractEvent.stop(e); - } - - /** - * Event handler; fired when the user right clicked inside the editable area - * - * @param {Event} e - * @type {void} - * @private - */ - function onContextmenu(e) { - if (_self.state == jpf.editor.DISABLED) return; - //if (jpf.isIE) - // this.$visualFocus(true); - var ret = _self.plugins.notifyAll('context', e); - } - - var changeTimer = null; - /** - * Firing change(), when the editor is databound, subsequently after each - * keystroke, can have a VERY large impact on editor performance. That's why - * we delay the change() call. - * - * @type {void} - */ - function resumeChangeTimer() { - if (!_self.realtime || changeTimer !== null) return; - changeTimer = setTimeout(function() { - clearTimeout(changeTimer); - _self.change(_self.getValue()); - changeTimer = null; - }, 200); - } - - /** - * Event handler; fired when the user pressed a key inside the editor IFRAME. - * For IE, we apply some necessary behavior correction and for other browsers, like - * Firefox and Safari, we enable some of the missing default keyboard shortcuts. - * - * @param {Event} e - * @type {Boolean} - * @private - */ - function onKeydown(e) { - e = e || window.event; - var i, found, code = e.which || e.keyCode; - if (jpf.isIE) { - if (commandQueue.length > 0 && _self.oDoc.body.innerHTML.length > 0) { - for (i = 0; i < commandQueue.length; i++) - _self.executeCommand(commandQueue[i][0], commandQueue[i][1]); - commandQueue = []; - } - switch(code) { - case 66: // B - case 98: // b - case 105: // i - case 73: // I - case 117: // u - case 85: // U - //case 86: // V |_ See onPaste() - //case 118: // v | event handler... - if ((e.ctrlKey || (jpf.isMac && e.metaKey)) && !e.shiftKey - && !e.altKey && _self.realtime) - _self.change(_self.getValue()); - break; - case 8: // backspace - found = false; - if (_self.selection.getType() == 'Control') { - _self.selection.remove(); - found = true; - } - listBehavior.call(_self, e, true); //correct lists, if any - if (found) - return false; - break; - case 46: - listBehavior.call(_self, e, true); //correct lists, if any - break; - case 9: // tab - if (listBehavior.call(_self, e)) - return false; - break; - } - } - else { - _self.$visualFocus(); - if ((e.ctrlKey || (jpf.isMac && e.metaKey)) && !e.shiftKey && !e.altKey) { - found = false; - switch (code) { - case 66: // B - case 98: // b - _self.executeCommand('Bold'); - found = true; - break; - case 105: // i - case 73: // I - _self.executeCommand('Italic'); - found = true; - break; - case 117: // u - case 85: // U - _self.executeCommand('Underline'); - found = true; - break; - case 86: // V - case 118: // v - if (!jpf.isGecko) - onPaste.call(_self); - //found = true; - break; - case 37: // left - case 39: // right - found = true; - } - if (found) { - jpf.AbstractEvent.stop(e); - if (_self.realtime) - _self.change(_self.getValue()); - } - } - else if (!e.ctrlKey && !e.shiftKey && code == 13) - _self.dispatchEvent('keyenter', {editor: _self, event: e}); - } - _self.$visualFocus(); - if (e.metaKey || e.ctrlKey || e.altKey || e.shiftKey) { - found = _self.plugins.notifyKeyBindings({ - code : code, - control: e.ctrlKey, - alt : e.altKey, - shift : e.shiftKey, - meta : e.metaKey - }); - if (found) { - jpf.AbstractEvent.stop(e); - return false; - } - } - - if (code == 9) { // tab - if (listBehavior.call(_self, e)) { - jpf.AbstractEvent.stop(e); - return false; - } - } - else if (code == 8 || code == 46) //backspace or del - listBehavior.call(_self, e, true); //correct lists, if any - - if (!e.ctrlKey && !e.altKey && (code < 112 || code > 122) - && (code < 33 && code > 31 || code > 42 || code == 8 || code == 13)) { - resumeChangeTimer(); - } - - document.onkeydown(e); - keydownTimer = null; - } - - var keyupTimer = null; - - /** - * Event handler; fired when the user releases a key inside the editable area - * - * @see object.abstractevent - * @param {Event} e - * @type {void} - * @private - */ - function onKeyup(e) { - _self.selection.cache(); - if (keyupTimer != null) - return; - - function keyupHandler() { - clearTimeout(keyupTimer); - if (_self.state == jpf.editor.DISABLED) return; - _self.notifyAll(); - _self.dispatchEvent('typing', {editor: _self, event: e}); - _self.plugins.notifyAll('typing', e.code); - keyupTimer = null; - } - - keyupTimer = window.setTimeout(keyupHandler, 200); - //keyHandler(); - document.onkeyup(e); - } - - /** - * Corrects the default/ standard behavior of list elements (<ul> and - * <ol> HTML nodes) to match the general user experience match with - * M$ Office Word. - * - * @param {Event} e - * @param {Boolean} bFix Flag set to TRUE if you want to correct list indentation - * @type Boolean - * @private - */ - function listBehavior(e, bFix) { - var pLists = this.plugins.get('bullist', 'numlist'); - if (!pLists || !pLists.length) return false; - if (typeof e.shift != "undefined") - e.shiftKey = e.shift; - var pList = pLists[0].queryState(this) == jpf.editor.ON - ? pLists[0] - : pLists[1].queryState(this) == jpf.editor.ON - ? pLists[1] - : null; - if (!pList) return false; - if (bFix === true) - pList.correctLists(this); - else - pList.correctIndentation(this, e.shiftKey ? 'outdent' : 'indent'); - - return true; - } - - /**** Focus Handling ****/ - - /** - * Give or return the focus to the editable area, hence 'visual' focus. - * - * @param {Boolean} bNotify Flag set to TRUE if plugins should be notified of this event - * @type {void} - */ - this.$visualFocus = function(bNotify) { - // setting focus to the iframe content, upsets the 'code' plugin - var bCode = this.plugins.isActive('code'); - if (jpf.window.focussed == this && !bCode) { - try { - _self.oWin.focus(); - } - catch(e) {}; - } - - if (bCode) { - _self.notifyAll(jpf.editor.DISABLED); - _self.notify('code', jpf.editor.SELECTED); - } - else if (bNotify) - _self.notifyAll(); - }; - - var fTimer; - /** - * Fix for focus handling to mix 'n match nicely with other JPF elements - * - * @param {Event} e - * @type {void} - */ - this.$focus = function(e){ - if (!this.oExt || this.oExt.disabled) - return; - - this.setProperty('state', this.plugins.isActive('code') - ? jpf.editor.DISABLED - : jpf.editor.OFF); - - this.$setStyleClass(this.oExt, this.baseCSSname + "Focus"); - - function delay(){ - try { - if (!fTimer || document.activeElement != _self.oExt) { - _self.$visualFocus(true); - clearInterval(fTimer); - } - else { - clearInterval(fTimer); - return; - } - } - catch(e) {} - } - - if (e && e.mouse && jpf.isIE) { - clearInterval(fTimer); - fTimer = setInterval(delay, 1); - } - else - delay(); - }; - - /** - * Probe whether we should apply a focus correction to the editor at any - * given interval - * - * @param {Event} e - * @type {Boolean} - */ - this.$isContentEditable = function(e){ - return jpf.xmldb.isChildOf(this.oDoc, e.srcElement, true); - }; - - /** - * Fix for focus/ blur handling to mix 'n match nicely with other JPF - * elements - * - * @param {Event} e - * @type {void} - */ - this.$blur = function(e){ - if (!this.oExt) - return; - - var pParent = jpf.popup.last && jpf.lookup(jpf.popup.last); - if (pParent && pParent.editor == this) - jpf.popup.forceHide(); - - this.$setStyleClass(this.oExt, "", [this.baseCSSname + "Focus"]); - - var bCode = this.plugins.isActive('code'); - if (!this.realtime || bCode) - this.change(bCode ? this.plugins.get('code').getValue() : this.getValue()); - - this.setProperty('state', jpf.editor.DISABLED); - }; - - /** - * Add various event handlers to a <i>Editor</i> object. - * - * @type {void} - */ - this.$addListeners = function() { - jpf.AbstractEvent.addListener(this.oDoc, 'mouseup', onClick); - //jpf.AbstractEvent.addListener(this.oDoc, 'select', onClick.bindWithEvent(this)); - jpf.AbstractEvent.addListener(this.oDoc, 'keyup', onKeyup); - jpf.AbstractEvent.addListener(this.oDoc, 'keydown', onKeydown); - jpf.AbstractEvent.addListener(this.oDoc, 'mousedown', function(e){ - e = e || window.event; - _self.selection.cache(); - jpf.popup.forceHide(); - //this.notifyAll(); - document.onmousedown(e); - }); - - jpf.AbstractEvent.addListener(this.oDoc, 'contextmenu', onContextmenu); - jpf.AbstractEvent.addListener(this.oDoc, 'focus', function(e) { - //if (!jpf.isIE) - window.onfocus(e.event); - }); - jpf.AbstractEvent.addListener(this.oDoc, 'blur', function(e) { - //if (!jpf.isIE) - window.onblur(e.event); - }); - - this.oDoc.host = this; - - jpf.AbstractEvent.addListener(this.oDoc.body, 'paste', onPaste); - }; - - //this.addEventListener("contextmenu", onContextmenu); - - /**** Button Handling ****/ - - /** - * Transform the state of a button node to 'enabled' - * - * @type {void} - * @private - */ - function buttonEnable() { - jpf.setStyleClass(this, 'editor_enabled', - ['editor_selected', 'editor_disabled']); - this.disabled = false; - } - - /** - * Transform the state of a button node to 'disabled' - * - * @type {void} - * @private - */ - function buttonDisable() { - jpf.setStyleClass(this, 'editor_disabled', - ['editor_selected', 'editor_enabled']); - this.disabled = true; - } - - /** - * Handler function; invoked when a toolbar button node was clicked - * - * @see object.abstractevent - * @param {Event} e - * @param {DOMElement} oButton - * @type {void} - */ - this.$buttonClick = function(e, oButton) { - _self.selection.cache(); - - jpf.setStyleClass(oButton, 'active'); - var item = oButton.getAttribute("type"); - - //context 'this' is the buttons' DIV domNode reference - if (!e._bogus) { - e.isPlugin = _self.plugins.isPlugin(item); - e.state = getState(item, e.isPlugin); - } - - if (e.state == jpf.editor.DISABLED) { - buttonDisable.call(oButton); - } - else { - if (this.disabled) - buttonEnable.call(oButton); - - if (e.state == jpf.editor.ON) { - jpf.setStyleClass(oButton, 'editor_selected'); - oButton.selected = true; - } - else { - jpf.setStyleClass(oButton, '', ['editor_selected']); - oButton.selected = false; - } - - if (!e._bogus) { - if (e.isPlugin) { - var o = _self.plugins.active = _self.plugins.get(item); - o.execute(_self); - } - else - _self.executeCommand(item); - e.state = getState(item, e.isPlugin); - } - } - jpf.setStyleClass(oButton, "", ["active"]); - }; - - /** - * Retrieve the state of a command and if the command is a plugin, retrieve - * the state of the plugin - * - * @param {String} id - * @param {Boolean} isPlugin - * @return The command state as an integer that maps to one of the editor state constants - * @type {Number} - * @private - */ - function getState(id, isPlugin) { - if (isPlugin) { - var plugin = _self.plugins.get(id); - if (_self.state == jpf.editor.DISABLED && !plugin.noDisable) - return jpf.editor.DISABLED; - return plugin.queryState - ? plugin.queryState(_self) - : _self.state; - } - - if (_self.state == jpf.editor.DISABLED) - return jpf.editor.DISABLED; - - return _self.getCommandState(id); - } - - /** - * Notify a specific button item on state changes (on, off, disabled, visible or hidden) - * - * @param {String} item - * @param {Number} state Optional. - * @type {void} - */ - this.notify = function(item, state) { - var oButton = oButtons[item]; - if (!oButton) - return; - - var oPlugin = this.plugins.get(item); - if (typeof state == "undefined" || state === null) { - if (oPlugin && oPlugin.queryState) - state = oPlugin.queryState(this); - else - state = this.getCommandState(item); - } - - if (oButton.state === state) - return; - - oButton.state = state; - - if (state == jpf.editor.DISABLED) - buttonDisable.call(oButton); - else if (state == jpf.editor.HIDDEN) - oButton.style.display = "none"; - else if (state == jpf.editor.VISIBLE) - oButton.style.display = ""; - else { - if (oButton.style.display == 'none') - oButton.style.display = ""; - - if (oButton.disabled) - buttonEnable.call(oButton); - - var btnState = (oButton.selected) - ? jpf.editor.ON - : jpf.editor.OFF; - - if (state != btnState) { - this.$buttonClick({ - state : state, - isPlugin: oPlugin ? true : false, - _bogus : true - }, oButton); - } - } - }; - - /** - * Notify all button items on state changes (on, off or disabled) - * - * @param {Number} state Optional. - * @type {void} - */ - this.notifyAll = function(state) { - for (var item in oButtons) - this.notify(item, state); - }; - - /** - * Returns the translated key from a locale pack/ collection - * - * @param {String} key - * @param {Boolean} bIsPlugin - * @type {String} - * @private - */ - this.translate = function(key, bIsPlugin) { - if ((!bIsPlugin && !jpf.editor.i18n[_self.language][key]) - || (bIsPlugin && !jpf.editor.i18n[_self.language]['plugins'][key])) - jpf.console.error('Translation does not exist' - + (bIsPlugin ? ' for plugin' : '') + ': ' + key); - - return bIsPlugin - ? jpf.editor.i18n[_self.language]['plugins'][key] - : jpf.editor.i18n[_self.language][key]; - }; - - /**** Init ****/ - - /** - * Draw all HTML elements for the editor toolbar - * - * @param {HTMLElement} oParent - * @type {void} - * @private - */ - function drawToolbars(oParent) { - var tb, l, k, i, j, z, x, node, buttons, bIsPlugin; - var item, bNode, oNode = this.$getOption('toolbars'); - var plugin, oButton, plugins = this.plugins; - - for (i = 0, l = oNode.childNodes.length; i < l; i++) { - node = oNode.childNodes[i]; - if (node.nodeType != 1) - continue; - - if (node[jpf.TAGNAME] != "toolbar") { - throw new Error(jpf.formatErrorString(0, this, - "Creating toolbars", - "Invalid element found in toolbars definition", - node)); - } - - for (j = 0, k = node.childNodes.length; j < k; j++) { - bNode = node.childNodes[j]; - - if (bNode.nodeType != 3 && bNode.nodeType != 4) { - throw new Error(jpf.formatErrorString(0, this, - "Creating toolbars", - "Invalid element found in toolbar definition", - bNode)); - } - - buttons = bNode.nodeValue.splitSafe(",", -1, true); - } - - if (!buttons || !buttons.length) - continue; - - this.$getNewContext("toolbar"); - tb = oParent.appendChild(this.$getLayoutNode("toolbar"));//, oParent.lastChild - - for (z = 0, x = buttons.length; z < x; z++) { - item = buttons[z]; - - if (item == "|") { //seperator! - this.$getNewContext("divider"); - tb.appendChild(this.$getLayoutNode("divider")); - } - else { - this.$getNewContext("button"); - oButton = tb.appendChild(this.$getLayoutNode("button")); - - bIsPlugin = false; - if (!this.$nativeCommands.contains(item)) { - plugin = plugins.add(item); - if (!plugin) - jpf.console.error('Plugin \'' + item + '\' can not \ - be found and/ or instantiated.', - 'editor'); - bIsPlugin = true; - } - - if (bIsPlugin) { - plugin = plugin || plugins.get(item); - if (!plugin) - continue; - if (plugin.type != jpf.editor.TOOLBARITEM) - continue; - - this.$getLayoutNode("button", "label", oButton) - .setAttribute("class", 'editor_icon editor_' + plugin.icon); - - oButton.setAttribute("title", this.translate(plugin.name, true)); - } - else { - this.$getLayoutNode("button", "label", oButton) - .setAttribute("class", 'editor_icon editor_' + item); - - oButton.setAttribute("title", this.translate(item)); - } - - oButton.setAttribute("onmousedown", "jpf.all[" - + _self.uniqueId + "].$buttonClick(event, this);"); - oButton.setAttribute("onmouseover", "jpf.setStyleClass(this, 'hover');"); - oButton.setAttribute("onmouseout", "jpf.setStyleClass(this, '', ['hover']);"); - - oButton.setAttribute("type", item); - } - } - - buttons = null; - } - - if (jpf.isIE) { - var nodes = oParent.getElementsByTagName("*"); - for (var i = nodes.length - 1; i >= 0; i--) - nodes[i].setAttribute("unselectable", "On"); - } - }; - - /** - * Draw all the HTML elements at startup time. - * - * @type {void} - */ - this.$draw = function() { - if (this.$jml.getAttribute("plugins")) { - this.$propHandlers["plugins"] - .call(this, this.$jml.getAttribute("plugins")); - } - if (this.$jml.getAttribute("language")) { - this.$propHandlers["language"] - .call(this, this.$jml.getAttribute("language")); - } - - this.plugins = new jpf.editor.plugins(this.$plugins, this); - this.selection = new jpf.editor.selection(this); - - this.oExt = this.$getExternal("main", null, function(oExt){ - drawToolbars.call(this, this.$getLayoutNode("main", "toolbar")); - }); - this.oToolbar = this.$getLayoutNode("main", "toolbar", this.oExt); - var oEditor = this.$getLayoutNode("main", "editor", this.oExt); - - // fetch the DOM references of all toolbar buttons and let the - // respective plugins finish initialization - var btns = this.oToolbar.getElementsByTagName("div"); - for (var item, plugin, i = btns.length - 1; i >= 0; i--) { - item = btns[i].getAttribute("type"); - if (!item) continue; - - oButtons[item] = btns[i]; - plugin = this.plugins.coll[item]; - if (!plugin) continue; - - plugin.buttonNode = btns[i]; - - if (plugin.init) - plugin.init(this); - } - - this.iframe = document.createElement('iframe'); - this.iframe.setAttribute('frameborder', '0'); - this.iframe.setAttribute('border', '0'); - this.iframe.setAttribute('marginwidth', '0'); - this.iframe.setAttribute('marginheight', '0'); - oEditor.appendChild(this.iframe); - this.oWin = this.iframe.contentWindow; - this.oDoc = this.oWin.document; - - // get the document style (CSS) from the skin: - // see: jpf.presentation.getCssString(), where the following statement - // is derived from. - var sCss = jpf.getXmlValue($xmlns(jpf.skins.skins[this.skinName.split(":")[0]].xml, - "docstyle", jpf.ns.jml)[0], "text()"); - if (!sCss) { - sCss = "\ - html {\ - cursor: text;\ - border: 0;\ - }\ - body {\ - margin: 8px;\ - padding: 0;\ - border: 0;\ - color: #000;\ - font-family: Verdana,Arial,Helvetica,sans-serif;\ - font-size: 10pt;\ - background: #fff;\ - word-wrap: break-word;\ - }\ - p {\ - margin: 0;\ - padding: 0;\ - }"; - } - - this.oDoc.open(); - this.oDoc.write('<?xml version="1.0" encoding="UTF-8"?>\ - <html>\ - <head>\ - <title></title>\ - <style type="text/css">' + sCss + '</style>\ - </head>\ - <body class="visualAid"></body>\ - </html>'); - this.oDoc.close(); - - if (jpf.hasFocusBug) - jpf.sanitizeTextbox(this.oDoc.body); - - // setup layout rules: - jpf.layout.setRules(this.oExt, this.uniqueId + "_editor", - "jpf.all[" + this.uniqueId + "].$resize()"); - jpf.layout.activateRules(this.oExt); - - // do the magic, make the editor editable. - this.makeEditable(); - - setTimeout(function() { - _self.setProperty('state', jpf.editor.DISABLED); - }) - }; - - /** - * Takes care of setting the proper size of the editor after a resize event - * was fired through the JPF layout manager - * @see object.layout - * - * @type {void} - */ - this.$resize = function() { - if (!this.iframe || !this.iframe.parentNode || !this.oExt.offsetHeight) - return; - - var h = (this.oExt.offsetHeight - this.oToolbar.offsetHeight - 2); - if (!h || h < 0) h = 0; - - this.iframe.parentNode.style.height = h + "px"; - - //TODO: check if any buttons from the toolbar became invisible/ visible again... - this.plugins.notifyAll("resize"); - - if (this.plugins.isActive('code')) - this.plugins.get('code').setSize(this); - }; - - /** - * Parse the block of JML that constructed this editor instance for arguments - * like width, height, etc. - * - * @param {XMLRootElement} x - * @type {void} - */ - this.$loadJml = function(x){ - this.oInt = this.$getLayoutNode("main", "container", this.oExt); - - if (jpf.xmldb.isOnlyChild(x.firstChild, [3,4])) - this.$handlePropSet("value", x.firstChild.nodeValue.trim()); - else - jpf.JmlParser.parseChildren(this.$jml, null, this); - - if (typeof this.realtime == "undefined") - this.$propHandlers["realtime"].call(this); - - //jpf.ed = this; - //jpf.ed.iframe.contentWindow.document == jpf.ed.oDoc - }; - - this.$destroy = function() { - this.plugins.$destroy(); - this.selection.$destroy(); - jpf.editor.ALTP.node = null; - this.plugins = this.selection = this.oDoc.host = this.oToobar = - this.oDoc = this.oWin = this.iframe = prepareRE = exportRE = null; - }; -}).implement( - jpf.Validation, - jpf.DataBinding, - jpf.Presentation -); - -jpf.editor.ON = 1; -jpf.editor.OFF = 0; -jpf.editor.DISABLED = -1; -jpf.editor.VISIBLE = 2; -jpf.editor.HIDDEN = 3; -jpf.editor.SELECTED = 4; -jpf.editor.ALTP = { - start: '<p>',//<div style="display:block;visibility:hidden;" _jpf_placeholder="1">', - end : '</p>', //'</div>', - text : '{jpf_placeholder}', - node : null -}; - -jpf.editor.i18n = { - 'en_GB': { - 'cancel': 'Cancel', - 'insert': 'Insert', - 'bold': 'Bold', - 'italic': 'Italic', - 'underline': 'Underline', - 'strikethrough': 'Strikethrough', - 'justifyleft': 'Align text left', - 'justifycenter': 'Center', - 'justifyright': 'Align text right', - 'justifyfull': 'Justify', - 'removeformat': 'Clear formatting', - 'cut': 'Cut', - 'copy': 'Copy', - 'paste': 'Paste', - 'outdent': 'Decrease indent', - 'indent': 'Increase indent', - 'undo': 'Undo', - 'redo': 'Redo', - 'plugins': { - 'anchor': 'Insert anchor', - 'blockquote': 'Blockquote', - 'charmap': 'Character map', - 'code': 'HTML source view', - 'forecolor': 'Font color', - 'backcolor': 'Highlight color', - 'insertdate': 'Insert current date', - 'inserttime': 'Insert current time', - 'rtl': 'Change text direction to right-to-left', - 'ltr': 'Change text direction to left-to-right', - 'emotions': 'Insert emotion', - 'fonts': 'Font', - 'fontsize': 'Font size', - 'fontstyle': 'Font style', - 'paragraph': 'Paragraph style', - 'help': 'Help', - 'hr': 'Insert horizontal rule', - 'image': 'Insert image', - 'imagespecial': 'Choose an image to insert', - 'link': 'Insert hyperlink', - 'unlink': 'Remove hyperlink', - 'bullist': 'Bullets', - 'numlist': 'Numbering', - 'media': 'Insert medium', - 'pastetext': 'Paste plaintext', - 'paste_keyboardmsg': 'Use %s on your keyboard to paste the text into the window.', - 'print': 'Print document', - 'preview': 'Preview document', - 'scayt': 'Turn spellcheck on/ off', - 'search': 'Search', - 'replace': 'Search and Replace', - 'sub': 'Subscript', - 'sup': 'Superscript', - 'table': 'Insert table', - 'table_noun': 'Table', - 'visualaid': 'Toggle visual aid on/ off' - } - }, - 'nl_NL': { - 'cancel': 'Annuleren', - 'insert': 'Invoegen', - 'bold': 'Vet', - 'italic': 'Schuingedrukt', - 'underline': 'Onderstreept', - 'strikethrough': 'Doorgestreept', - 'justifyleft': 'Recht uitlijnen', - 'justifycenter': 'Centreren', - 'justifyright': 'Rechts uitlijnen', - 'justifyfull': 'Justify', - 'removeformat': 'Stijlen verwijderen', - 'cut': 'Knippen', - 'copy': 'Kopieren', - 'paste': 'Plakken', - 'outdent': 'Inspringen verkleinen', - 'indent': 'Inspringen vergroten', - 'undo': 'Ongedaan maken', - 'redo': 'Opnieuw', - 'plugins': { - 'anchor': 'Anchor invoegen', - 'blockquote': 'Blockquote', - 'charmap': 'Speciale tekens', - 'code': 'HTML broncode', - 'forecolor': 'Tekstkleur', - 'backcolor': 'Markeerkleur', - 'insertdate': 'Huidige datum invoegen', - 'inserttime': 'Huidige tijd invoegen', - 'rtl': 'Verander tekstrichting naar rechts-naar-links', - 'ltr': 'Verander tekstrichting naar links-naar-rechts', - 'emotions': 'Emoticon invoegen', - 'fonts': 'Lettertype', - 'fontsize': 'Letter grootte', - 'fontstyle': 'Tekststijl', - 'paragraph': 'Paragraafstijl', - 'help': 'Hulp', - 'hr': 'Horizontale lijn invoegen', - 'image': 'Afbeelding invoegen', - 'imagespecial': 'Afbeelding kiezen', - 'link': 'Link invoegen', - 'unlink': 'Link verwijderen', - 'bullist': 'Ongenummerd', - 'numlist': 'Genummerd', - 'media': 'Medium invoegen', - 'pastetext': 'Tekst Plakken', - 'paste_keyboardmsg': 'Gebruik %s op uw toetsenbord om tekst in dit scherm te plakken.', - 'print': 'Printen', - 'preview': 'Voorbeeldvertoning', - 'scayt': 'Spelling check aan/ uit', - 'search': 'Zoeken', - 'replace': 'Zoeken en vervangen', - 'sub': 'Subscript', - 'sup': 'Superscript', - 'table': 'Tabel invoegen', - 'table_noun': 'Tabel', - 'visualaid': 'Visuele hulp aan/ uit' - } - } -}; - - - -/*FILEHEAD(/var/lib/jpf/src/elements/list.js)SIZE(-1077090856)TIME(1238944817)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-/**
- * Element displaying a skinnable list of options which can be selected.
- * Selection of multiple items can be allowed. Items can be renamed
- * and removed. The list can be used as a collection of checkboxes or
- * radiobuttons. This is especially useful for use in forms.
- * This element is one of the most often used elements. It can display lists
- * of items in a cms style interface or display a list of search results in
- * a more website like interface.
- * Example:
- * A simple list with inline items.
- * <code>
- * <j:list multiselect="false">
- * <j:item>The Netherlands</j:item>
- * <j:item>United States of America</j:item>
- * <j:item>United Kingdom</j:item>
- * ...
- * </j:list>
- * </code>
- * Example:
- * A databound list with items loaded from an xml file.
- * <code>
- * <j:list model="url:users.xml" traverse="user" caption="@name" />
- * </code>
- * Example:
- * A databound list using the j:bindings element
- * <code>
- * <j:list model="url:users.xml">
- * <j:bindings>
- * <j:caption select="@name" />
- * <j:css select="self::node()[@type='friend']" value="friend" />
- * <j:traverse select="users" />
- * </j:bindings>
- * </j:list>
- * </code>
- * Example:
- * A small product search application using a list to display results.
- * <code>
- * <j:bar>
- * <h1>Search for a product</h1>
- *
- * <j:textbox id="txtSearch" selectfocus="true" />
- * <j:button onclick="search()" default="true" />
- * </j:bar>
- *
- * <j:model id="mdlSearch" />
- *
- * <j:list
- * model = "mdlSearch"
- * autoselect = "false"
- * caching = "false"
- * empty-message = "No products found">
- * <j:bindings>
- * <j:caption select="."><![CDATA[
- * <h2>{title}</h2>
- * <img src="{img}" />
- * <p>{decs}</p>
- * ]]></j:caption>
- * <j:traverse select="product" />
- * </j:bindings>
- * </j:list>
- *
- * <j:script>
- * function search(){
- * mdlSearch.loadFrom("url:search.php?keyword=" + txtSearch.getValue());
- * }
- * </j:script>
- * </code>
- *
- * @event click Fires when a user presses a mouse button while over this element.
- *
- * @constructor
- * @define list, select, select1, thumbnail
- * @allowchild {smartbinding}
- * @addnode elements
- *
- * @inherits jpf.BaseList
- * @inherits jpf.Rename
- * @inherits jpf.DragDrop
- *
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.4
- */
-jpf.thumbnail =
-jpf.select =
-jpf.select1 =
-jpf.list = jpf.component(jpf.NODE_VISIBLE, function(){
- var _self = this;
-
- this.$getCaptionElement = function(){
- if (!(this.$indicator || this.$selected))
- return;
-
- var x = this.$getLayoutNode("item", "caption", this.$indicator || this.$selected);
- if (!x)
- return;
- return x.nodeType == 1 ? x : x.parentNode;
- };
-
- this.addEventListener("afterselect", function(e){
- if (this.hasFeature(__VALIDATION__))
- this.validate(true);
- });
-
- /**** Properties and Attributes ****/
-
- this.$supportedProperties.push("appearance", "mode", "more");
-
- /**
- * @attribute {String} appearance the type of select this element is.
- * This is an xforms property and only available if jpf is compiled
- * with __WITH_XFORMS set to 1.
- * Possible values:
- * full depending on the tagName this element is either a list of radio options or of checked options.
- * compact this elements functions like a list with multiselect off.
- * minimal this element functions as a dropdown element.
- */
- this.$propHandlers["appearance"] = function(value){
-
- };
-
- /**
- * @attribute {String} mode Sets the way this element interacts with the user.
- * Possible values:
- * check the user can select a single item from the list. The selected item is indicated.
- * radio the user can select multiple items from a list. Each selected item is indicated.
- */
- this.mode = "normal";
- this.$propHandlers["mode"] = function(value){
- this.mode = value || "normal";
-
- if ("check|radio".indexOf(this.mode) > -1) {
- this.allowdeselect = false;
-
- this.addEventListener("afterrename", $afterRenameMode);
-
- if (this.mode == "check") {
- this.autoselect = false;
- this.ctrlselect = true;
- }
- else if (this.mode == "radio")
- this.multiselect = false;
-
- //if (!this.actionRules) //default disabled
- //this.actionRules = {}
- }
- else {
- //@todo undo actionRules setting
- this.ctrlselect = false;
- this.removeEventListener("afterrename", $afterRenameMode);
- }
- };
-
- function $afterRenameMode(){
- var sb = this.$getMultiBind();
- if (!sb)
- return;
-
- //Make sure that the old value is removed and the new one is entered
- sb.$updateSelection();
- //this.reselect(this.selected);
- }
-
- /**
- * @attribute {String} more Adds a new item to the list and lets the users
- * type in the new name. This is especially useful in the interface when
- * {@link element.list.attribute.mode} is set to check or radio. For instance in a form.
- * Example:
- * This example shows a list in form offering the user several options. The
- * user can add a new option. A server script could remember the addition
- * and present it to all new users of the form.
- * <code>
- * <j:label>Which newspapers do you read?</j:label>
- * <j:list ref="krant"
- * more = "caption:Other newspaper"
- * model = "mdlSuggestions:question[@key='krant']">
- * <j:bindings>
- * <j:caption select="text()" />
- * <j:value select="text()" />
- * <j:traverse select="answer" />
- * </j:bindings>
- * <j:actions>
- * <j:rename select="self::node()[@custom='1']" />
- * <j:remove select="self::node()[@custom='1']" />
- * <j:add>
- * <answer custom="1" />
- * </j:add>
- * </j:actions>
- * </j:list>
- * </code>
- */
- this.$propHandlers["more"] = function(value){
- if (value) {
- this.delayedselect = false;
- this.addEventListener("xmlupdate", $xmlUpdate);
- //this.addEventListener("afterrename", $afterRenameMore);
- //this.addEventListener("beforeselect", $beforeSelect);
-
- this.$setClearMessage = function(msg){
- if (!this.moreItem)
- this.$fill();
- this.oInt.appendChild(this.moreItem);
- };
- this.$updateClearMessage = function(){}
- this.$removeClearMessage = function(){};
- }
- else {
- this.removeEventListener("xmlupdate", $xmlUpdate);
- //this.removeEventListener("afterrename", $afterRenameMore);
- //this.removeEventListener("beforeselect", $beforeSelect);
- }
- };
-
- function $xmlUpdate(e){
- if ("insert|add|synchronize|move".indexOf(e.action) > -1)
- this.oInt.appendChild(this.moreItem);
- }
-
- /*function $afterRenameMore(){
- var caption = this.applyRuleSetOnNode("caption", this.indicator)
- var xmlNode = this.findXmlNodeByValue(caption);
-
- var curNode = this.indicator;
- if (xmlNode != curNode || !caption) {
- if (xmlNode && !this.isSelected(xmlNode))
- this.select(xmlNode);
- this.remove(curNode);
- }
- else
- if (!this.isSelected(curNode))
- this.select(curNode);
- }
-
- function $beforeSelect(e){
- //This is a hack
- if (e.xmlNode && this.isSelected(e.xmlNode)
- && e.xmlNode.getAttribute('custom') == '1') {
- this.setIndicator(e.xmlNode);
- this.selected = e.xmlNode;
- debugger;
- setTimeout(function(){
- _self.startRename()
- });
- return false;
- }
- }*/
-
- /**** Keyboard support ****/
-
- this.addEventListener("keydown", this.$keyHandler, true);
-
- /**** Drag & Drop ****/
-
- this.$showDragIndicator = function(sel, e){
- var x = e.offsetX;
- var y = e.offsetY;
-
- this.oDrag.startX = x;
- this.oDrag.startY = y;
-
- document.body.appendChild(this.oDrag);
- this.$updateNode(this.selected, this.oDrag);
-
- return this.oDrag;
- };
-
- this.$hideDragIndicator = function(){
- this.oDrag.style.display = "none";
- };
-
- this.$moveDragIndicator = function(e){
- this.oDrag.style.left = (e.clientX - this.oDrag.startX) + "px";
- this.oDrag.style.top = (e.clientY - this.oDrag.startY) + "px";
- };
-
- this.$initDragDrop = function(){
- if (!this.$hasLayoutNode("dragindicator"))
- return;
-
- this.oDrag = jpf.xmldb.htmlImport(
- this.$getLayoutNode("dragindicator"), document.body);
-
- this.oDrag.style.zIndex = 1000000;
- this.oDrag.style.position = "absolute";
- this.oDrag.style.cursor = "default";
- this.oDrag.style.display = "none";
- };
-
- this.findValueNode = function(el){
- if (!el) return null;
-
- while(el && el.nodeType == 1
- && !el.getAttribute(jpf.xmldb.htmlIdTag)) {
- el = el.parentNode;
- }
-
- return (el && el.nodeType == 1 && el.getAttribute(jpf.xmldb.htmlIdTag))
- ? el
- : null;
- };
-
- this.$dragout = function(dragdata){
- if (this.lastel)
- this.$setStyleClass(this.lastel, "", ["dragDenied", "dragInsert",
- "dragAppend", "selected", "indicate"]);
- this.$setStyleClass(this.$selected, "selected", ["dragDenied",
- "dragInsert", "dragAppend", "indicate"]);
-
- this.lastel = null;
- };
-
- this.$dragover = function(el, dragdata, extra){
- if(el == this.oExt) return;
-
- this.$setStyleClass(this.lastel || this.$selected, "", ["dragDenied",
- "dragInsert", "dragAppend", "selected", "indicate"]);
-
- this.$setStyleClass(this.lastel = this.findValueNode(el), extra
- ? (extra[1] && extra[1].getAttribute("operation") == "insert-before"
- ? "dragInsert"
- : "dragAppend")
- : "dragDenied");
- };
-
- this.$dragdrop = function(el, dragdata, extra){
- this.$setStyleClass(this.lastel || this.$selected,
- !this.lastel && (this.$selected || this.lastel == this.$selected)
- ? "selected"
- : "",
- ["dragDenied", "dragInsert", "dragAppend", "selected", "indicate"]);
-
- this.lastel = null;
- };
-
- /**** Init ****/
-
- this.$draw = function(){
- this.appearance = this.$jml.getAttribute("appearance") || "compact";
- var mode = this.$jml.getAttribute("mode");
-
- if (this.tagName == "select" && (this.appearance == "full"
- || this.appearance == "minimal") || mode == "check") {
- this.$jml.setAttribute("mode", "check");
- if (!this.$jml.getAttribute("skin"))
- this.$loadSkin("default:checklist"); //@todo use getOption here
- }
- else if (this.tagName == "select1" && this.appearance == "full"
- || mode == "radio") {
- this.$jml.setAttribute("mode", "radio");
- if (!this.$jml.getAttribute("skin"))
- this.$loadSkin("default:radiolist"); //@todo use getOption here
- }
- else if (this.tagName == "select1" && this.appearance == "compact")
- this.multiselect = false;
-
- //Build Main Skin
- this.oExt = this.$getExternal();
- this.oInt = this.$getLayoutNode("main", "container", this.oExt);
-
- if (jpf.hasCssUpdateScrollbarBug && !this.mode)
- this.$fixScrollBug();
-
- this.oExt.onclick = function(e){
- _self.dispatchEvent("click", {
- htmlEvent: e || event
- });
- }
-
- //Get Options form skin
- //Types: 1=One dimensional List, 2=Two dimensional List
- this.listtype = parseInt(this.$getOption("main", "type")) || 1;
- //Types: 1=Check on click, 2=Check independent
- this.behaviour = parseInt(this.$getOption("main", "behaviour")) || 1;
- };
-
- this.$loadJml = function(x){
- if (this.$jml.childNodes.length)
- this.$loadInlineData(this.$jml);
- };
-
- this.$destroy = function(){
- this.oExt.onclick = null;
- jpf.removeNode(this.oDrag);
- this.oDrag = null;
- };
-}).implement(
- jpf.Rename,
- jpf.DragDrop,
- jpf.BaseList
-);
- - -/*FILEHEAD(/var/lib/jpf/src/elements/errorbox.js)SIZE(-1077090856)TIME(1238944817)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * Element showing an error message when the attached element
- * is in erroneous state and has the invalidmsg="" attribute specified.
- * In most cases the errorbox element is implicit and will be created
- * automatically.
- * Example:
- * <code>
- * <j:errorbox>
- * Invalid e-mail address entered.
- * </j:errorbox>
- * </code>
- * Remarks:
- * In most cases the errorbox element is not created directly but implicitly
- * by a validationgroup. an element that goes into an error state will
- * show the errorbox.
- * <code>
- * <j:bar validgroup="vgForm">
- * <j:label>Phone number</j:label>
- * <j:textbox id="txtPhone"
- * required = "true"
- * pattern = "(\d{3}) \d{4} \d{4}"
- * invalidmsg = "Incorrect phone number entered" />
- *
- * <j:label>Password</j:label>
- * <j:textbox
- * required = "true"
- * mask = "password"
- * minlength = "4"
- * invalidmsg = "Please enter a password of at least four characters" />
- * </j:bar>
- * </code>
- *
- * To check if the element has valid information entered, leaving the textbox
- * (focussing another element) will trigger a check. Programmatically a check
- * can be done using the following code:
- * <code>
- * txtPhone.validate();
- *
- * //Or use the html5 syntax
- * txtPhone.checkValidity();
- * </code>
- *
- * To check for the entire group of elements use the validation group. For only
- * the first non-valid element the errorbox is shown. That element also receives
- * focus.
- * <code>
- * vgForm.validate();
- * </code>
- *
- * @constructor
- * @define errorbox
- *
- * @allowchild {anyxhtml}
- * @addnode elements
- *
- * @inherits jpf.Presentation
- *
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.4
- */
-
-jpf.errorbox = jpf.component(jpf.NODE_VISIBLE, function(){
- this.editableParts = {"main" : [["container","@invalidmsg"]]};
-
- var _self = this;
-
- this.$positioning = "basic";
- this.display = function(host){
- this.host = host;
-
- var refHtml =
- host.validityState.errorHtml ||
- host.oExt;
-
- document.body.appendChild(this.oExt);
- var pos = jpf.getAbsolutePosition(refHtml, document.body);
-
- if (document != refHtml.ownerDocument) {
- var pos2 = jpf.getAbsolutePosition(refHtml.ownerDocument.parentWindow.frameElement, document.body);
- pos[0] += pos2[0];
- pos[1] += pos2[1];
- }
-
- var left = (pos[0] + parseFloat(host.$getOption("main", "erroffsetx") || 0))
- this.oExt.style.left = left + "px"
- this.oExt.style.top = (pos[1] + parseFloat(host.$getOption("main", "erroffsety") || 0)) + "px"
- this.show();
-
- this.$setStyleClass(this.oExt,
- left + this.oExt.offsetWidth > this.oExt.offsetParent.offsetWidth
- ? "rightbox"
- : "leftbox", ["leftbox", "rightbox"]);
- }
-
- /**
- * Sets the message of the errorbox.
- * @param {String} value
- */
- this.setMessage = function(value){
- if(value && value.indexOf(";")>-1){
- value = value.split(";");
- value = "<strong>" + value[0] + "</strong>" + value[1];
- }
- this.oInt.innerHTML = value || "";
- };
-
-
- this.$draw = function(){
- //Build Main Skin
- this.oExt = this.$getExternal();
- this.oInt = this.$getLayoutNode("main", "container", this.oExt);
- this.oClose = this.$getLayoutNode("main", "close", this.oExt);
-
- if (this.oClose) {
- this.oClose.onclick = function(){ - _self.hide();
-
- if (_self.host) - _self.host.focus(null, {mouse:true}); - };
- }
-
- this.oExt.onmousedown = function(e){
- (e || event).cancelBubble = true;
-
- if (jpf.hasFocusBug)
- jpf.window.$focusfix();
- }
-
- this.hide();
- };
-
- this.$loadJml = function(x){
- jpf.JmlParser.parseChildren(this.$jml, this.oInt, this);
-
- };
-
- this.$destroy = function(){
- if (this.oClose)
- this.oClose.onclick = null;
-
- this.oExt.onmousedown = null;
- }
-}).implement(
- jpf.Presentation
-);
- -/*FILEHEAD(/var/lib/jpf/src/elements/portal.js)SIZE(-1077090856)TIME(1239018216)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-/**
- * Element displaying a rectangle consisting of one or more columns
- * which contain zero or more windows. Each window is loaded with specific
- * content described in jml. Each of these so-called 'docklets'
- * can have specific data loaded from a datasource and can
- * be instantiated more than once.
- * Example:
- * <code>
- * <j:portal columns="60%,40%">
- * <j:bindings>
- * <j:src select="@src" />
- * <j:collapsed select="@collapsed" default="0" />
- * <j:icon value="icoDocklet.png" />
- * <j:column select="@column" />
- * <j:caption select="@name" />
- * <j:traverse select="docklet" />
- * </j:bindings>
- * <j:model>
- * <docklets>
- * <docklet name="Current Usage" src="url:usage.xml" column="0" />
- * <docklet name="Billing History" src="url:history.xml" column="0" />
- * <docklet name="Orders" src="url:orders.xml" column="1" />
- * <docklet name="Features" src="url:features.xml" column="1" />
- * </docklets>
- * </j:model>
- * </j:portal>
- * </code>
- * Remarks:
- * A docklet xml is a piece of jml that should be in the following form:
- * <code>
- * <j:docklet xmlns:j="http://www.javeline.com/2005/jml"
- * caption="Billing History" icon="icoBilling.gif" name="BillHistory">
- * <j:script><![CDATA[
- * function BillHistory(){
- * //Create a Javeline class
- * jpf.makeClass(this);
- *
- * //Inherit from the portal.docklet baseclass
- * this.inherit(jpf.portal.docklet);
- *
- * this.$init = function(xmlSettings, oDocklet){
- * //Process xml settings
- * }
- * }
- * ]]></j:script>
- *
- * <!-- the edit panel of the window -->
- * <j:config>
- * ...
- * </j:config>
- *
- * <!-- the body of the window -->
- * <j:body>
- * ...
- * </j:body>
- * </j:docklet>
- * </code>
- *
- * @constructor
- * @allowchild {smartbinding}
- * @addnode elements:portal
- *
- * @inherits jpf.Presentation
- * @inherits jpf.MultiSelect
- * @inherits jpf.DataBinding
- * @inherits jpf.JmlElement
- * @inherits jpf.Cache
- *
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.9
- *
- * @binding src Determines the data instruction that loads the docklet from it's datasource.
- * @binding collapsed Determines wether the docklet is collapsed after init.
- * @binding icon Determines the icon of the docklet.
- * @binding column Determines the column in which the docklet is created.
- * @binding caption Determines the caption of the docklet.
- */
-jpf.portal = jpf.component(jpf.NODE_VISIBLE, function(){
- this.canHaveChildren = true;
- this.$focussable = false;
-
- this.$deInitNode = function(xmlNode, htmlNode){
- if (!htmlNode)
- return;
-
- //Remove htmlNodes from tree
- htmlNode.parentNode.removeChild(htmlNode);
- };
-
- this.$updateNode = function(xmlNode, htmlNode){
- this.applyRuleSetOnNode("icon", xmlNode);
- };
-
- this.$moveNode = function(xmlNode, htmlNode){
- if (!htmlNode)
- return;
- };
-
- /**** Keyboard support ****/
-
- //Handler for a plane list
- this.addEventListener("keydown", function(e){
- var key = e.keyCode;
- var ctrlKey = e.ctrlKey;
- var shiftKey = e.shiftKey;
- var altKey = e.altKey;
-
- if (!this.selected)
- return;
-
- switch (key) {
- default:
- break;
- }
- }, true);
-
- /**** Databinding and Caching ****/
-
- this.$getCurrentFragment = function(){
- //if(!this.value) return false;
-
- var fragment = document.createDocumentFragment();
- while (this.columns[0].childNodes.length) {
- fragment.appendChild(this.columns[0].childNodes[0]);
- }
-
- return fragment;
- };
-
- this.$setCurrentFragment = function(fragment){
- this.oInt.appendChild(fragment);
-
- if (!jpf.window.hasFocus(this))
- this.blur();
- };
-
- this.$findNode = function(cacheNode, id){
- if (!cacheNode)
- return this.pHtmlDoc.getElementById(id);
- return cacheNode.getElementById(id);
- };
-
- this.$setClearMessage = function(msg){
- var oEmpty = jpf.xmldb.htmlImport(this.$getLayoutNode("empty"), this.oInt);
- var empty = this.$getLayoutNode("empty", "caption", oEmpty);
- if (empty)
- jpf.xmldb.setNodeValue(empty, msg || "");
- if (oEmpty)
- oEmpty.setAttribute("id", "empty" + this.uniqueId);
- };
-
- this.$removeClearMessage = function(){
- var oEmpty = document.getElementById("empty" + this.uniqueId);
- if (oEmpty)
- oEmpty.parentNode.removeChild(oEmpty);
- //else this.oInt.innerHTML = ""; //clear if no empty message is supported
- };
-
- var portalNode = this;
- function createDocklet(xmlNode, docklet, dataNode){
- /* Model replacement - needs to be build
- var models = xmlNode.selectNodes("//model/@id");
- for (var i = 0; i < models.lenth; i++) {
- xmlNode.selectNodes("//node()[@model='" + models[i]
- }
- */
- //also replace docklet id's
- var name = xmlNode.getAttribute("name");
-
- //Load docklet
- docklet.$jml = xmlNode;
- docklet.$loadSkin("default:docklet");
- docklet.btnedit = true;
- docklet.btnmin = true;
- docklet.btnclose = true;
-
- docklet.$draw();//name
- docklet.$loadJml(xmlNode, name);
- docklet.setCaption(portalNode.applyRuleSetOnNode("caption", dataNode));
- docklet.setIcon(portalNode.applyRuleSetOnNode("icon", dataNode));
-
- if (xmlNode.getAttribute("width"))
- docklet.setWidth(xmlNode.getAttribute("width"));
- else
- docklet.oExt.style.width = "auto";
- //if(xmlNode.getAttribute("height")) docklet.setHeight(xmlNode.getAttribute("height"));
- //else docklet.oExt.style.height = "auto";
-
- docklet.display(0, 0);
-
- //Create dockletClass
- if (!self[name]) {
- alert("could not find class '" + name + "'");
- }
-
- //instantiate class
- var dockletClass = new self[name]();
- portalNode.docklets.push(dockletClass);
- dockletClass.init(dataNode, docklet);
- }
-
- this.docklets = [];
- var docklet_cache = {}
- this.$add = function(dataNode, Lid, xmlParentNode, htmlParentNode, beforeNode){
- //Build window
- var pHtmlNode = this.columns[this.applyRuleSetOnNode("column", dataNode) || 0];
- var docklet = new jpf.modalwindow(pHtmlNode);
- docklet.inherit(jpf.modalwindow.widget);
-
- docklet.parentNode = this;
- docklet.inherit(jpf.JmlDom);
- //this.applyRuleSetOnNode("border", xmlNode);
-
- var srcUrl = this.applyRuleSetOnNode("src", dataNode) || "file:"
- + this.applyRuleSetOnNode("url", dataNode);
-
- if (docklet_cache[srcUrl]) {
- var xmlNode = docklet_cache[srcUrl];
- if (jpf.isSafariOld)
- xmlNode = jpf.getJmlDocFromString(xmlNode).documentElement;
- createDocklet(xmlNode, docklet, dataNode);
- }
- else {
- jpf.setModel(srcUrl, {
- load: function(xmlNode){
- if (!xmlNode || this.isLoaded)
- return;
-
- //hmmm this is not as optimized as I'd like (going throught the xml parser twice)
- var strXml = xmlNode.xml || xmlNode.serialize();
-
- if (jpf.isSafariOld) {
- strXml = strXml.replace(/name/, "name='"
- + xmlNode.getAttribute("name") + "'");
- docklet_cache[srcUrl] = strXml;
- }
- else {
- xmlNode = jpf.getJmlDocFromString(strXml).documentElement;
- docklet_cache[srcUrl] = xmlNode.cloneNode(true);
- }
-
- createDocklet(xmlNode, docklet, dataNode);
- this.isLoaded = true;
- },
-
- setModel: function(model, xpath){
- model.register(this, xpath);
- }
- });
- }
- };
-
- this.$fill = function(){
- };
-
- this.addEventListener("xmlupdate", function(e){
- if (e.action.match(/add|insert|move/)) {
- jpf.JmlParser.parseLastPass();
- }
- });
-
- this.$selectDefault = function(xmlNode){
- if (this.select(this.getFirstTraverseNode(xmlNode)))
- return true;
- else {
- var nodes = this.getTraverseNodes(xmlNode);
- for(var i = 0; i < nodes.length; i++) {
- if (this.$selectDefault(nodes[i]))
- return true;
- }
- }
- };
-
- var totalWidth = 0;
- this.columns = [];
- this.addColumn = function(size){
- this.$getNewContext("column");
- var col = jpf.xmldb.htmlImport(this.$getLayoutNode("column"), this.oInt);
- var id = this.columns.push(col) - 1;
-
- //col.style.left = totalWidth + (size.match(/%/) ? "%" : "px");
- totalWidth += parseFloat(size);
-
- col.style.width = size + (size.match(/%|px|pt/) ? "" : "px");//"33.33%";
- col.isColumn = true;
- col.host = this;
- };
-
- /**** Init ****/
-
- this.$draw = function(){
- //Build Main Skin
- this.oExt = this.$getExternal();
- this.oInt = this.$getLayoutNode("main", "container", this.oExt);
-
- /**
- * @attribute {String} columns a comma seperated list of column sizes.
- * A column size can be specified in a number (size in pixels) or using
- * a number and a % sign to indicate a percentage.
- * Defaults to "33%, 33%, 33%".
- * Example:
- * <code>
- * <j:portal columns="25%, 50%, 25%">
- * ...
- * </j:portal>
- * </code>
- */
- var cols = (this.$jml.getAttribute("columns") || "33.33%,33.33%,33.33%").split(",");
- for (var i = 0; i < cols.length; i++) {
- this.addColumn(cols[i]);
- }
-
- //if(this.$jml.childNodes.length) this.$loadInlineData(this.$jml);
- jpf.JmlParser.parseChildren(this.$jml, null, this);
-
- if (document.elementFromPointAdd)
- document.elementFromPointAdd(this.oExt);
- };
-
- this.$loadJml = function(x){
-
- };
-}).implement(
- jpf.Cache,
- jpf.Presentation,
- jpf.MultiSelect,
- jpf.DataBinding
-);
-
-/**
- * @constructor
- */
-jpf.portal.docklet = function(){
- this.init = function(xmlSettings, oWidget){
- this.xmlSettings = xmlSettings
- this.oWidget = oWidget;
-
- if (this.$init)
- this.$init(xmlSettings, oWidget);
- };
-};
-
- - -/*FILEHEAD(/var/lib/jpf/src/elements/caldropdown.js)SIZE(-1077090856)TIME(1238944817)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-/**
- * Element displaying a list of day numbers in a grid, ordered by week. It
- * allows the user to choose the month and year for which to display the days.
- * Calendar returns a date in chosen date format. Minimal size of calendar is
- * 150px.
- *
- * @constructor
- * @define caldropdown
- * @addnode elements
- *
- * @author Lukasz Lipinski
- * @version %I%, %G%
- * @since 1.0
- *
- * @inherits jpf.Presentation
- * @inherits jpf.DataBinding
- * @inherits jpf.Validation
- * @inherits jpf.XForms
- *
- * @binding value Determines the way the value for the element is retrieved
- * from the bound data.
- *
- * @attribute {String} output-format style of returned date
- * @attribute {String} caption-format style of displayed date, default yyyy-mm-dd
- * @attribute {String} default the name which represent some date
- * Possible values:
- * today calendar is set on today's date
- * @attribute {String} value the date returned by calendar; should be in the
- * same format as output-format
- *
- * @event slidedown Fires when the calendar slides open.
- * cancellable: Prevents the calendar from sliding open
- * @event slideup Fires when the calendar slides up.
- * cancellable: Prevents the calendar from sliding up
- *
- * Example:
- * Calendar component with date set on "Saint Nicholas Day" in iso date format
- * <code>
- * <j:caldropdown top="200" left="400" output-format="yyyy-mm-dd" value="2008-12-06"></j:caldropdown>
- * </code>
- *
- * Example:
- * Sets the date based on data loaded into this component.
- * <code>
- * <j:caldropdown>
- * <j:bindings>
- * <j:value select="@date" />
- * </j:bindings>
- * </j:caldropdown>
- * </code>
- *
- * Example:
- * A shorter way to write this is:
- * <code>
- * <j:caldropdown ref="@date" />
- * </code>
- */
-jpf.caldropdown = jpf.component(jpf.NODE_VISIBLE, function() {
- this.$animType = 1;
- this.$animSteps = 5;
- this.$animSpeed = 20;
- this.$itemSelectEvent = "onmouseup";
-
- /**** Properties and Attributes ****/
-
- this.dragdrop = false;
- this.reselectable = true;
- this.$focussable = true;
- this.autoselect = false;
- this.multiselect = false;
-
- this.outputFormat = null;
- this.captionFormat = "yyyy-mm-dd";
-
- this.sliderHeight = 0;
-
- var _day = null,
- _month = null,
- _year = null,
- _hours = 1,
- _minutes = 0,
- _seconds = 0,
- _currentMonth = null,
- _currentYear = null,
- _numberOfDays = null,
- _dayNumber = null,
-
- _temp = null;
-
- var days = ["Sunday", "Monday", "Tuesday", "Wednesday",
- "Thursday", "Friday", "Saturday"];
- var months = [{name : "January", number : 31},
- {name : "February", number : 28},
- {name : "March", number : 31},
- {name : "April", number : 30},
- {name : "May", number : 31},
- {name : "June", number : 30},
- {name : "July", number : 31},
- {name : "August", number : 31},
- {name : "September", number : 30},
- {name : "October", number : 31},
- {name : "November", number : 30},
- {name : "December", number : 31}];
-
- var _self = this; //NOT USED
-
- this.$supportedProperties.push("initial-message", "output-format",
- "default", "caption-format", "value");
-
- /**
- * @attribute {String} initial-message the message displayed by this element
- * when it doesn't have a value set. This property is inherited from parent
- * nodes. When none is found it is looked for on the appsettings element.
- */
- this.$propHandlers["initial-message"] = function(value) {
- this.initialMsg = value
- || jpf.xmldb.getInheritedAttribute(this.$jml, "intial-message");
- };
-
- /**
- * @attribute {String} style of returned date
- *
- * recognized masks:
- * d day of the month as digits, no leading zero for single-digit days
- * dd day of the month as digits, leading zero for single-digit days
- * ddd day of the week as a three-letter abbreviation
- * dddd day of the week as its full name
- * m month as digits, no leading zero for single-digit months
- * mm month as digits, leading zero for single-digit months
- * mmm month as a three-letter abbreviation
- * mmmm month as its full name
- * yy year as last two digits, leading zero for years less than 2010
- * yyyy year represented by four digits
- * h hours, no leading zero for single-digit hours (12-hour clock)
- * hh hours, leading zero for single-digit hours (12-hour clock)
- * H hours, no leading zero for single-digit hours (24-hour clock)
- * HH hours, leading zero for single-digit hours (24-hour clock)
- * M minutes, no leading zero for single-digit minutes
- * MM minutes, leading zero for single-digit minutes
- * s seconds, no leading zero for single-digit seconds
- * ss seconds, leading zero for single-digit seconds
- */
- this.$propHandlers["output-format"] = function(value) {
- if (this.value) {
- this.setProperty("value", new Date(_year, _month, _day, _hours,
- _minutes, _seconds).format(this.outputFormat = value));
- }
- else
- this.outputFormat = value;
- }
-
- /**
- * @attribute {String} style of returned date
- *
- * recognized masks:
- * d day of the month as digits, no leading zero for single-digit days
- * dd day of the month as digits, leading zero for single-digit days
- * ddd day of the week as a three-letter abbreviation
- * dddd day of the week as its full name
- * m month as digits, no leading zero for single-digit months
- * mm month as digits, leading zero for single-digit months
- * mmm month as a three-letter abbreviation
- * mmmm month as its full name
- * yy year as last two digits, leading zero for years less than 2010
- * yyyy year represented by four digits
- * h hours, no leading zero for single-digit hours (12-hour clock)
- * hh hours, leading zero for single-digit hours (12-hour clock)
- * H hours, no leading zero for single-digit hours (24-hour clock)
- * HH hours, leading zero for single-digit hours (24-hour clock)
- * M minutes, no leading zero for single-digit minutes
- * MM minutes, leading zero for single-digit minutes
- * s seconds, no leading zero for single-digit seconds
- * ss seconds, leading zero for single-digit seconds
- */
- this.$propHandlers["caption-format"] = function(value) {
- if (this.value) {
- this.$setLabel(new Date(_year, _month, _day, _hours,
- _minutes, _seconds).format(this.captionFormat = value));
- }
- else
- this.captionFormat = value;
- }
-
- this.$propHandlers["value"] = function(value) {
- if (!this.outputFormat) {
- _temp = value;
- jpf.console.info("return: "+value+" "+this.outputFormat);
- return;
- }
-
- if (!value) {
- this.$setLabel();
- return;
- }
-
- var date = Date.parse(value, this.outputFormat);
-
- if (!date || !date.getFullYear()) {
- throw new Error(jpf.formErrorString(this, "Parsing date",
- "Invalid date: " + value));
- }
-
- _day = date.getDate();
- _month = date.getMonth();
- _year = date.getFullYear();
- _hours = date.getHours();
- _minutes = date.getMinutes();
- _seconds = date.getSeconds();
-
- this.value = value;
- this.$setLabel(new Date(_year, _month, _day, _hours,
- _minutes, _seconds).format(this.captionFormat));
- this.redraw(_month, _year);
- }
-
- /**
- * @method
- *
- * @return {String} date indicated by calendar
- */
- this.getValue = function(){
- return this.value;
- }
-
- /**
- * @method Sets calendar date
- */
- this.setValue = function(value){
- this.setProperty("value", value);
- }
-
- /**** Keyboard Handling ****/
-
- this.addEventListener("keydown", function(e) {
- e = e || event;
-
- var key = e.keyCode,
- ctrlKey = e.ctrlKey,
- shiftKey = e.shiftKey;
-
- switch (key) {
- case 13: /* enter */
- this.selectDay(_day);
- this.slideUp();
- break;
-
- case 33: /* page up */
- this.nextMonth();
- break;
-
- case 34: /* page down */
- this.prevMonth();
- break;
-
- case 37: /* left arrow */
- if (ctrlKey)
- this.prevMonth();
- else if (shiftKey)
- this.prevYear();
- else {
- if (_day - 1 < 1) {
- this.prevMonth();
- this.selectDay(months[_currentMonth].number);
- }
- else {
- this.selectDay(_day - 1);
- }
- }
- break;
-
- case 38: /* up arrow */
- if (ctrlKey)
- this.slideUp();
- else {
- if (_day - 7 < 1) {
- this.prevMonth();
- this.selectDay(months[_currentMonth].number + _day - 7);
- }
- else {
- this.selectDay(_day - 7);
- }
- }
- break;
-
- case 39: /* right arrow */
- if (ctrlKey)
- this.nextMonth();
- else if (shiftKey)
- this.nextYear();
- else
- this.selectDay(_day + 1);
- break;
-
- case 40: /* down arrow */
- if (ctrlKey)
- this.slideDown(e);
- else
- this.selectDay(_day + 7);
- break;
-
- case 84:
- if (ctrlKey)
- this.today();
- return false;
- break;
- }
- }, true);
-
- /**** Public methods ****/
-
- /**
- * Toggles the visibility of the container with the calendar. It opens
- * or closes it using a slide effect.
- */
- this.slideToggle = function(e) {
- if (!e) e = event;
-
- if (this.isOpen)
- this.slideUp();
- else
- this.slideDown(e);
- };
-
- /**
- * Shows the container with the list elements using a slide effect.
- */
- this.slideDown = function(e) {
-
- if (this.dispatchEvent("slidedown") === false)
- return false;
-
- this.isOpen = true;
-
- this.oSlider.style.display = "block";
- this.oSlider.style[jpf.supportOverflowComponent
- ? "overflowY"
- : "overflow"] = "hidden";
-
- this.oSlider.style.display = "";
- this.$setStyleClass(this.oExt, this.baseCSSname + "Down");
-
- this.oSlider.style.height = (this.sliderHeight > 0
- ? this.sliderHeight - 1
- : 0) + "px";
-
- this.oSlider.style.width = (this.oExt.offsetWidth > 0
- ? this.oExt.offsetWidth - 1
- : 0) + "px";
-
- jpf.caldropdown.cache["oSlider"].host = this;
-
- this.redraw(_month, _year);
-
- jpf.popup.show(this.uniqueId, {
- x : 0,
- y : this.oExt.offsetHeight,
- animate : true,
- ref : this.oExt,
- width : this.oExt.offsetWidth + 1,
- height : this.sliderHeight,
- callback: function(container) {
- container.style[jpf.supportOverflowComponent
- ? "overflowY"
- : "overflow"] = "hidden";
- }
- });
- };
-
- /**
- * Hides the container with the calendar using a slide effect.
- */
- this.slideUp = function() {
- if (this.isOpen == 2) return false;
- if (this.dispatchEvent("slideup") === false) return false;
-
- this.isOpen = false;
- if (this.selected) {
- var htmlNode = jpf.xmldb.findHTMLNode(this.selected, this);
- if (htmlNode) this.$setStyleClass(htmlNode, '', ["hover"]);
- }
-
- this.$setStyleClass(this.oExt, '', [this.baseCSSname + "Down"]);
- jpf.popup.hide();
- return false;
- };
-
- /**** Private methods and event handlers ****/
-
- this.$setLabel = function(value) {
- this.oLabel.innerHTML = value || this.initialMsg || "";
-
- this.$setStyleClass(this.oExt, value ? "" : this.baseCSSname + "Initial",
- [!value ? "" : this.baseCSSname + "Initial"]);
- };
-
- this.addEventListener("afterselect", function(e) {
- if (!e) e = event;
-
- this.slideUp();
- if (!this.isOpen)
- this.$setStyleClass(this.oExt, "", [this.baseCSSname + "Over"]);
-
- this.$setLabel(this.applyRuleSetOnNode("value", this.selected))
-
- this.$updateOtherBindings();
-
- if (this.hasFeature(__VALIDATION__) && this.form) {
- this.validate(true);
- }
- });
-
- this.addEventListener("afterdeselect", function() {
- this.$setLabel("");
- });
-
- function setMaxCount() {
- if (this.isOpen == 2)
- this.slideDown();
- }
-
- //For MultiBinding
- this.$showSelection = function(value) {
- //Set value in Label
- var bc = this.$getMultiBind();
-
- //Only display caption when a value is set
- if (value === undefined) {
- var sValue2,
- sValue = bc.applyRuleSetOnNode("value", bc.xmlRoot, null, true);
- if (sValue)
- sValue2 = bc.applyRuleSetOnNode("caption", bc.xmlRoot, null, true);
-
- if (!sValue2 && this.xmlRoot && sValue) {
- var rule = this.getBindRule(this.mainBind).getAttribute("select");
-
- var xpath = this.traverse + "[" + rule + "='"
- + sValue.replace(/'/g, "\\'") + "']";
-
- var xmlNode = this.xmlRoot.selectSingleNode(xpath);
- value = this.applyRuleSetOnNode("caption", xmlNode);
- }
- else {
- value = sValue2 || sValue;
- }
- }
- };
-
- //I might want to move this method to the MultiLevelBinding baseclass
- this.$updateOtherBindings = function() {
- if (!this.multiselect) {
- // Set Caption bind
- var bc = this.$getMultiBind(), caption;
- if (bc && bc.xmlRoot && (caption = bc.bindingRules["caption"])) {
- var xmlNode = jpf.xmldb.createNodeFromXpath(bc.xmlRoot,
- bc.bindingRules["caption"][0].getAttribute("select"));
- if (!xmlNode)
- return;
-
- jpf.xmldb.setNodeValue(xmlNode,
- this.applyRuleSetOnNode("caption", this.selected));
- }
- }
- };
-
- // Private functions
- this.$blur = function() {
- this.slideUp();
- //this.oExt.dispatchEvent("mouseout")
- if (!this.isOpen)
- this.$setStyleClass(this.oExt, "", [this.baseCSSname + "Over"])
- //if(this.oExt.onmouseout) this.oExt.onmouseout();
-
- this.$setStyleClass(this.oExt, "", [this.baseCSSname + "Focus"]);
- };
-
- this.$focus = function(){
- jpf.popup.forceHide();
- this.$setStyleClass(this.oFocus || this.oExt, this.baseCSSname + "Focus");
- }
-
- this.$setClearMessage = function(msg) {
- if (msg) {
- this.$setLabel(msg);
- }
- };
-
- this.$removeClearMessage = function() {
- this.$setLabel("");
- };
-
- this.addEventListener("slidedown", function() {
- //THIS SHOULD BE UPDATED TO NEW SMARTBINDINGS
- if (!this.form || !this.form.xmlActions || this.xmlRoot)
- return;
- var loadlist = this.form.xmlActions
- .selectSingleNode("LoadList[@element='" + this.name + "']");
- if (!loadlist) return;
-
- this.isOpen = 2;
- this.form.processLoadRule(loadlist, true, [loadlist]);
-
- return false;
- });
-
- this.addEventListener("popuphide", this.slideUp);
-
- var isLeapYear = function(year) {
- return ((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0)
- ? true
- : false;
- };
-
- this.redraw = function(month, year) {
- _currentMonth = month;
- _currentYear = year;
- var _width = this.oExt.offsetWidth;
-
- var temp = Math.floor((_width - 36) / 8) * 8 + 32 - jpf.getDiff(this.oNavigation)[0];
-
- if (temp >= 0)
- this.oNavigation.style.width = temp + "px";
-
- //var w_firstYearDay = new Date(year, 0, 1);
- //var w_dayInWeek = w_firstYearDay.getDay();
- var w_days = new Date(year, 0, 1).getDay();
-
- for (i = 0; i <= month; i++) {
- if (isLeapYear(year) && i == 1)
- w_days++;
- w_days += months[i].number;
- }
-
- var w_weeks = Math.ceil(w_days / 7),
- date = new Date(year, month);
-
- _numberOfDays = months[date.getMonth()].number;
- if (isLeapYear(year) && date.getMonth() == 1)
- _numberOfDays++;
-
- _dayNumber = new Date(year, month, 1).getDay();
- var prevMonth = month == 0 ? 11 : month - 1,
- prevMonthDays = months[prevMonth].number - _dayNumber + 1,
- nextMonthDays = 1,
- rows = this.oNavigation.childNodes,
- cells,
- y;
-
- for (i = 0; i < rows.length; i++) {
- if ((rows[i].className || "").indexOf("today") != -1) {
- if (_width < 300) {
- rows[i].innerHTML = "T";
- rows[i].style.width = "8px";
- }
- else {
- rows[i].innerHTML = "Today";
- rows[i].style.width = "32px";
- }
- }
- else if ((rows[i].className || "").indexOf("status") != -1) {
- if (_width >= 300)
- rows[i].innerHTML = months[_currentMonth].name
- + " " + _currentYear;
- else {
- rows[i].innerHTML = (_currentMonth + 1) + "/" + _currentYear;
- }
- }
- }
-
- this.sliderHeight = 22; //navigators bar height
- temp = Math.floor((_width - 37) / 8);
- var squareSize = temp > 0 ? temp : 0;
-
- var daysofweek = this.oDow.childNodes,
- d_height = Math.floor(squareSize / 4 + 6),
- d_paddingTop = Math.floor(squareSize / 4 - 8) > 0
- ? Math.floor(squareSize / 4 - 8)
- : 0,
- d_fontSize = _width <= 220 ? "9px" : "11px",
- d_width = (squareSize * 8 + 32);
-
-
- this.oDow.style.width = d_width + "px";
-
- this.sliderHeight += d_height + d_paddingTop;
-
- for (var z = 0, i = 0; i < daysofweek.length; i++) {
- if ((daysofweek[i].className || "").indexOf("dayofweek") > -1) {
- daysofweek[i].style.width = squareSize + "px";
- daysofweek[i].style.height = d_height + "px";
- daysofweek[i].style.paddingTop = d_paddingTop + "px";
- daysofweek[i].style.fontSize = d_fontSize;
-
- if (z > 0) {
- daysofweek[i].innerHTML = days[z - 1].substr(0, 3);
- }
- z++;
- }
- }
-
- var c_height = Math.floor((squareSize + 12) / 2);
- var c_paddingTop = squareSize - c_height > 0
- ? squareSize - c_height
- : 0;
-
- rows = this.oSlider.childNodes;
- for (z = 0, y = 0, i = 0; i < rows.length; i++) {
- if ((rows[i].className || "").indexOf("row") == -1)
- continue;
-
- rows[i].style.width = (d_width - jpf.getDiff(rows[i])[0]) + "px";
- if (!jpf.isGecko) {
- rows[i].style.paddingTop = "1px";
- }
-
- this.sliderHeight += (squareSize + 5);
-
- cells = rows[i].childNodes;
- for (var j = 0, disabledRow = 0; j < cells.length; j++) {
- if ((cells[j].className || "").indexOf("cell") == -1)
- continue;
- z++;
- cells[j].style.width = squareSize + "px";
- cells[j].style.height = c_height + "px";
- cells[j].style.paddingTop = c_paddingTop + "px";
-
- cells[j].style.margin = z%8 == 0 && z !== 1
- ? "1px 0 1px 0"
- : "1px 2px 1px 0";
-
- this.$setStyleClass(cells[j], "", ["weekend", "disabled",
- "active", "prev", "next"]);
-
- if ((z - 1) % 8 == 0) {
- cells[j].innerHTML = w_weeks
- - Math.ceil((months[_month].number + _dayNumber) / 7)
- + 1 + (z - 1) / 8;
- }
- else {
- y++;
- if (y <= _dayNumber) {
- cells[j].innerHTML = prevMonthDays++;
- this.$setStyleClass(cells[j], "disabled prev");
- }
- else if (y > _dayNumber && y <= _numberOfDays + _dayNumber) {
- cells[j].innerHTML = y - _dayNumber;
-
- var dayNrWeek = new Date(year, month,
- y - _dayNumber).getDay();
-
- if (dayNrWeek == 0 || dayNrWeek == 6) {
- this.$setStyleClass(cells[j], "weekend");
- }
-
- if (month == _month && year == _year
- && y - _dayNumber == _day) {
- this.$setStyleClass(cells[j], "active");
- }
- }
- else if (y > _numberOfDays + _dayNumber) {
- cells[j].innerHTML = nextMonthDays++;
- this.$setStyleClass(cells[j], "disabled next");
- disabledRow++;
- }
- }
- }
-
- rows[i].style.visibility = disabledRow == 7
- ? "hidden"
- : "visible";
- }
- };
-
- /**
- * Change choosen date with selected and highlight its cell on calendar
- * component
- *
- * @param {Number} nr day number
- * @param {String} type class name of html representation of selected cell
- */
- this.selectDay = function(nr, type) {
- var newMonth = type == "prev"
- ? _currentMonth
- : (type == "next"
- ? _currentMonth + 2
- : _currentMonth + 1);
-
- var newYear = _currentYear;
-
- if (newMonth < 1) {
- newMonth = 12;
- newYear--;
- }
- else if (newMonth > 12) {
- newMonth = 1;
- newYear++;
- }
-
- this.change(new Date(newYear, (newMonth - 1), nr, _hours,
- _minutes, _seconds).format(this.outputFormat));
- };
-
- /**
- * Change displayed year to next
- */
- this.nextYear = function() {
- this.redraw(_currentMonth, _currentYear + 1);
- };
-
- /**
- * Change displayed year to previous
- */
- this.prevYear = function() {
- this.redraw(_currentMonth, _currentYear - 1);
- };
-
- /**
- * Change displayed month to next. If actual month is December, function
- * change current displayed year to next
- */
- this.nextMonth = function() {
- var newMonth, newYear;
- if (_currentMonth > 10) {
- newMonth = 0;
- newYear = _currentYear + 1;
- }
- else {
- newMonth = _currentMonth + 1;
- newYear = _currentYear;
- }
-
- this.redraw(newMonth, newYear);
- };
-
- /**
- * Change displayed month to previous. If actual month is January, function
- * change current displayed year to previous
- */
- this.prevMonth = function() {
- var newMonth, newYear;
- if (_currentMonth < 1) {
- newMonth = 11;
- newYear = _currentYear - 1;
- }
- else {
- newMonth = _currentMonth - 1;
- newYear = _currentYear;
- }
-
- this.redraw(newMonth, newYear);
- };
-
- /**
- * Select today's date on calendar component
- */
- this.today = function() {
- //this.setProperty("value", new Date().format(this.outputFormat));
- this.change(new Date().format(this.outputFormat));
- };
-
- /**** Init ****/
-
- this.$draw = function() {
- this.$getNewContext("main");
- this.$getNewContext("container");
-
- this.$animType = this.$getOption("main", "animtype") || 1;
- this.clickOpen = this.$getOption("main", "clickopen") || "button";
-
- //Build Main Skin
- this.oExt = this.$getExternal(null, null, function(oExt) {
- oExt.setAttribute("onmouseover",
- 'var o = jpf.lookup(' + this.uniqueId + ');\
- o.$setStyleClass(o.oExt, o.baseCSSname + "Over");');
- oExt.setAttribute("onmouseout",
- 'var o = jpf.lookup('+ this.uniqueId + ');\
- if (o.isOpen) return;\
- o.$setStyleClass(o.oExt, "", [o.baseCSSname + "Over"]);');
-
- //Button
- var oButton = this.$getLayoutNode("main", "button", oExt);
- if (oButton) {
- oButton.setAttribute("onmousedown",
- 'jpf.lookup(' + this.uniqueId + ').slideToggle(event);');
- }
-
- //Label
- var oLabel = this.$getLayoutNode("main", "label", oExt);
- if (this.clickOpen == "both") {
- oLabel.parentNode.setAttribute("onmousedown", 'jpf.lookup('
- + this.uniqueId + ').slideToggle(event);');
- }
- });
- this.oLabel = this.$getLayoutNode("main", "label", this.oExt);
-
- if (this.oLabel.nodeType == 3)
- this.oLabel = this.oLabel.parentNode;
-
- this.oIcon = this.$getLayoutNode("main", "icon", this.oExt);
- if (this.oButton)
- this.oButton = this.$getLayoutNode("main", "button", this.oExt);
-
- if (jpf.caldropdown.cache) {
- var cal = jpf.caldropdown.cache;
- this.oSlider = cal["oSlider"];
- this.oNavigation = cal["oNavigation"];
- this.oDow = cal["oDow"];
-
- jpf.caldropdown.cache.refcount++;
-
- //Set up the popup
- this.pHtmlDoc = jpf.popup.setContent(this.uniqueId, this.oSlider,
- jpf.skins.getCssString(this.skinName));
-
- return;
- }
-
- this.oSlider = this.$getExternal("container", null, function(oExt1) {
- var i, oSlider = this.$getLayoutNode("container", "contents", oExt1);
-
- for (i = 0; i < 6; i++) {
- this.$getNewContext("row");
- var oRow = oSlider.appendChild(this.$getLayoutNode("row"));
-
- for (var j = 0; j < 8; j++) {
- this.$getNewContext("cell");
- var oCell = this.$getLayoutNode("cell");
- if (j > 0) {
- oCell.setAttribute("onmouseout",
- "jpf.setStyleClass(this, '', ['hover']);");
- oCell.setAttribute("onmouseover",
- "if (this.className.indexOf('disabled') > -1 \
- || this.className.indexOf('active') > -1) \
- return;\
- jpf.setStyleClass(this, 'hover');");
- oCell.setAttribute("onmousedown",
- "var o = jpf.findHost(this);\
- if (this.className.indexOf('prev') > -1) \
- o.selectDay(this.innerHTML, 'prev');\
- else if (this.className.indexOf('next') > -1) \
- o.selectDay(this.innerHTML, 'next');\
- else \
- o.selectDay(this.innerHTML);\
- o.slideUp();");
- }
- oRow.appendChild(oCell);
- }
- }
-
- var oNavigation = this.$getLayoutNode("container", "navigation",
- oExt1);
-
- if (oNavigation) {
- var buttons = ["prevYear", "prevMonth", "nextYear", "nextMonth",
- "today", "status"];
- for (i = 0; i < buttons.length; i++) {
- this.$getNewContext("button");
- var btn = oNavigation.appendChild(this.$getLayoutNode("button"));
- this.$setStyleClass(btn, buttons[i]);
- if (buttons[i] !== "status") {
- btn.setAttribute("onmousedown", 'jpf.findHost(this).' + buttons[i] + '()');
- btn.setAttribute("onmouseover", 'jpf.setStyleClass(this, "hover");');
- btn.setAttribute("onmouseout", 'jpf.setStyleClass(this, "", ["hover"]);');
- }
- }
- }
-
- var oDaysOfWeek = this.$getLayoutNode("container",
- "daysofweek", oExt1);
-
- for (i = 0; i < days.length + 1; i++) {
- this.$getNewContext("day");
- oDaysOfWeek.appendChild(this.$getLayoutNode("day"));
- }
- });
-
- this.oNavigation = this.$getLayoutNode("container", "navigation", this.oSlider);
- this.oDow = this.$getLayoutNode("container", "daysofweek", this.oSlider);
-
- //Set up the popup
- this.pHtmlDoc = jpf.popup.setContent(this.uniqueId, this.oSlider,
- jpf.skins.getCssString(this.skinName));
-
- document.body.appendChild(this.oSlider);
-
- //Get Options form skin
- //Types: 1=One dimensional List, 2=Two dimensional List
- this.listtype = parseInt(this.$getLayoutNode("main", "type")) || 1;
-
- if (this.$jml.childNodes.length)
- this.$loadInlineData(this.$jml);
-
- if (!jpf.caldropdown.cache) {
- jpf.caldropdown.cache = {
- "oSlider" : this.oSlider,
- "oNavigation" : this.oNavigation,
- "oDow" : this.oDow
- };
- jpf.caldropdown.cache.refcount = 0;
- }
- };
-
- this.$loadJml = function(x) {
- var date;
- if (typeof this.value == "undefined") {
- switch(this["default"]) {
- case "today":
- this.setProperty("value", new Date().format(this.outputFormat));
- break;
- default :
- date = new Date();
- _day = 0;
- _month = date.getMonth();
- _year = date.getFullYear();
-
-// if (!this.selected && this.initialMsg)
- this.$setLabel();
- break;
- }
- }
- else {
- date = Date.parse(_temp || this.value, this.outputFormat);
- _day = date.getDate();
- _month = date.getMonth();
- _year = date.getFullYear();
-
- this.setProperty("value", new Date(_year, _month, _day, _hours,
- _minutes, _seconds).format(this.outputFormat));
- }
- };
-
- this.$destroy = function() {
- jpf.popup.removeContent(this.uniqueId);
- jpf.removeNode(this.oSlider);
- this.oSlider = null;
-
- if (jpf.caldropdown.cache.refcount == 0) {
- jpf.caldropdown.cache = null;
- }
- else {
- jpf.caldropdown.cache.refcount--;
- }
- };
-}).implement(
- jpf.DataBinding,
- jpf.Validation,
- jpf.Presentation
-);
-
- - -/*FILEHEAD(/var/lib/jpf/src/elements/menu.js)SIZE(-1077090856)TIME(1238950356)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - -/** - * Element displaying a skinnable menu of items which can be choosen. - * Based on the context of the menu, items can be shown and hidden. That's - * why this element is often called a contextmenu. - * Example: - * <code> - * <j:iconmap id="tbicons" src="toolbar.icons.gif" - * type="horizontal" size="20" offset="2,2"></j:iconmap> - * - * <j:menu id="msub"> - * <j:item icon="tbicons:12">test</j:item> - * <j:item icon="tbicons:14">test2</j:item> - * </j:menu> - * - * <j:menu id="mmain"> - * <j:item icon="tbicons:1">table_wizard</j:item> - * <j:item icon="tbicons:2" hotkey="Ctrl+M">table_wizard</j:item> - * <j:divider></j:divider> - * <j:radio>item 1</j:radio> - * <j:radio>item 2</j:radio> - * <j:radio>item 3</j:radio> - * <j:radio>item 4</j:radio> - * <j:divider></j:divider> - * <j:check hotkey="Ctrl+T">item check 1</j:check> - * <j:check hotkey="F3">item check 2</j:check> - * <j:divider></j:divider> - * <j:item icon="tbicons:11" submenu="msub">table_wizard</j:item> - * <j:item icon="tbicons:10">table_wizard</j:item> - * </j:menu> - * - * <j:window contextmenu="mmain"> - * ... - * </j:window> - * </code> - * @see baseclass.jmlelement.event.contextmenu - * - * @event display Fires when the contextmenu is shown. - * @event itemclick Fires when a user presses the mouse button while over a child of this element. - * object: - * {String} value the value of the clicked element. - * - * @constructor - * @define menu - * @allowchild item, divider, check, radio - * @addnode elements - * - * @author Ruben Daniels - * @version %I%, %G% - * @since 0.4 - * - * @inherits jpf.Presentation - */ -jpf.menu = jpf.component(jpf.NODE_VISIBLE, function(){ - this.$focussable = jpf.KEYBOARD; - this.$positioning = "basic" - var _self = this; - var blurring = false; - - /**** Properties and Attributes ****/ - - this.zindex = 10000000; - - this.$propHandlers["visible"] = function(value, nofocus, hideOpener){ - if (value) { - this.oExt.style.display = "block"; - } - else { - this.oExt.style.display = "none"; - - //Ah oui, c'est tres difficile - - var lastFocus = jpf.menu.lastFocus; - - //@todo test this with a list being the opener of the menu - if (lastFocus != this.opener && this.opener && this.opener.$blur) - this.opener.$blur(); - - if (this.opener && this.opener.parentNode.tagName == "menu") { - if (!this.$hideTree) - this.$hideTree = -1 - this.opener.parentNode.focus(); - } - - else if (lastFocus) { - //We're being hidden because some other object gets focus - if (jpf.window.$settingFocus) { - if (jpf.window.$settingFocus != lastFocus && lastFocus.$blur) - lastFocus.$blur(); - this.$blur(); - - if (jpf.window.$settingFocus.tagName != "menu") //not menu walking - jpf.menu.lastFocus = null; - } - //We're being hidden because window looses focus - else if (!jpf.window.hasFocus()) { - if (lastFocus.$blur) - lastFocus.$blur(); - this.$blur(); - - jpf.window.focussed = lastFocus; - if (lastFocus.$focusParent) - lastFocus.$focusParent.$lastFocussed = lastFocus; - - jpf.menu.lastFocus = null; - } - //We're just being hidden - else if (this.$hideTree) { - if (!this.$hideTree) - this.$hideTree = -1 - - var visTest = (lastFocus.disabled || !lastFocus.visible) - && lastFocus != jpf.document.documentElement; - - if (nofocus || visTest) { - if (lastFocus.$blur) - lastFocus.$blur(); - this.$blur(); - jpf.window.focussed = null; - - if (visTest && jpf.window.moveNext() === false) - jpf.window.$focusRoot(); - } - else { - lastFocus.focus(null, null, true); - } - - jpf.menu.lastFocus = null; - } - } - - if (this.$showingSubMenu) { - this.$showingSubMenu.hide(); - this.$showingSubMenu = null; - } - - if (this.opener && this.opener.$submenu) { - this.opener.$submenu(true, true); - - //@todo problem with loosing focus when window looses focus - if (this.$hideTree === true && this.opener.parentNode.tagName == "menu") { - this.opener.parentNode.$hideTree = true - this.opener.parentNode.hide(); - } - - this.opener = null; - } - this.$hideTree = null; - - if (this.$selected) { - jpf.setStyleClass(this.$selected.oExt, "", ["hover"]); - this.$selected = null; - } - } - }; - - /**** Public Methods ****/ - - var lastFocus; - - /** - * Shows the menu, optionally within a certain context. - * @param {Number} x the left position of the menu. - * @param {Number} y the top position of the menu. - * @param {Boolean} noanim whether to animate the showing of this menu. - * @param {JMLElement} opener the element that is the context of this menu. - * @param {XMLElement} xmlNode the xml data element that provides data context to the menu child nodes. - * @see baseclass.jmlelement.event.contextmenu - */ - this.display = function(x, y, noanim, opener, xmlNode, openMenuId, btnWidth){ - this.opener = opener; - this.dispatchEvent("display"); - - //Show / hide Child Nodes Based on XML - var c = 0, last, d = 0, i, node, nodes = this.childNodes; - var l = nodes.length - for (i = 0; i < l; i++) { - node = nodes[i]; - - if (!node.select || !xmlNode - || xmlNode.selectSingleNode(node.select)) { - node.show(); - - if (node.tagName == "divider") { - last = node; - if (c == 0) - node.hide(); - c = 0; - } - else c++; - } - else { - node.hide(); - - if (!node.nextSibling && c == 0) - last.hide(); - } - } - - if (this.oOverlay) { - if (btnWidth) { - this.oOverlay.style.display = "block"; - this.oOverlay.style.width = btnWidth + "px"; - } - else - this.oOverlay.style.display = "none"; - } - - this.visible = false; - this.show(); - jpf.popup.show(this.uniqueId, { - x : x, - y : y, - animate : noanim ? false : "fade", - ref : document.documentElement, - allowTogether: openMenuId - }); - - var lastFocus = - jpf.menu.lastFocus = opener && opener.$focussable === true - ? opener - : jpf.menu.lastFocus || jpf.window.focussed; - this.focus(); - - //Make the component that provides context appear to have focus - - if (lastFocus && lastFocus != this && lastFocus.$focus) - lastFocus.$focus(); - - this.xmlReference = xmlNode; - }; - - /** - * @copy Widget#getValue - */ - this.getValue = function(group){ - return this.getSelected(group).value || ""; - }; - - /** - * Retrieves the selected element from a group of radio elements. - * @param {String} group the name of the group. - * @return {radio} the selected radio element. - */ - this.getSelected = function(group){ - var nodes = this.childNodes; - var i, l = nodes.length; - for (i = 0; i < l; i++) { - if (nodes[i].group != group) - continue; - - if (nodes[i].selected) - return nodes[i]; - } - - return false; - } - - /** - * Selects an element within a radio group. - * @param {String} group the name of the group. - * @param {String} value the value of the item to select. - */ - this.select = function(group, value){ - var nodes = this.childNodes; - var i, l = nodes.length; - for (i = 0; i < l; i++) { - if (nodes[i].group != group) - continue; - - if (nodes[i].value == value || !nodes[i].value && nodes[i].caption == value) - nodes[i].$handlePropSet("selected", true); - else if (nodes[i].selected) - nodes[i].$handlePropSet("selected", false); - } - }; - - /**** Events ****/ - - this.addEventListener("keydown", function(e){ - var key = e.keyCode; - var ctrlKey = e.ctrlKey; - var shiftKey = e.shiftKey; - - switch (key) { - case 13: - if (!this.$selected) - return; - - var node = this.$selected; - node.$down(); - node.$up(); - node.$click(); - break; - case 38: - //UP - var node = this.$selected && this.$selected.previousSibling - || this.lastChild; - - if (node && node.tagName == "divider") - node = node.previousSibling; - - if (!node) - return; - - if (this.$selected) - jpf.setStyleClass(this.$selected.oExt, "", ["hover"]); - - jpf.setStyleClass(node.oExt, "hover"); - this.$selected = node; - break; - case 40: - //DOWN - var node = this.$selected && this.$selected.nextSibling - || this.firstChild; - - if (node && node.tagName == "divider") - node = node.nextSibling; - - if (!node) - return; - - if (this.$selected) - jpf.setStyleClass(this.$selected.oExt, "", ["hover"]); - - jpf.setStyleClass(node.oExt, "hover"); - this.$selected = node; - break; - case 37: - //LEFT - //if (this.$selected && this.$selected.submenu) - //this.$selected.$submenu(true, true); - - if (!this.opener) - return; - - if (this.opener.tagName == "button") { - var node = this.opener.previousSibling; - while(node && !node.submenu) { - node = node.previousSibling; - } - - if (node) { - node.dispatchEvent("mouseover"); - - var btnMenu = node.parentNode.menuIsPressed; - if (btnMenu) { - self[btnMenu.submenu].dispatchEvent("keydown", { - keyCode : 40 - }); - } - } - } - else if (this.opener.parentNode.tagName == "menu") { - //@todo Ahum bad abstraction boundary - var op = this.opener; - this.hide(); - jpf.setStyleClass(op.oExt, "hover"); - op.parentNode.$showingSubMenu = null; - } - - break; - case 39: - //RIGHT - if (this.$selected && this.$selected.submenu) { - this.$selected.$submenu(null, true); - this.$showingSubMenu.dispatchEvent("keydown", { - keyCode : 40 - }); - - return; - } - - if (this.opener) { - var op = this.opener; - while (op && op.parentNode && op.parentNode.tagName == "menu") - op = op.parentNode.opener; - - if (op && op.tagName == "button") { - var node = op.nextSibling; - while(node && !node.submenu) { - node = node.nextSibling; - } - - if (node) { - node.dispatchEvent("mouseover"); - - var btnMenu = node.parentNode.menuIsPressed; - if (btnMenu) { - self[btnMenu.submenu].dispatchEvent("keydown", { - keyCode : 40 - }); - } - - return; - } - } - } - - if (!this.$selected) { - arguments.callee.call(this, { - keyCode : 40 - }); - } - - break; - default: - return; - } - - return false; - }, true); - - //Hide menu when it looses focus or when the popup hides itself - function forceHide(){ - if (this.$showingSubMenu) - return; - - if (this.$hideTree != -1) { - this.$hideTree = true; - this.hide(); - } - - return false; - } - - this.addEventListener("focus", function(){ - jpf.popup.last = this.uniqueId; - }); - - this.addEventListener("blur", forceHide); - this.addEventListener("popuphide", forceHide); - - /**** Init ****/ - - this.$draw = function(){ - this.pHtmlNode = document.body; - - //Build Main Skin - this.oExt = this.$getExternal(); - this.oOverlay = this.$getLayoutNode("main", "overlay", this.oExt); - - jpf.popup.setContent(this.uniqueId, this.oExt, "", null, null); - }; - - this.$loadJml = function(x){ - var i, oInt = this.$getLayoutNode("main", "container", this.oExt); - - //Skin changing support - if (this.oInt) { - this.oInt = oInt; - - var node, nodes = this.childNodes; - for (i = 0; i < nodes.length; i++) { - node = nodes[i]; - node.loadJml(node.$jml); - } - } - else { - this.oInt = oInt; - - //Let's not parse our children, when we've already have them - if (this.childNodes.length) - return; - - //Build children - var node, nodes = this.$jml.childNodes; - var l = nodes.length; - for (i = 0; i < l; i++) { - node = nodes[i]; - if (node.nodeType != 1) continue; - - var tagName = node[jpf.TAGNAME]; - if ("item|radio|check".indexOf(tagName) > -1) { - new jpf.item(oInt, tagName).loadJml(node, this); - } - else if (tagName == "divider") { - new jpf.divider(oInt, tagName).loadJml(node, this); - } - else { - throw new Error(jpf.formatErrorString(0, this, - "Parsing children of menu component", - "Unknown component found as child of menu", node)); - } - } - } - }; - - this.$destroy = function(){ - jpf.popup.removeContent(this.uniqueId); - } -}).implement(jpf.Presentation); - -/** - * Item of a menu displaying a clickable area. - * @define item, check, radio - * @constructor - * - * @event click Fires when a user presses the mouse button while over this element. - * object: - * {String} value the value of the clicked element. - */ -jpf.radio = -jpf.check = -jpf.item = jpf.subnode(jpf.NODE_HIDDEN, function(){ - this.$focussable = false; - var _self = this; - - /**** Properties and Attributes ****/ - - this.$supportedProperties = ["submenu", "value", "select", "group", "icon", - "checked", "selected", "disabled", "caption"]; - - var lastHotkey; - this.$handlePropSet = function(prop, value, force){ - this[prop] = value; - - switch(prop){ - /** - * @attribute {String} [submenu] the id of the menu that is shown - * when the user hovers over this menu item. - * Example: - * <code> - * <j:menu id="msub"> - * <j:item icon="tbicons:12">test</j:item> - * <j:item icon="tbicons:14">test2</j:item> - * </j:menu> - * - * <j:menu id="mmain"> - * <j:item submenu="msub">Sub menu</j:item> - * </j:menu> - * </code> - */ - case "submenu": - jpf.setStyleClass(this.oExt, "submenu"); - break; - /** - * @attribute {String} value the value of this element. - */ - case "value": - break; - /** - * @attribute {String} [select] the xpath statement which works on the - * xml context of the parent menu element to determine whether this - * item is shown. - * Example: - * This example shows a list - * <code> - * <j:list> - * [...] - * - * <j:contextmenu menu="mnuXY" select="computer" /> - * <j:contextmenu menu="mnuTest" /> - * </j:list> - * - * <j:menu id="mnuTest"> - * <j:item select="person">Send an E-mail</j:Item> - * <j:item select="phone">Call Number</j:Item> - * <j:divider /> - * <j:item select="phone">Remove</j:Item> - * <j:divider /> - * <j:item select="person|phone">View Pictures</j:Item> - * </j:menu> - * - * <j:menu id="mnuXY"> - * <j:item>Reboot</j:Item> - * </j:menu> - * </code> - */ - case "select": - this.select = value - ? "self::" + value.split("|").join("|self::") - : value; - break; - /** - * @attribute {String} [group] the name of the group this item belongs - * to. - * Example: - * <code> - * <j:menu> - * <j:radio group="example">item 1</j:radio> - * <j:radio group="example">item 2</j:radio> - * <j:radio group="example">item 3</j:radio> - * <j:radio group="example">item 4</j:radio> - * </j:menu> - * </code> - */ - case "group": - break; - /** - * @attribute {String} hotkey the key combination a user can press - * to active the function of this element. Use any combination of - * Ctrl, Shift, Alt, F1-F12 and alphanumerical characters. Use a - * space, a minus or plus sign as a seperator. - * Example: - * <code> - * <j:item hotkey="Ctrl+Q">Quit</j:item> - * </code> - */ - case "hotkey": - if (this.oHotkey) - jpf.xmldb.setNodeValue(this.oHotkey, value); - - if (lastHotkey) - jpf.removeHotkey(lastHotkey); - - if (value) { - lastHotkey = value; - jpf.registerHotkey(value, function(){ - //hmm not very scalable... - var buttons = jpf.document.getElementsByTagName("button"); - for (var i = 0; i < buttons.length; i++) { - if (buttons[i].submenu == _self.parentNode.name) { - var btn = buttons[i]; - btn.$setState("Over", {}); - - setTimeout(function(){ - btn.$setState("Out", {}); - }, 200); - - break; - } - } - - _self.$down(); - _self.$up(); - _self.$click(); - }); - } - - break; - /** - * @attribute {String} icon the url of the image used as an icon or - * a reference to an iconmap. - */ - case "icon": - if (this.oIcon) - jpf.skins.setIcon(this.oIcon, value, this.parentNode.iconPath); - break; - /** - * @attribute {String} caption the text displayed on the item. - */ - case "caption": - jpf.xmldb.setNodeValue(this.oCaption, value); - break; - /** - * @attribute {Boolean} checked whether the item is checked. - */ - case "checked": - if (this.tagName != "check") - return; - - if (jpf.isTrue(value)) - jpf.setStyleClass(this.oExt, "checked"); - else - jpf.setStyleClass(this.oExt, "", ["checked"]); - break; - /** - * @attribute {Boolean} checked whether the item is selected. - */ - case "selected": - if (this.tagName != "radio") - return; - - if (jpf.isTrue(value)) - jpf.setStyleClass(this.oExt, "selected"); - else - jpf.setStyleClass(this.oExt, "", ["selected"]); - break; - /** - * @attribute {Boolean} disabled whether the item is active. - */ - case "disabled": - if (jpf.isTrue(value)) - jpf.setStyleClass(this.oExt, "disabled"); - else - jpf.setStyleClass(this.oExt, "", ["disabled"]); - break; - } - } - - /**** Public Methods ****/ - - /** - * @copy jmlElement#enable - */ - this.enable = function(list){ - jpf.setStyleClass(this.oExt, - this.parentNode.baseCSSname + "Disabled"); - }; - - /** - * @copy jmlElement#disable - */ - this.disable = function(list){ - jpf.setStyleClass(this.oExt, null, - [this.parentNode.baseCSSname + "Disabled"]); - }; - - /** - * @copy jmlElement#show - */ - this.show = function(){ - this.oExt.style.display = "block"; - } - - /** - * @copy jmlElement#hide - */ - this.hide = function(){ - this.oExt.style.display = "none"; - } - - /**** Dom Hooks ****/ - - this.$domHandlers["reparent"].push(function(beforeNode, pNode, withinParent){ - if (!this.$jmlLoaded) - return; - - if (!withinParent && this.skinName != pNode.skinName) { - //@todo for now, assuming dom garbage collection doesn't leak - this.loadJml(); - } - }); - - /**** Events ****/ - - this.$down = function(){ - - } - - this.$up = function(){ - if (this.tagName == "radio") - this.parentNode.select(this.group, this.value || this.caption); - - else if (this.tagName == "check") - this.$handlePropSet("checked", !this.checked); - - if (this.submenu) { - this.$over(null, true); - return; - } - - this.parentNode.$hideTree = true; - this.parentNode.hide();//true not focus?/ - - this.parentNode.dispatchEvent("itemclick", { - value : this.value || this.caption - }); - - //@todo Anim effect here? - } - - this.$click = function(){ - this.dispatchEvent("click", { - xmlContext : this.parentNode.xmlReference - }); - } - - var timer; - this.$out = function(e){ - if (jpf.xmldb.isChildOf(this.oExt, e.toElement || e.explicitOriginalTarget) - || jpf.xmldb.isChildOf(this.oExt, e.srcElement || e.target)) //@todo test FF - return; - - clearTimeout(timer); - if (!this.submenu || this.$submenu(true)) { - jpf.setStyleClass(this.oExt, '', ['hover']); - - var sel = this.parentNode.$selected; - if (sel && sel != this) - jpf.setStyleClass(sel.oExt, "", ["hover"]); - - this.parentNode.$selected = null; - } - } - - this.$over = function(e, force){ - if (this.parentNode.$selected) - jpf.setStyleClass(this.parentNode.$selected.oExt, "", ["hover"]); - - jpf.setStyleClass(this.oExt, "hover"); - this.parentNode.$selected = this; - - if (!force && (jpf.xmldb.isChildOf(this.oExt, e.toElement || e.explicitOriginalTarget) - || jpf.xmldb.isChildOf(this.oExt, e.fromElement || e.target))) //@todo test FF - return; - - var ps = this.parentNode.$showingSubMenu; - if (ps) { - if (ps.name == this.submenu) - return; - - ps.hide(); - this.parentNode.$showingSubMenu = null; - } - - if (this.submenu) { - if (force) { - _self.$submenu(); - } - else { - clearTimeout(timer); - timer = setTimeout(function(){ - _self.$submenu(); - timer = null; - }, 200); - } - } - } - - this.$submenu = function(hide, force){ - if (!this.submenu) - return true; - - var menu = self[this.submenu]; - if (!menu) { - throw new Error(jpf.formatErrorString(0, this, - "Displaying submenu", - "Could not find submenu '" + this.submenu + "'", this.$jml)); - - return; - } - - if (!hide) { - //if (this.parentNode.showingSubMenu == this.submenu) - //return; - - this.parentNode.$showingSubMenu = menu; - - var pos = jpf.getAbsolutePosition(this.oExt); - menu.display(pos[0] + this.oExt.offsetWidth + 1, - pos[1], false, this, - this.parentNode.xmlReference, this.parentNode.uniqueId); - menu.setAttribute("zindex", (this.parentNode.zindex || 1) + 1); - } - else { - if (menu.visible && !force) { - return false; - } - - jpf.setStyleClass(this.oExt, '', ['hover']); - menu.hide(); - return true; - } - } - - /**** Init ****/ - - this.$draw = function(isSkinSwitch){ - var p = this.parentNode; - - p.$getNewContext("item"); - var elItem = p.$getLayoutNode("item"); - - var o = 'jpf.lookup(' + this.uniqueId + ')'; - elItem.setAttribute("onmouseup", o + '.$up(event)'); - elItem.setAttribute("onmouseover", o + '.$over(event)'); - elItem.setAttribute("onmouseout", o + '.$out(event)'); - elItem.setAttribute("onmousedown", o + '.$down()'); - elItem.setAttribute("onclick", o + '.$click()'); - - jpf.setStyleClass(elItem, this.tagName); - - this.oExt = jpf.xmldb.htmlImport(elItem, this.parentNode.oInt); - this.oCaption = p.$getLayoutNode("item", "caption", this.oExt) - this.oIcon = p.$getLayoutNode("item", "icon", this.oExt); - this.oHotkey = p.$getLayoutNode("item", "hotkey", this.oExt); - - if (!isSkinSwitch && this.nextSibling && this.nextSibling.oExt) - this.oExt.parentNode.insertBefore(this.oExt, this.nextSibling.oExt); - } - - /** - * @private - */ - this.loadJml = function(x, parentNode) { - this.$jml = x; - if (parentNode) - this.$setParent(parentNode); - - this.skinName = this.parentNode.skinName; - var isSkinSwitch = this.oExt ? true : false; - - this.$draw(isSkinSwitch); - - if (isSkinSwitch) { - if (typeof this.checked !== "undefined") - this.$handlePropSet("checked", this.checked); - else if (typeof this.selected !== "undefined") - this.$handlePropSet("selected", this.selected); - - if (this.disabled) - this.$handlePropSet("disabled", this.disabled); - - if (this.caption) - this.$handlePropSet("caption", this.caption); - } - else { - var attr = x.attributes; - for (var a, i = 0; i < attr.length; i++) { - a = attr[i]; - this.$handlePropSet(a.nodeName, a.nodeValue); - } - - var onclick = x.getAttribute("onclick"); - if (onclick) { - this.addEventListener("click", new Function(onclick)); - delete this.onclick - } - - if (this.caption === undefined && x.firstChild) { - this.caption = x.firstChild.nodeValue; - this.$handlePropSet("caption", this.caption); - } - } - } -}); - - -/*FILEHEAD(/var/lib/jpf/src/elements/slider.js)SIZE(-1077090856)TIME(1238944817)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - -/** - * Element allowing the user to select a value from a range of - * values between a minimum and a maximum value. - * Example: - * This example shows a slider that influences the position of a video. The - * value attribute of the slider is set using property binding. The square - * brackets imply a bidirectional binding. - * <code> - * <j:video id="player1" - * src = "elements/video/demo_video.flv" - * autoplay = "true"> - * Unsupported video codec. - * </j:video> - * - * <j:button onclick="player1.play()">play</j:button> - * <j:button onclick="player1.pause()">pause</j:button> - * - * <j:slider value="[player1.position]" /> - * </code> - * Example: - * This example shows two slider which lets the user indicate a value in a form. - * <code> - * <j:label>How would you grade the opening hours of the helpdesk</j:label> - * <j:slider ref="hours_hd" - * mask = "no opinion|bad|below average|average|above average|good" - * min = "0" - * max = "5" - * step = "1" - * slide = "snap" /> - * - * <j:label>How soon will you make your buying decision</j:label> - * <j:slider ref="decide_buy" - * mask = "undecided|1 week|1 month|6 months|1 year|never" - * min = "0" - * max = "5" - * step = "1" - * slide = "snap" /> - * </code> - * - * @constructor - * @define slider, range - * @allowchild {smartbinding} - * @addnode elements - * - * @author Ruben Daniels - * @version %I%, %G% - * @since 0.9 - * - * @inherits jpf.Presentation - * @inherits jpf.DataBinding - * @inherits jpf.Validation - * @inherits jpf.XForms - * - * @binding value Determines the way the value for the element is retrieved - * from the bound data. - * Example: - * Sets the slider position based on data loaded into this component. - * <code> - * <j:slider> - * <j:bindings> - * <j:value select="@value" /> - * </j:bindings> - * </j:slider> - * </code> - * Example: - * A shorter way to write this is: - * <code> - * <j:slider ref="@value" /> - * </code> - */ -jpf.range = -jpf.slider = jpf.component(jpf.NODE_VISIBLE, function(){ - this.$focussable = true; // This object can get the focus - - var _self = this; - var dragging = false; - - /**** Properties and Attributes ****/ - this.disabled = false; // Object is enabled - this.realtime = true; - this.value = 0; - this.mask = "%"; - this.min = 0; - this.max = 1; - - this.$supportedProperties.push("step", "mask", "min", - "max", "slide", "value"); - - this.$booleanProperties["realtime"] = true; - - /** - * @attribute {Boolean} realtime whether the slider updates it's value realtime, or just when the user stops dragging. - * @attribute {Number} step specifying the step size of a discreet slider. - * Example: - * <code> - * <j:label>How much money do you make annualy.</j:label> - * <j:range ref="salary" - * min = "0" - * max = "50000" - * step = "1000" - * slide = "snap" /> - * </code> - */ - this.$propHandlers["step"] = function(value){ - this.step = parseInt(value) || 0; - - if (!this.$hasLayoutNode("marker")) - return; - - //Remove Markers - var markers = this.oMarkers.childNodes; - for (var i = markers.length - 1; i >= 0; i--) { - if (markers[i].nodeType == 1) - jpf.removeNode(markers[i]); - } - - //Add markers - if (this.step) { - var leftPos, count = (this.max - this.min) / this.step; - for (var o, nodes = [], i = 0; i < count + 1; i++) { - this.$getNewContext("marker"); - o = this.$getLayoutNode("marker"); - - leftPos = Math.max(0, (i * (1 / count) * 100) - 1); - o.setAttribute("style", "left:" + leftPos + "%"); - nodes.push(o); - } - - jpf.xmldb.htmlImport(markers, this.oMarkers); - } - } - - /** - * @attribute {String} mask a pipe '|' seperated list of strings that are - * used as the caption of the slider when their connected value is picked. - * Example: - * <code> - * <j:label>How big is your cat?</j:label> - * <j:slider ref="decide_buy" - * mask = "don't know|20cm|25cm|30cm|35cm|> 35cm" - * min = "0" - * max = "5" - * step = "1" - * slide = "snap" /> - * </code> - */ - this.$propHandlers["mask"] = function(value){ - if (!value) - this.mask = "%"; - - if (!this.mask.match(/^(%|#)$/)) - this.mask = value.split("|"); - } - - /** - * @attribute {String} progress a value between 0 and 1 which is visualized - * inside the slider. This can be used to show a progress indicator for - * the download of movies or other media. - * Example: - * <code> - * </code> - */ - this.$propHandlers["progress"] = function(value){ - if (!this.oProgress) { - this.oProgress = - jpf.xmldb.htmlImport(this.$getLayoutNode("progress"), - this.$getLayoutNode("main", "progress", this.oExt)); - } - - this.oProgress.style.width = ((value || 0) * 100) + "%"; - } - - /** - * @attribute {Number} min the minimal value the slider can have. This is - * the value that the slider has when the grabber is at it's begin position. - */ - this.$propHandlers["min"] = function(value){ - this.min = parseInt(value) || 0; - } - - /** - * @attribute {Number} max the maximal value the slider can have. This is - * the value that the slider has when the grabber is at it's end position. - */ - this.$propHandlers["max"] = function(value){ - this.max = parseInt(value) || 1; - } - - /** - * @attribute {String} slide the way the grabber can be handled - * Possible values: - * normal the slider moves over a continuous space. - * discrete the slider's value is discrete but the grabber moves over a continuous space and only snaps when the user lets go of the grabber. - * snap the slider snaps to the discrete values it can have while dragging. - * Remarks: - * Discrete space is set by the step attribute. - */ - this.$propHandlers["slide"] = function(value){ - this.slideDiscreet = value == "discrete"; - this.slideSnap = value == "snap"; - } - - /** - * @attribute {String} value the value of slider which is represented in - * the position of the grabber using the following - * formula: (value - min) / (max - min) - */ - this.$propHandlers["value"] = function(value, force){ - if (!this.$dir) - return; //@todo fix this - - if (dragging && !force) - return; - - this.value = Math.max(this.min, Math.min(this.max, value)) || 0; - var max, min, multiplier = (this.value - this.min) / (this.max - this.min); - - if (this.$dir == "horizontal") { - max = (this.oContainer.offsetWidth - - jpf.getWidthDiff(this.oContainer)) - - this.oSlider.offsetWidth; - min = parseInt(jpf.getBox( - jpf.getStyle(this.oContainer, "padding"))[3]); - - this.oSlider.style.left = (((max - min) * multiplier) + min) + "px"; - } - else { - max = (this.oContainer.offsetHeight - - jpf.getHeightDiff(this.oContainer)) - - this.oSlider.offsetHeight; - min = parseInt(jpf.getBox( - jpf.getStyle(this.oContainer, "padding"))[0]); - this.oSlider.style.top = (((max - min) * (1 - multiplier)) + min) + "px"; - } - - if (this.oLabel) { - //Percentage - if (this.mask == "%") { - this.oLabel.nodeValue = Math.round(multiplier * 100) + "%"; - } - //Number - else - if (this.mask == "#") { - status = this.value; - this.oLabel.nodeValue = this.step - ? (Math.round(this.value / this.step) * this.step) - : this.value; - } - //Lookup - else { - this.oLabel.nodeValue = this.mask[Math.round(this.value - this.min) - / (this.step || 1)]; //optional floor ?? - } - - } - }; - - /**** Public methods ****/ - - /** - * @copy Widget#setValue - */ - this.setValue = function(value, onlySetXml){ - this.$onlySetXml = onlySetXml;//blrgh.. - this.setProperty("value", value); - this.$onlySetXml = false; - }; - - /** - * @copy Widget#getValue - */ - this.getValue = function(){ - return this.step - ? Math.round(parseInt(this.value) / this.step) * this.step - : this.value; - }; - - /**** Keyboard support ****/ - - this.addEventListener("keydown", function(e){ - var key = e.keyCode; - var ctrlKey = e.ctrlKey; - var shiftKey = e.shiftKey; - - switch (key) { - case 37: - //LEFT - if (this.$dir != "horizontal") - return; - this.setValue(this.value - (ctrlKey ? 0.01 : 0.1)); - break; - case 38: - //UP - if (this.$dir != "vertical") - return; - this.setValue(this.value + (ctrlKey ? 0.01 : 0.1)); - break; - case 39: - //RIGHT - if (this.$dir != "horizontal") - return; - this.setValue(this.value + (ctrlKey ? 0.01 : 0.1)); - break; - case 40: - //DOWN - if (this.$dir != "vertical") - return; - this.setValue(this.value - (ctrlKey ? 0.01 : 0.1)); - break; - default: - return; - } - - return false; - }, true); - - /**** Init ****/ - - this.$draw = function(){ - //Build Main Skin - this.oExt = this.$getExternal(); - this.oLabel = this.$getLayoutNode("main", "status", this.oExt); - this.oMarkers = this.$getLayoutNode("main", "markers", this.oExt); - this.oSlider = this.$getLayoutNode("main", "slider", this.oExt); - this.oInt = this.oContainer = this.$getLayoutNode("main", - "container", this.oExt); - - this.$dir = this.$getOption("main", "direction") || "horizontal"; - - this.oSlider.style.left = (parseInt(jpf.getBox( - jpf.getStyle(this.oExt, "padding"))[3])) + "px"; - - this.oSlider.onmousedown = function(e){ - if (_self.disabled) - return false; - - //@todo use start action here - - if (!e) - e = event; - document.dragNode = this; - - this.x = (e.clientX || e.x); - this.y = (e.clientY || e.y); - this.stX = this.offsetLeft; - this.siX = this.offsetWidth - this.stY = this.offsetTop; - this.siY = this.offsetheight - this.startValue = _self.value; - - if (_self.$dir == "horizontal") { - this.max = parseInt(jpf.getStyle(_self.oContainer, "width")) - - this.offsetWidth; - this.min = parseInt(jpf.getBox( - jpf.getStyle(_self.oContainer, "padding"))[3]); - } - else { - this.max = parseInt(jpf.getStyle(_self.oContainer, "height")) - - this.offsetHeight; - this.min = parseInt(jpf.getBox( - jpf.getStyle(_self.oContainer, "padding"))[0]); - } - - _self.$setStyleClass(this, "btndown", ["btnover"]); - - jpf.dragmode.mode = true; - - function getValue(o, e, slideDiscreet){ - var to = (_self.$dir == "horizontal") - ? (e.clientX || e.x) - o.x + o.stX - : (e.clientY || e.y) - o.y + o.stY; - to = (to > o.max ? o.max : (to < o.min ? o.min : to)); - var value = (((to - o.min) * 100 / (o.max - o.min) / 100) - * (_self.max - _self.min)) + _self.min; - - value = slideDiscreet - ? (Math.round(value / slideDiscreet) * slideDiscreet) - : value; - value = (_self.$dir == "horizontal") ? value : 1 - value; - - return value; - } - - dragging = true; - - document.onmousemove = function(e){ - var o = this.dragNode; - - if (!o) { - document.onmousemove = - document.onmouseup = - jpf.dragmode.mode = null; - - return; //? - } - - if (_self.realtime) { - _self.value = -1; //reset value - _self.setValue(getValue(o, e || event, _self.slideDiscreet)); - } - - _self.$propHandlers["value"].call(_self, getValue(o, e || event, _self.slideDiscreet), true); - } - - document.onmouseup = function(e){ - var o = this.dragNode; - this.dragNode = null; - o.onmouseout(); - - dragging = false; - - /*if (_self.realtime) { - _self.value = -1; //reset value - _self.setValue(o.startValue, true); - }*/ - - _self.$ignoreSignals = _self.realtime; - _self.change(getValue(o, e || event, - _self.slideDiscreet || _self.slideSnap)); - _self.$ignoreSignals = false; - - document.onmousemove = - document.onmouseup = - jpf.dragmode.mode = null; - } - - //event.cancelBubble = true; - return false; - }; - - this.oSlider.onmouseup = this.oSlider.onmouseover = function(){ - if (document.dragNode != this) - _self.$setStyleClass(this, "btnover", ["btndown"]); - }; - - this.oSlider.onmouseout = function(){ - if (document.dragNode != this) - _self.$setStyleClass(this, "", ["btndown", "btnover"]); - }; - - jpf.layout.setRules(this.oExt, "knob", "var o = jpf.all[" + this.uniqueId + "];\ - o.$propHandlers.value.call(o, o.value);", true); - }; - - this.$loadJml = function(x){ - this.$propHandlers["value"].call(this, this.value); - - //@todo this goes wrong with skin switching. smartbindings is called again. - jpf.JmlParser.parseChildren(this.$jml, null, this); - }; - - this.$destroy = function(){ - this.oSlider.onmousedown = - this.oSlider.onmouseup = - this.oSlider.onmouseover = - this.oSlider.onmouseout = null; - }; -}).implement( - jpf.DataBinding, - jpf.Validation, - jpf.Presentation -); - - - -/*FILEHEAD(/var/lib/jpf/src/elements/textbox.js)SIZE(-1077090856)TIME(1239027647)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -//@todo DOCUMENT the modules too - -/** - * Element displaying a rectangular area wich allows a - * user to type information. The information typed can be - * restricted by using masking. The information can also - * be hidden from view when used in password mode. Furthermore - * by supplying a dataset information typed can autocomplete. - * - * @constructor - * @define input, secret, textarea, textbox - * @allowchild autocomplete, {smartbinding} - * @addnode elements - * - * @inherits jpf.DataBinding - * @inherits jpf.Presentation - * @inherits jpf.Validation - * @inherits jpf.XForms - * - * @author Ruben Daniels - * @version %I%, %G% - * @since 0.1 - * - * @binding value Determines the way the value for the element is retrieved - * from the bound data. - * Example: - * Sets the value based on data loaded into this component. - * <code> - * <j:textbox> - * <j:bindings> - * <j:value select="@name" /> - * </j:bindings> - * </j:textbox> - * </code> - * Example: - * A shorter way to write this is: - * <code> - * <j:textbox ref="@name" /> - * </code> - * - * @event click Fires when the user presses a mousebutton while over this element and then let's the mousebutton go. - * @event mouseup Fires when the user lets go of a mousebutton while over this element. - * @event mousedown Fires when the user presses a mousebutton while over this element. - * @event keyup Fires when the user lets go of a keyboard button while this element is focussed. - * object: - * {Number} keyCode which key was pressed. This is an ascii number. - * @event clear Fires when the content of this element is cleared. - */ -jpf.input = -jpf.secret = -jpf.textarea = -jpf.textbox = jpf.component(jpf.NODE_VISIBLE, function(){ - this.$focussable = true; // This object can get the focus - var masking = false; - var _self = this; - - /**** Properties and Attributes ****/ - - //this.realtime = false; - this.value = ""; - this.isContentEditable = true; - this.multiline = this.tagName == "textarea" ? true : false; - - this.$booleanProperties["focusselect"] = true; - this.$booleanProperties["realtime"] = true; - this.$supportedProperties.push("value", "mask", "initial", - "focusselect", "realtime", "type"); - - /** - * @attribute {String} value the text of this element - */ - this.$propHandlers["value"] = function(value, initial){ - // Set Value - if (this.isHTMLBox) { - if (this.oInt.innerHTML != value) - this.oInt.innerHTML = value; - } - else if (this.oInt.value != value) - this.oInt.value = value; - - if (this.oButton) - this.oButton.style.display = value && !initial ? "block" : "none"; - }; - - //See validation - this.$propHandlers["maxlength"] = function(value){ - this.$setRule("maxlength", value - ? "value.toString().length <= " + value - : null); - - //Special validation support using nativate max-length browser support - if (this.oInt.tagName.toLowerCase().match(/input|textarea/)) - this.oInt.maxLength = parseInt(value) || null; - }; - - /** - * @attribute {String} mask a complex input pattern that the user should - * adhere to. This is a string which is a combination of special and normal - * characters. Then comma seperated it has two options. The first option - * specifies whether the non input characters (the chars not typed by the - * user) are in the value of this element. The second option specifies the - * character that is displayed when the user hasn't yet filled in a - * character. - * Possible values: - * 0 Any digit - * 1 The number 1 or 2. - * 9 Any digit or a space. - * # Any digit, space, plus or minus. - * L Any alpha character, case insensitive. - * ? Any alpha character, case insensitive or space. - * A Any alphanumeric character. - * a Any alphanumeric character or space. - * X Hexadecimal character, case insensitive. - * x Hexadecimal character, case insensitive or space. - * & Any whitespace. - * C Any character. - * ! The string is right aligned. - * ' The start or end of a literal part. - * " The start or end of a literal part. - * < The following characters will be lowercase, event though typed uppercase. - * > The following characters will be uppercase, event though typed lowercase. - * \ Cancel the special meaning of a character. - * Example: - * An american style phone number. - * <code> - * <j:textbox mask="(000)0000-0000;;_" /> - * </code> - * Example: - * A dutch postal code - * <code> - * <j:textbox mask="0000 AA;;_" /> - * </code> - * Example: - * A date - * <code> - * <j:textbox mask="00-00-0000;;_" datatype="xsd:date" /> - * </code> - * Example: - * A serial number - * <code> - * <j:textbox mask="'WCS74'0000-00000;1;_" /> - * </code> - * Example: - * A MAC address - * <code> - * <j:textbox mask="XX-XX-XX-XX-XX-XX;;_" /> - * </code> - * Remarks: - * This currently only works in internet explorer. - */ - this.$propHandlers["mask"] = function(value){ - if (this.mask == "PASSWORD")// || !jpf.hasMsRangeObject) - return; - - if (!value) { - throw new Error("Not Implemented"); - } - - if (!masking) { - masking = true; - this.inherit(jpf.textbox.masking); /** @inherits jpf.textbox.masking */ - this.focusselect = false; - this.realtime = false; - } - - this.setMask(this.mask); - }; - - /** - * @attribute {String} initial-message the message displayed by this element - * when it doesn't have a value set. This property is inherited from parent - * nodes. When none is found it is looked for on the appsettings element. - */ - this.$propHandlers["initial-message"] = function(value){ - this.initialMsg = value - || jpf.xmldb.getInheritedAttribute(this.$jml, "initial-message"); - - if (this.initialMsg) { - this.oInt.onblur(); - this.$propHandlers["value"].call(this, this.initialMsg, true); - } - }; - - /** - * @attribute {Boolean} realtime whether the value of the bound data is - * updated as the user types it, or only when this element looses focus or - * the user presses enter. - */ - this.$propHandlers["realtime"] = function(value){ - this.realtime = typeof value == "boolean" - ? value - : jpf.isTrue(jpf.xmldb.getInheritedAttribute(this.$jml, "realtime")) || false; - }; - - /** - * @attribute {Boolean} focusselect whether the text in this element is - * selected when this element receives focus. - */ - this.$propHandlers["focusselect"] = function(value){ - this.oInt.onmousedown = function(){ - _self.focusselect = false; - }; - - this.oInt.onmouseup = - this.oInt.onmouseout = function(){ - _self.focusselect = value; - }; - }; - - /** - * @attribute {String} type the type or function this element represents. - * This can be any arbitrary name. Although there are some special values. - * Possible values: - * username this element is used to type in the name part of login credentials. - * password this element is used to type in the password part of login credentials. - */ - this.$propHandlers["type"] = function(value){ - if (value && "password|username".indexOf(value) > -1 - && typeof this.focusselect == "undefined") { - this.focusselect = true; - this.$propHandlers["focusselect"].call(this, true); - } - }; - - /**** Public Methods ****/ - - /** - * @copy Widget#setValue - */ - this.setValue = function(value){ - return this.setProperty("value", value); - }; - - /** - * @copy Widget#getValue - */ - this.getValue = function(){ - var v = this.isHTMLBox ? this.oInt.innerHTML : this.oInt.value; - return v == this.initialMsg ? "" : v.replace(/\r/g, ""); - }; - - /** - * Selects the text in this element. - */ - this.select = function(){ this.oInt.select(); }; - - /** - * Deselects the text in this element. - */ - this.deselect = function(){ this.oInt.deselect(); }; - - /**** Private Methods *****/ - - this.$enable = function(){ this.oInt.disabled = false; }; - this.$disable = function(){ this.oInt.disabled = true; }; - - this.$insertData = function(str){ - return this.setValue(str); - }; - - /** - * @private - */ - this.insert = function(text){ - if (jpf.hasMsRangeObject) { - try { - this.oInt.focus(); - } - catch(e) {} - var range = document.selection.createRange(); - if (this.oninsert) - text = this.oninsert(text); - range.pasteHTML(text); - range.collapse(true); - range.select(); - } - else { - this.oInt.value += text; - } - }; - - this.$clear = function(){ - this.value = "";//@todo what about property binding? - - if (this.initialMsg && jpf.window.focussed != this) { - this.$propHandlers["value"].call(this, this.initialMsg, true); - jpf.setStyleClass(_self.oExt, _self.baseCSSname + "Initial"); - } - else { - this.$propHandlers["value"].call(this, ""); - } - - if (!this.oInt.tagName.toLowerCase().match(/input|textarea/i)) { - if (jpf.hasMsRangeObject) { - try { - var range = document.selection.createRange(); - range.moveStart("sentence", -1); - //range.text = ""; - range.select(); - } - catch(e) {} - } - } - - this.dispatchEvent("clear"); - }; - - this.$keyHandler = function(key, ctrlKey, shiftKey, altKey, e){ - if (this.dispatchEvent("keydown", { - keyCode : key, - ctrlKey : ctrlKey, - shiftKey : shiftKey, - altKey : altKey, - htmlEvent : e}) === false) - return false; - - // @todo: revisit this IF statement - dead code? - if (false && jpf.isIE && (key == 86 && ctrlKey || key == 45 && shiftKey)) { - var text = window.clipboardData.getData("Text"); - if ((text = this.dispatchEvent("keydown", { - text : this.onpaste(text)}) === false)) - return false; - if (!text) - text = window.clipboardData.getData("Text"); - - this.oInt.focus(); - var range = document.selection.createRange(); - range.text = ""; - range.collapse(); - range.pasteHTML(text.replace(/\n/g, "<br />").replace(/\t/g, " ")); - - return false; - } - }; - - var fTimer; - this.$focus = function(e){ - if (!this.oExt || this.oExt.disabled) - return; - - this.$setStyleClass(this.oExt, this.baseCSSname + "Focus"); - - if (this.initialMsg && this.oInt.value == this.initialMsg) { - this.$propHandlers["value"].call(this, "", true); - jpf.setStyleClass(this.oExt, "", [this.baseCSSname + "Initial"]); - } - - function delay(){ - try { - if (!fTimer || document.activeElement != _self.oInt) { - _self.oInt.focus(); - } - else { - clearInterval(fTimer); - return; - } - } - catch(e) {} - - if (masking) - _self.setPosition(); - - if (_self.focusselect) - _self.select(); - }; - - if ((!e || e.mouse) && jpf.isIE) { - clearInterval(fTimer); - fTimer = setInterval(delay, 1); - } - else - delay(); - }; - - this.$blur = function(e){ - if (!this.oExt) - return; - - if (!this.realtime) - this.change(this.getValue()); - - this.$setStyleClass(this.oExt, "", [this.baseCSSname + "Focus"]); - - if (this.initialMsg && this.oInt.value == "") { - this.$propHandlers["value"].call(this, this.initialMsg, true); - jpf.setStyleClass(this.oExt, this.baseCSSname + "Initial"); - } - - /*if (jpf.hasMsRangeObject) { - var r = this.oInt.createTextRange(); - r.collapse(); - r.select(); - }*/ - - try { - if (jpf.isIE || !e || e.srcElement != jpf.window) - this.oInt.blur(); - } - catch(e) {} - - // check if we clicked on the oContainer. ifso dont hide it - if (this.oContainer) { - setTimeout("var o = jpf.lookup(" + this.uniqueId + ");\ - o.oContainer.style.display = 'none'", 100); - } - - clearInterval(fTimer); - }; - - /**** Init ****/ - - this.$draw = function(){ - //Build Main Skin - this.oExt = this.$getExternal(null, null, function(oExt){ - if (this.$jml.getAttribute("mask") == "PASSWORD" - || "secret|password".indexOf(this.tagName) > -1 - || this.$jml.getAttribute("type") == "password") { - this.$jml.removeAttribute("mask"); - this.$getLayoutNode("main", "input").setAttribute("type", "password"); - } - else if (this.tagName == "email") { - this.datatype = "jpf:email"; - this.$propHandlers["datatype"].call(this, "jpf:email"); - } - else if (this.tagName == "url") { - this.datatype = "jpf:url"; - this.$propHandlers["datatype"].call(this, "jpf:url"); - } - - oExt.setAttribute("onmousedown", "this.host.dispatchEvent('mousedown', {htmlEvent : event});"); - oExt.setAttribute("onmouseup", "this.host.dispatchEvent('mouseup', {htmlEvent : event});"); - oExt.setAttribute("onclick", "this.host.dispatchEvent('click', {htmlEvent : event});"); - }); - this.oInt = this.$getLayoutNode("main", "input", this.oExt); - this.oButton = this.$getLayoutNode("main", "button", this.oExt); - - if (!jpf.hasContentEditable && "input|textarea".indexOf(this.oInt.tagName.toLowerCase()) == -1) { - var node = this.oInt; - this.oInt = node.parentNode.insertBefore(document.createElement("textarea"), node); - node.parentNode.removeChild(node); - this.oInt.className = node.className; - if (this.oExt == node) - this.oExt = this.oInt; - } - - //@todo for skin switching this should be removed - if (this.oInt.tagName.toLowerCase() == "textarea") { - this.addEventListener("focus", function(e){ - //if (this.multiline != "optional") - //e.returnValue = false - }); - } - - this.oInt.onselectstart = function(e){ - if (!e) e = event; - e.cancelBubble = true; - } - this.oInt.host = this; - - //temp fix - this.oInt.onkeydown = function(e){ - if (this.disabled) return false; - - e = e || window.event; - - //Change - if (!_self.realtime) { - var value = _self.getValue(); - if (e.keyCode == 13 && value != this.value) - _self.change(value); - } - else if (jpf.isSafari && _self.xmlRoot && _self.getValue() != this.value) //safari issue (only old??) - setTimeout("var o = jpf.lookup(" + _self.uniqueId + ");\ - o.change(o.getValue())"); - - if (_self.multiline == "optional" && e.keyCode == 13 && !e.ctrlKey) - return false; - - if (e.ctrlKey && (e.keyCode == 66 || e.keyCode == 73 - || e.keyCode == 85)) - return false; - - //Autocomplete - if (_self.oContainer) { - var oTxt = _self; - var keyCode = e.keyCode; - setTimeout(function(){ - oTxt.fillAutocomplete(keyCode); - }); - } - - //Non masking - if (!_self.mask) { - return _self.$keyHandler(e.keyCode, e.ctrlKey, - e.shiftKey, e.altKey, e); - } - }; - - this.oInt.onkeyup = function(e){ - if (!e) - e = event; - - var keyCode = e.keyCode; - - if (_self.oButton) - _self.oButton.style.display = this.value ? "block" : "none"; - - if (_self.realtime) { - setTimeout(function(){ - if (!_self.mask && _self.getValue() != _self.value) - _self.change(_self.getValue()); //this is a hack - _self.dispatchEvent("keyup", {keyCode : keyCode});//@todo - }); - } - else { - _self.dispatchEvent("keyup", {keyCode : keyCode});//@todo - } - - if (_self.isValid() && e.keyCode != 13 && e.keyCode != 17) - _self.clearError(); - }; - - this.oInt.onfocus = function(){ - if (jpf.hasFocusBug) - jpf.window.$focusfix2(); - }; - - this.oInt.onblur = function(){ - if (jpf.hasFocusBug) - jpf.window.$blurfix(); - }; - - if (jpf.hasAutocompleteXulBug) - this.oInt.setAttribute("autocomplete", "off"); - - if (!this.oInt.tagName.toLowerCase().match(/input|textarea/)) { - this.isHTMLBox = true; - - this.oInt.unselectable = "Off"; - this.oInt.contentEditable = true; - this.oInt.style.width = "1px"; - - this.oInt.select = function(){ - var r = document.selection.createRange(); - r.moveToElementText(this); - r.select(); - } - }; - - this.oInt.deselect = function(){ - if (!document.selection) return; - - var r = document.selection.createRange(); - r.collapse(); - r.select(); - }; - }; - - this.$loadJml = function(x){ - //Autocomplete - var ac = $xmlns(x, "autocomplete", jpf.ns.jml)[0]; - if (ac) { - this.inherit(jpf.textbox.autocomplete); /** @inherits jpf.textbox.autocomplete */ - this.initAutocomplete(ac); - } - - if (typeof this.realtime == "undefined") - this.$propHandlers["realtime"].call(this); - - if (jpf.xmldb.isOnlyChild(x.firstChild, [3,4])) - this.$handlePropSet("value", x.firstChild.nodeValue.trim()); - else if (!ac) - jpf.JmlParser.parseChildren(this.$jml, null, this); - }; - - this.$destroy = function(){ - this.oInt.onkeypress = - this.oInt.onmouseup = - this.oInt.onmouseout = - this.oInt.onmousedown = - this.oInt.onkeydown = - this.oInt.onkeyup = - this.oInt.onselectstart = null; - }; -}).implement( - jpf.DataBinding, - jpf.Validation, - jpf.Presentation -); - - - -/*FILEHEAD(/var/lib/jpf/src/elements/button.js)SIZE(-1077090856)TIME(1238950356)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -/** - * Element displaying a clickable rectangle that visually confirms to the - * user when the area is clicked and then executes a command. - * - * @constructor - * @define button, submit, trigger, reset - * @addnode elements - * - * @author Ruben Daniels - * @version %I%, %G% - * @since 0.4 - * - * @inherits jpf.Presentation - * @inherits jpf.BaseButton - */ -jpf.submit = -jpf.trigger = -jpf.reset = -jpf.button = jpf.component(jpf.NODE_VISIBLE, function(){ - var useExtraDiv; - var _self = this; - - this.editableParts = { - "main": [["caption", "text()"]] - }; - - - /**** Properties and Attributes ****/ - - this.$focussable = true; // This object can get the focus - this.value = null; - - /** - * @attribute {String} icon the url from which the icon image is loaded. - * @attribute {Boolean} state whether this boolean is a multi state button. - * @attribute {String} value the initial value of a state button. - * @attribute {String} tooltip the text displayed when a user hovers with the mouse over the element. - * @attribute {String} color the text color of the caption of this element. - * @attribute {String} caption the text displayed on this element indicating the action when the button is pressed. - * @attribute {String} action one of the default actions this button can perform when pressed. - * Possible values: - * undo Executes undo on the action tracker of the target element. - * redo Executes redo on the action tracker of the target element. - * remove Removes the selected node(s) of the target element. - * add Adds a node to the target element. - * rename Starts the rename function on the target element. - * login Calls log in on the auth element with the values of the textboxes of type username and password. - * logout Calls lot out on the auth element. - * ok Executes a commitTransaction() on the target element, and closes or hides that element. - * cancel Executes a rollbackTransaction() on the target element, and closes or hides that element. - * apply Executes a commitTransaction() on the target element. - * close Closes the target element. - * @attribute {String} target id of the element to apply the action to. Defaults to the parent container. - * @attribute {String} default whether this button is the default action for the containing window. - * @attribute {String} submenu the name of the contextmenu to display when the button is pressed. - */ - this.$booleanProperties["default"] = true; - this.$supportedProperties.push("icon", "value", "tooltip", "state", - "color", "caption", "action", "target", "default", "submenu"); - - this.$propHandlers["icon"] = function(value){ - if (!this.oIcon) - return jpf.console.warn("No icon defined in the Button skin", "button"); - - if (value) - this.$setStyleClass(this.oExt, this.baseCSSname + "Icon"); - else - this.$setStyleClass(this.oExt, "", [this.baseCSSname + "Icon"]); - - jpf.skins.setIcon(this.oIcon, value, this.iconPath); - }; - - this.$propHandlers["value"] = function(value){ - if (value === undefined) - value = !this.value; - this.value = value; - - if (this.value) - this.$setState("Down", {}); - else - this.$setState("Out", {}); - }; - - this.$propHandlers["tooltip"] = function(value){ - this.oExt.setAttribute("title", value); - }; - - this.$propHandlers["state"] = function(value){ - this.$setStateBehaviour(value == 1); - }; - - this.$propHandlers["color"] = function(value){ - if (this.oCaption) - this.oCaption.parentNode.style.color = value; - }; - - this.$propHandlers["caption"] = function(value){ - if (value) - this.$setStyleClass(this.oExt, "", [this.baseCSSname + "Empty"]); - else - this.$setStyleClass(this.oExt, this.baseCSSname + "Empty"); - - if (this.oCaption) - this.oCaption.nodeValue = String(value || "").trim(); - }; - - //@todo reparenting - var forceFocus; - this.$propHandlers["default"] = function(value){ - if (!this.focussable && value || forceFocus) - this.setAttribute("focussable", forceFocus = value); - - this.parentNode.removeEventListener("focus", setDefault); - this.parentNode.removeEventListener("blur", removeDefault); - - if (!value) - return; - - //Currrently only support for parentNode, this might need to be expanded - this.parentNode.addEventListener("focus", setDefault); - this.parentNode.addEventListener("blur", removeDefault); - }; - - function setDefault(e){ - if (e.defaultButtonSet || e.returnValue === false) - return; - - e.defaultButtonSet = true; - - if (useExtraDiv) - _self.oExt.appendChild(jpf.button.$extradiv); - - _self.$setStyleClass(_self.oExt, _self.baseCSSname + "Default"); - - if (e.srcElement != _self && _self.$focusParent) { - _self.$focusParent.addEventListener("keydown", btnKeyDown); - } - } - - function removeDefault(e){ - if (useExtraDiv && jpf.button.$extradiv.parentNode == _self.oExt) - _self.oExt.removeChild(jpf.button.$extradiv); - - _self.$setStyleClass(_self.oExt, "", [_self.baseCSSname + "Default"]); - - if (e.srcElement != _self && _self.$focusParent) { - _self.$focusParent.removeEventListener("keydown", btnKeyDown); - } - } - - function btnKeyDown(e){ - var ml; - - var f = jpf.window.focussed; - if (f) { - if (f.hasFeature(__MULTISELECT__)) - return; - - ml = f.multiline; - } - - if (ml && ml != "optional" && e.keyCode == 13 - && e.ctrlKey || (!ml || ml == "optional") - && e.keyCode == 13 && !e.ctrlKey && !e.shiftKey && !e.altKey) - _self.oExt.onmouseup(e.htmlEvent, true); - } - - this.addEventListener("focus", setDefault); - this.addEventListener("blur", removeDefault); - - - //@todo move this to menu.js - function menuKeyHandler(e){ - return; - var key = e.keyCode; - - var next, nr = jpf.xmldb.getChildNumber(this); - if (key == 37) { //left - next = nr == 0 - ? this.parentNode.childNodes.length - 1 - : nr - 1; - this.parentNode.childNodes[next].dispatchEvent("mouseover"); - } - else if (key == 39) { //right - next = (nr >= this.parentNode.childNodes.length - 1) - ? 0 - : nr + 1; - this.parentNode.childNodes[next].dispatchEvent("mouseover"); - } - } - - function menuDown(e){ - var menu = self[this.submenu]; - - this.value = !this.value; - - if (this.value) - this.$setState("Down", {}); - - if (!menu) { - throw new Error(jpf.formatErrorString(0, this, - "Showing submenu", - "Could not find submenu '" + this.submenu + "'")); - } - - if (!this.value) { - menu.hide(); - this.$setState("Over", {}, "toolbarover"); - - this.parentNode.menuIsPressed = false; - if (this.parentNode.hasMoved) - this.value = false; - - if (jpf.hasFocusBug) - jpf.window.$focusfix(); - - return false; - } - - this.parentNode.menuIsPressed = this; - - var pos = jpf.getAbsolutePosition(this.oExt, menu.oExt.offsetParent); - menu.display(pos[0], - pos[1] + this.oExt.offsetHeight, false, this, - null, null, this.oExt.offsetWidth - 2); - - this.parentNode.hasMoved = false; - - e.htmlEvent.cancelBubble = true; - - return false; - } - - function menuOver(){ - var menuPressed = this.parentNode.menuIsPressed; - - if (!menuPressed || menuPressed == this) - return; - - menuPressed.setValue(false); - var oldMenu = self[menuPressed.submenu]; - oldMenu.$propHandlers["visible"].call(oldMenu, false, true);//.hide(); - - this.setValue(true); - this.parentNode.menuIsPressed = this; - - var menu = self[this.submenu]; - - if (!menu) { - throw new Error(jpf.formatErrorString(0, this, - "Showing submenu", - "Could not find submenu '" + this.submenu + "'")); - } - - var pos = jpf.getAbsolutePosition(this.oExt, menu.oExt.offsetParent); - - menu.display(pos[0], - pos[1] + this.oExt.offsetHeight, true, this, - null, null, this.oExt.offsetWidth - 2); - - //jpf.window.$focus(this); - this.$focus(); - - this.parentNode.hasMoved = true; - - return false; - } - - /** - * @attribute {string} submenu If this attribute is set, the button will - * function like a menu button - */ - this.$propHandlers["submenu"] = function(value){ - if (!value){ - if (this.value && this.parentNode) - menuDown.call(this); - - this.$focussable = true; - this.$setNormalBehaviour(); - this.removeEventListener("mousedown", menuDown); - this.removeEventListener("mouseover", menuOver); - this.removeEventListener("keydown", menuKeyHandler, true); - return; - } - - this.$focussable = false; - this.$setStateBehaviour(); - - this.addEventListener("mousedown", menuDown); - this.addEventListener("mouseover", menuOver); - this.addEventListener("keydown", menuKeyHandler, true); - }; - - /**** Public Methods ****/ - - /** - * @copy Widget#setValue - */ - this.setValue = function(value){ - this.setProperty("value", value); - }; - - /** - * Sets the text displayed as caption of this element. - * - * @param {String} value required The string to display. - * @see baseclass.validation - */ - this.setCaption = function(value){ - this.setProperty("caption", value); - }; - - /** - * Sets the URL of the icon displayed on this element. - * - * @param {String} value required The URL to the location of the icon. - * @see element.button - * @see element.modalwindow - */ - this.setIcon = function(url){ - this.setProperty("icon", url); - }; - - /**** Private state methods ****/ - - this.$enable = function(){ - if (this["default"]) { - setDefault({}); - if (jpf.window.focussed) - jpf.window.focussed.focus(true); - } - if (this.state && this.value) { - this.$setState("Down", {}); - } - - this.$doBgSwitch(1); - }; - - this.$disable = function(){ - if (this["default"]) - removeDefault({}); - - this.$doBgSwitch(4); - this.$setStyleClass(this.oExt, "", - [this.baseCSSname + "Over", this.baseCSSname + "Down"]); - }; - - this.$setStateBehaviour = function(value){ - this.value = value || false; - this.isBoolean = true; - this.$setStyleClass(this.oExt, this.baseCSSname + "Bool"); - - if (this.value) { - this.$setStyleClass(this.oExt, this.baseCSSname + "Down"); - this.$doBgSwitch(this.states["Down"]); - } - }; - - this.$setNormalBehaviour = function(){ - this.value = null; - this.isBoolean = false; - this.$setStyleClass(this.oExt, "", [this.baseCSSname + "Bool"]); - }; - - this.$setState = function(state, e, strEvent){ - if (this.disabled) - return; - - if (strEvent && this.dispatchEvent(strEvent, {htmlEvent: e}) === false) - return; - - this.$doBgSwitch(this.states[state]); - var bs = this.baseCSSname; - this.$setStyleClass(this.oExt, (state != "Out" ? bs + state : ""), - [(this.value ? "" : bs + "Down"), bs + "Over"]); - - if (this.submenu) { - bs = this.baseCSSname + "menu"; - this.$setStyleClass(this.oExt, (state != "Out" ? bs + state : ""), - [(this.value ? "" : bs + "Down"), bs + "Over"]); - } - - //if (state != "Down") - //e.cancelBubble = true; - }; - - this.$clickHandler = function(){ - // This handles the actual OnClick action. Return true to redraw the button. - if (this.isBoolean && !this.submenu) { - this.setProperty("value", !this.value); - return true; - } - }; - - this.$submenu = function(hide, force){ - if (hide) { - this.setValue(false); - this.$setState("Out", {}, "mouseout"); - this.parentNode.menuIsPressed = false; - } - }; - - /**** DOM Hooks ****/ - - //@todo can't we make this generic for button, bar, page, divider and others, maybe in presentation - this.$domHandlers["reparent"].push( - function(beforeNode, pNode, withinParent){ - if (!this.$jmlLoaded) - return; - - var skinName; - if (isUsingParentSkin && !withinParent - && this.skinName != pNode.skinName - || !isUsingParentSkin && (skinName = this.parentNode.$getOption - && this.parentNode.$getOption("main", "button-skin"))) { - isUsingParentSkin = true; - this.$forceSkinChange(this.parentNode.skinName.split(":")[0] + ":" + skinName); - } - }); - - /**** Init ****/ - - var inited = false, isUsingParentSkin = false; - this.$draw = function(){ - if (typeof this.focussable == "undefined") { - if (this.parentNode.parentNode - && this.parentNode.parentNode.tagName == "toolbar" - && !this.$jml.getAttribute("focussable")) - this.focussable = false; - } - - var skinName; - if (this.parentNode && (skinName = this.parentNode.$getOption - && this.parentNode.$getOption("main", "button-skin"))) { - isUsingParentSkin = true; - skinName = this.parentNode.skinName.split(":")[0] + ":" + skinName; - if (this.skinName != skinName) - this.$loadSkin(skinName); - this.$focussable = jpf.KEYBOARD; - } - else if(isUsingParentSkin){ - isUsingParentSkin = false; - this.$loadSkin(); - this.$focussable = true; - } - - //Build Main Skin - this.oExt = this.$getExternal(); - this.oIcon = this.$getLayoutNode("main", "icon", this.oExt); - this.oCaption = this.$getLayoutNode("main", "caption", this.oExt); - - useExtraDiv = jpf.isTrue(this.$getOption("main", "extradiv")); - if (!jpf.button.$extradiv && useExtraDiv) { - (jpf.button.$extradiv = document.createElement("div")) - .className = "extradiv" - } - - if (this.tagName == "submit") - this.action = "submit"; - else if (this.tagName == "reset") - this.action = "reset"; - - this.$setupEvents(); - }; - - this.$skinchange = function(){ - if (this.caption) - this.$propHandlers["caption"].call(this, this.caption); - - if (this.icon) - this.$propHandlers["icon"].call(this, this.icon); - - this.$updateState({reset:1}); - //this.$blur(); - - //if (this.$focussable !== true && this.hasFocus()) - //jpf.window.$focusLast(this.$focusParent); - } - - this.$loadJml = function(x){ - if (!this.caption && x.firstChild) - this.setProperty("caption", x.firstChild.nodeValue); - else if (typeof this.caption == "undefined") - this.$propHandlers["caption"].call(this, ""); - - this.$makeEditable("main", this.oExt, this.$jml); - - if (!inited) { - jpf.JmlParser.parseChildren(this.$jml, null, this); - inited = true; - } - }; - - //@todo solve how this works with XForms - this.addEventListener("click", function(e){ - var action = this.action; - - //#-ifdef __WITH_HTML5 - if (!action) - action = this.tagName; - //#-endif - - setTimeout(function(){ - (jpf.button.actions[action] || jpf.K).call(_self); - }); - }); - -}).implement(jpf.Presentation, jpf.BaseButton); - -jpf.button.actions = { - "undo" : function(action){ - var tracker; - if (this.target && self[this.target]) { - tracker = self[this.target].getActionTracker() - } - else { - var at, node = this; - while(node.parentNode) - at = (node = node.parentNode).$at; - } - - (tracker || jpf.window.$at)[action || "undo"](); - }, - - "redo" : function(){ - jpf.button.actions.undo.call(this, "redo"); - }, - - "remove" : function(){ - if (this.target && self[this.target]) - self[this.target].remove() - else - jpf.console.warn("Target to remove wasn't found or specified:'" - + this.target + "'"); - }, - - "add" : function(){ - if (this.target && self[this.target]) - self[this.target].add() - else - jpf.console.warn("Target to add wasn't found or specified:'" - + this.target + "'"); - }, - - "rename" : function(){ - if (this.target && self[this.target]) - self[this.target].startRename() - else - jpf.console.warn("Target to rename wasn't found or specified:'" - + this.target + "'"); - }, - - "login" : function(){ - var parent = this.target && self[this.target] - ? self[this.target] - : this.parentNode; - - var vg = parent.$validgroup || new jpf.ValidationGroup(); - if (!vg.childNodes.length) - vg.childNodes = parent.childNodes.slice(); - - var vars = {}; - function loopChildren(nodes){ - for (var node, i = 0, l = nodes.length; i < l; i++) { - node = nodes[i]; - - if (node.hasFeature(__VALIDATION__) - && !node.$validgroup && !node.form) { - node.setProperty("validgroup", vg); - } - - if (node.$jml.getAttribute("type")) - vars[node.$jml.getAttribute("type")] = node.getValue(); - - if (vars.username && vars.password) - return; - - if (node.childNodes.length) - loopChildren(node.childNodes); - } - } - loopChildren(parent.childNodes); - - if (!vg.isValid()) - return; - - if (!vars.username || !vars.password) { - throw new Error(jpf.formatErrorString(0, this, - "Clicking the login button", - "Could not find the username or password box")); - - return; - } - - jpf.auth.login(vars.username, vars.password); - }, - - "logout" : function(){ - jpf.auth.logout(); - }, - - "submit" : function(doReset){ - var vg, model; - - var parent = this.target && self[this.target] - ? self[this.target] - : this.parentNode; - - if (parent.tagName == "model") - model = parent; - else { - if (!parent.$validgroup) { - parent.$validgroup = parent.validgroup - ? self[parent.validgroup] - : new jpf.ValidationGroup(); - } - - vg = parent.$validgroup; - if (!vg.childNodes.length) - vg.childNodes = parent.childNodes.slice(); - - function loopChildren(nodes){ - for (var node, i = 0, l = nodes.length; i < l; i++) { - node = nodes[i]; - - if (node.getModel) { - model = node.getModel(); - if (model) - return false; - } - - if (node.childNodes.length) - if (loopChildren(node.childNodes) === false) - return false; - } - } - loopChildren(parent.childNodes); - - if (!model) { - throw new Error(jpf.formatErrorString(0, this, - "Finding a model to submit", - "Could not find a model to submit.")); - - return; - } - } - - if (doReset) { - model.reset(); - return; - } - - if (vg && !vg.isValid()) - return; - - model.submit(); - }, - - "reset" : function(){ - jpf.button.actions["submit"].call(this, true); - }, - - "ok" : function(){ - var node; - - if (this.target) { - node = self[this.target]; - } - else { - var node = this.parentNode; - while (node && !node.hasFeature(__TRANSACTION__)) { - node = node.parentNode; - } - - if (node && !node.hasFeature(__TRANSACTION__)) - return; - } - - if (node.commit() && node.close) - node.close(); - }, - - "cancel" : function(){ - var node; - - if (this.target) { - node = self[this.target]; - } - else { - var node = this.parentNode; - while (node && !node.hasFeature(__TRANSACTION__)) { - node = node.parentNode; - } - - if (node && !node.hasFeature(__TRANSACTION__)) - return; - } - - node.rollback(); - if (node.close) - node.close(); - }, - - "apply" : function(){ - var node; - - if (this.target) { - node = self[this.target]; - } - else { - var node = this.parentNode; - while (node && !node.hasFeature(__TRANSACTION__)) { - node = node.parentNode; - } - - if (node && !node.hasFeature(__TRANSACTION__)) - return; - } - - if (node.autoshow) - node.autoshow = -1; - if (node.commit()) - node.begin("update"); - }, - - "close" : function(){ - var parent = this.target && self[this.target] - ? self[this.target] - : this.parentNode; - - while(parent && !parent.close) - parent = parent.parentNode; - - if (parent && parent.close) - parent.close(); - else - jpf.console.warn("Target to close wasn't found or specified:'" - + this.target + "'"); - } -}; - - - -/*FILEHEAD(/var/lib/jpf/src/elements/audio.js)SIZE(-1077090856)TIME(1238933683)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -/** - * @classDescription This class creates a new audio object - * @return {Audio} Returns a new audio - * @type {Audio} - * @inherits jpf.Presentation - * @inherits jpf.Media - * @constructor - * @allowchild {text} - * @addnode elements:audio - * @link http://www.whatwg.org/specs/web-apps/current-work/#audio - * - * @author Mike de Boer - * @version %I%, %G% - * @since 1.0 - */ - -jpf.audio = jpf.component(jpf.NODE_HIDDEN, function() { - this.$supportedProperties.push("waveform", "peak", "EQ", "ID3"); - - this.mainBind = "src"; - - /** - * Load a audio by setting the URL pointer to a different audio file - * - * @param {String} sAudio - * @type {Object} - */ - var dbLoad = this.load; - this.loadMedia = function() { - if (!arguments.length) { - if (this.player) { - this.setProperty('currentSrc', this.src); - this.setProperty('networkState', jpf.Media.NETWORK_LOADING); - this.player.load(this.src); - } - } - else { - dbLoad.apply(this, arguments); - } - - return this; - }; - - /** - * Seek the audio to a specific position. - * - * @param {Number} iTo The number of seconds to seek the playhead to. - * @type {Object} - */ - this.seek = function(iTo) { - if (this.player && iTo >= 0 && iTo <= this.duration) - this.player.seek(iTo); - }; - - /** - * Set the volume of the audio to a specific range (0 - 100) - * - * @param {Number} iVolume - * @type {Object} - */ - this.setVolume = function(iVolume) { - if (this.player) - this.player.setVolume(iVolume); - }; - - /** - * Guess the mime-type of a audio file, based on its filename/ extension. - * - * @param {String} path - * @type {String} - */ - this.$guessType = function(path) { - // make a best-guess, based on the extension of the src attribute (file name) - var ext = path.substr(path.lastIndexOf('.') + 1); - var type = ""; - switch (ext) { - default: - case "mp3": - type = "audio/flash"; - break; - } - return type; - }; - - /** - * Find the correct audio player type that will be able to playback the audio - * file with a specific mime-type provided. - * - * @param {String} mimeType - * @type {String} - */ - this.$getPlayerType = function(mimeType) { - if (!mimeType) return null; - - var playerType = null; - - var aMimeTypes = mimeType.splitSafe(','); - if (aMimeTypes.length == 1) - aMimeTypes = aMimeTypes[0].splitSafe(';'); - for (var i = 0; i < aMimeTypes.length; i++) { - if (mimeType.indexOf('flash') > -1) - playerType = "TypeFlash"; - else if (mimeType.indexOf('quicktime') > -1) - playerType = "TypeQT"; - else if (mimeType.indexOf('wmv') > -1) - playerType = jpf.isMac ? "TypeQT" : "TypeWmp"; - else if (mimeType.indexOf('silverlight') > -1) - playerType = "TypeSilverlight"; - - if (playerType && jpf.audio[playerType] && - jpf.audio[playerType].isSupported()) { - return playerType; - } - } - - return playerType; - }; - - /** - * Checks if a specified playerType is supported by JPF or not... - * - * @type {Boolean} - */ - this.$isSupported = function() { - return (jpf.audio[this.playerType] - && jpf.audio[this.playerType].isSupported()); - }; - - /** - * Initialize and instantiate the audio player provided by getPlayerType() - * - * @type {Object} - */ - this.$initPlayer = function() { - this.player = new jpf.audio[this.playerType](this, this.oExt, { - src : this.src, - width : this.width, - height : this.height, - autoLoad : true, - autoPlay : this.autoplay, - showControls: this.controls, - volume : this.volume, - mimeType : this.type - }); - return this; - }; - - /** - * The 'init' event hook is called when the player control has been initialized; - * usually that means that the active control (flash, QT or WMP) has been loaded - * and is ready to load a file. - * Possible initialization errors are also passed to this function. - * - * @param {Object} e Event data, specific to this hook, containing player data. - * @type {void} - */ - this.$initHook = function(e) { - if (e.error) { - var oError = this.MediaError(e.error); - if (this.dispatchEvent('error', { - error : oError, - bubbles: true - }) === false) - throw oError; - } - - this.load(); - }; - - /** - * The 'cuePoint' event hook is called when the player has set a cue point in - * the audio file. - * - * @ignore - * @type {void} - */ - this.$cuePointHook = function() {}; //ignored - - /** - * The 'playheadUpdate' event hook is called when the position of the playhead - * that is currently active (or 'playing') is updated. - * This feature is currently handled by {@link element.audio.method.$changeHook} - * - * @ignore - * @type {void} - */ - this.$playheadUpdateHook = function() {}; //ignored - - /** - * The 'error' event hook is called when an error occurs within the internals - * of the player control. - * - * @param {Object} e Event data, specific to this hook, containing player data. - * @type {void} - */ - this.$errorHook = function(e) { - jpf.console.error(e.error); - }; - - /** - * The 'progress' event hook is called when the progress of the loading sequence - * of an audio file is updated. The control signals us on how many bytes are - * loaded and how many still remain. - * - * @param {Object} e Event data, specific to this hook, containing player data. - * @type {void} - */ - this.$progressHook = function(e) { - // bytesLoaded, totalBytes - this.setProperty('bufferedBytes', {start: 0, end: e.bytesLoaded, length: e.bytesLoaded}); - this.setProperty('totalBytes', e.totalBytes); - var iDiff = Math.abs(e.bytesLoaded - e.totalBytes); - if (iDiff <= 20) - this.setProperty('readyState', jpf.Media.HAVE_ENOUGH_DATA); - }; - - /** - * The 'stateChange' event hook is called when the internal state of a control - * changes. The state of internal properties of an audio control may be - * propagated through this function. - * - * @param {Object} e Event data, specific to this hook, containing player data. - * @type {void} - */ - this.$stateChangeHook = function(e) { - //for audio, we only use this for connection errors: connectionError - if (e.state == "connectionError") { - this.networkState = jpf.Media.HAVE_NOTHING; - //this.setProperty("readyState", this.networkState); - this.$propHandlers["readyState"].call(this, this.networkState); - } - }; - - /** - * The 'change' event hook is called when a) the volume level changes or - * b) when the playhead position changes. - * - * @param {Object} e Event data, specific to this hook, containing player data. - * @type {void} - */ - this.$changeHook = function(e) { - if (typeof e.volume != "undefined") { - this.volume = e.volume; - this.muted = (e.volume > 0); - this.setProperty('volume', e.volume); - } - else { - this.duration = this.player.getTotalTime(); - this.position = e.playheadTime / this.duration; - if (isNaN(this.position)) return; - this.setProperty('position', this.position); - this.currentTime = e.playheadTime; - this.setProperty('currentTime', this.currentTime); - } - }; - - /** - * The 'complete' event hook is called when a control has finished playing - * an audio file completely, i.e. the progress is at 100%. - * - * @param {Object} e Event data, specific to this hook, containing player data. - * @type {void} - */ - this.$completeHook = function(e) { - this.paused = true; - this.setProperty('paused', true); - }; - - /** - * When a audio player signals that is has initialized properly and is ready - * to play, this function sets all the flags and behaviors properly. - * - * @param {Object} e Event data, specific to this hook, containing player data. - * @type {Object} - */ - this.$readyHook = function(e) { - this.setProperty('networkState', jpf.Media.NETWORK_LOADED); - this.setProperty('readyState', jpf.Media.HAVE_FUTURE_DATA); - this.setProperty('duration', this.player.getTotalTime()); - this.seeking = false; - this.seekable = true; - this.setProperty('seeking', false); - if (this.autoplay) - this.play(); - return this; - }; - - /** - * The 'metadata' event hook is called when a control receives metadata of an - * audio file, like ID3, waveform pattern, peak and equalizer data. - * - * @param {Object} e Event data, specific to this hook, containing player data. - * @type {void} - */ - this.$metadataHook = function(e) { - this.oVideo.setProperty('readyState', jpf.Media.HAVE_METADATA); - if (e.waveData) - this.setProperty('waveform', e.waveData); - if (e.peakData) - this.setProperty('peak', e.peakData); - if (e.eqData) - this.setProperty('EQ', e.eqData); - if (e.id3Data) - this.setProperty('ID3', e.id3Data); - }; - - /** - * Build Main Skin - * - * @type {void} - */ - this.$draw = function(){ - this.oExt = this.pHtmlNode.appendChild(document.createElement("div")); - this.oExt.className = "jpf_audio " + (this.$jml.getAttributeNode("class") || ""); - this.oInt = this.oExt; - }; - - /** - * Parse the block of JML that constructs the HTML5 compatible <AUDIO> tag - * for arguments like URL of the audio, volume, mimetype, etc. - * - * @param {XMLRootElement} x - * @type {void} - */ - this.$loadJml = function(x){ - if (this.setSource()) - this.$propHandlers["type"].call(this, this.type); - else - jpf.JmlParser.parseChildren(this.$jml, null, this); - }; - - this.$destroy = function(bRuntime) { - if (this.player && this.player.$detroy) - this.player.$destroy(); - delete this.player; - this.player = null; - - if (bRuntime) - this.oExt.innerHTML = ""; - }; -}).implement( - jpf.DataBinding, - jpf.Media -); - -jpf.audio.TypeInterface = { - properties: ["src", "volume", "showControls", "autoPlay", "totalTime", "mimeType"], - - /** - * Set and/or override the properties of this object to the values - * specified in the opions argument. - * - * @param {Object} options - * @type {Object} - */ - setOptions: function(options) { - if (options == null) return this; - // Create a hash of acceptable properties - var hash = this.properties; - for (var i = 0; i < hash.length; i++) { - var prop = hash[i]; - if (options[prop] == null) continue; - this[prop] = options[prop]; - } - return this; - }, - - /** - * Utility method; get an element from the browser's document object, by ID. - * - * @param {Object} id - * @type {HTMLDomElement} - */ - getElement: function(id) { - var elem; - - if (typeof id == "object") - return id; - if (jpf.isIE) - return window[id]; - else { - elem = document[id] ? document[id] : document.getElementById(id); - if (!elem) - elem = jpf.lookup(id); - return elem; - } - } -}; - - - -/*FILEHEAD(/var/lib/jpf/src/elements/grid.js)SIZE(-1077090856)TIME(1238944817)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-/**
- * Any child element of this element is placed in a grid. The size of the
- * columns and rows of the grid can be set by attributes. Child elements can
- * span multiple columns. Using '*' as a size indicator will use the remaining
- * size for that column or row, when the grid's size is set.
- * Example:
- * This example shows a window with a grid and two buttons that change the
- * orientation of the grid runtime. The textarea and it's label have a span set
- * to '*'. This means they will span the entire width of all columns, no matter
- * how many columns there are.
- * <code>
- * <j:window> - * <j:grid id="gridTest"
- * columns = "80, *"
- * margin = "10 10 10 10"
- * padding = "5"
- * bottom = "35"
- * top = "0"> - * <j:label>Name</j:label> - * <j:textbox /> - * <j:label>Address</j:label> - * <j:textarea height="50" /> - * <j:label>Country</j:label> - * <j:dropdown /> - * - * <j:label span="*">Message</j:label> - * <j:textarea id="txtMessage" - * height = "*" - * span = "*" /> - * </j:grid> - * - * <j:button - * caption = "Two Columns" - * onclick = "gridTest.setAttribute('columns', '80, *');"/> - * - * <j:button - * caption = "Four Columns" - * onclick = "gridTest.setAttribute('columns', '60, 120, 60, *');"/> - * </j:window>
- * </code>
- * Remarks:
- * This is one of three positioning methods.
- * See {@link baseclass.alignment}
- * See {@link baseclass.anchoring}
- *
- * @define grid
- * @allowchild {elements}, {anyjml}
- * @addnode elements
- * @constructor
- *
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 1.0
- */
-jpf.grid = jpf.component(jpf.NODE_VISIBLE, function(){
- var id;
- var update = false;
- var l = jpf.layout;
- var _self = this;
- var updater = {
- $updateLayout : function(){
- _self.$updateGrid();
- }
- };
-
- /**** Properties and Attributes ****/
-
- this.canHaveChildren = true;
- this.$focussable = false;
-
- this.columns = "100,*";
- this.padding = 2;
- this.margin = "5 5 5 5";
- this.cellheight = 19;
-
- /**
- * @attribute {String} columns a comma seperated list of column sizes. A column size can be specified in a number (size in pixels) or using a number and a % sign to indicate a percentage. A '*' indicates the column spans the rest space. There can be only one '*' in the column string.
- * Example:
- * <code>
- * <j:grid columns="150, *, 20%" />
- * </code>
- * @attribute {String} padding the space between each element.
- * @attribute {String} margin the space between the container and the elements, space seperated in pixels for each side. Similar to css in the sequence top right bottom left.
- * Example:
- * <code>
- * <j:grid margin="10 10 40 10" />
- * </code>
- * @attribute {String} cellheight the default height of each element. This can be overriden by setting a height on an element. The height will always size all elements of the same row.
- */
- this.$supportedProperties.push("columns", "padding", "margin",
- "cellheight", "span");
-
- var jmlHideShow =
- this.$updateTrigger =
- this.$propHandlers["columns"] =
- this.$propHandlers["padding"] =
- this.$propHandlers["margin"] =
- this.$propHandlers["cellheight"] = function(value){
- if (!update && jpf.loaded)
- l.queue(_self.oExt, updater);
- update = true;
- };
-
- /**** DOM Hooks ****/
-
- this.$domHandlers["removechild"].push(function(jmlNode, doOnlyAdmin){
- if (doOnlyAdmin)
- return;
-
- jmlNode.$propHandlers["width"] =
- jmlNode.$propHandlers["height"] =
- jmlNode.$propHandlers["span"] = null;
-
- jmlNode.$hide = jmlNode.$_hide;
- jmlNode.$show = jmlNode.$_show;
-
- /* Removing is probably not a good idea, because we're not sure if the node is reparented
- if (jmlNode.hasFeature(__ALIGNMENT__) && jmlNode.aData)
- jmlNode.enableAlignment();
- */
-
- if (jmlNode.hasFeature(__ANCHORING__) && jmlNode.$hasAnchorRules())
- jmlNode.$setAnchoringEnabled();
-
- l.queue(this.oExt, updater);
- update = true;
- });
-
- this.$domHandlers["insert"].push(function(jmlNode, bNode, withinParent){
- if (withinParent)
- return;
-
- if (mlNode.hasFeature(__ALIGNMENT__) && jmlNode.aData)
- jmlNode.disableAlignment();
-
- else if (jmlNode.hasFeature(__ANCHORING__) && jmlNode.$hasAnchorRules())
- jmlNode.disableAnchoring();
-
- /**
- * @define jpf.JmlElement
- * @attribute {String} span the number of columns this element spans. Only used inside a grid element.
- * @attribute {String} width
- * Remarks:
- * When used as a child of a grid element the width can also be set as '*'. This will fill the rest space.
- * @attribute {String} height
- * Remarks:
- * When used as a child of a grid element the height can also be set as '*'. This will fill the rest space.
- */
-
- jmlNode.$propHandlers["width"] =
- jmlNode.$propHandlers["height"] =
- jmlNode.$propHandlers["span"] = updateTrigger;
-
- jmlNode.$_hide = jmlNode.$hide;
- jmlNode.$_show = jmlNode.$show;
- jmlNode.$hide = jmlHideShow;
- jmlNode.$show = jmlHideShow;
-
- l.queue(this.oExt, updater);
- update = true;
- });
-
-
- /**
- * @macro
- */
- function setPercentage(expr, value){
- return typeof expr == "string"
- ? expr.replace(jpf.percentageMatch, "((" + value + " * $1)/100)")
- : expr;
- }
-
- this.$updateGrid = function(){
- if (!update)
- return;
-
- //@todo when not visible make all property settings rule based
-
- var pWidth = "pWidth";
- var pHeight = "pHeight";
-
- this.cellheight = parseInt(this.cellheight);
- var cols = setPercentage(this.columns, pWidth).split(/\s*,\s*/);
- var collength = cols.length;
- var margin = jpf.getBox(this.margin);
- var rowheight = [];
- this.padding = parseInt(this.padding);
-
- var oCols = [];
- var col, row, oExt, diff, j, m, cellInfo;
- this.ids = [this.oExt];
- var span, jNode, jNodes = this.childNodes;
- for (var nodes = [], c = 0, i = 0, l = jNodes.length; i < l; i++) {
- jNode = jNodes[i];
- if (jNode.nodeFunc != jpf.NODE_VISIBLE || !jNode.visible)
- continue;
-
- if (jNode.hasFeature(__ANCHORING__))
- jNode.disableAnchoring();
-
- m = jpf.getBox(jNode.getAttribute("margin"));
- //for (j = 0; j < 4; j++)
- //m[j] += this.padding;
-
- diff = jpf.getDiff(jNode.oExt);
- oExt = jNode.oExt;
- if (!oExt.getAttribute("id"))
- jpf.setUniqueHtmlId(oExt);
- if (jpf.isIE)
- oExt.style.position = "absolute"; //Expensive
-
- span = jNode.getAttribute("span");
-
- cellInfo = {
- span : span == "*" ? collength : parseInt(span) || 1,
- m : m,
- height : setPercentage(jNode.height, pHeight),
- width : jNode.width,
- oHtml : oExt,
- hordiff : diff[0],
- verdiff : diff[1],
- id : (jpf.hasHtmlIdsInJs
- ? oExt.getAttribute("id")
- : "document.getElementById('" + oExt.getAttribute("id") + "')")
- //"ids[" + (this.ids.push(oExt) - 1) + "]"
- }
-
- nodes.push(cellInfo);
-
- row = Math.floor(c / collength);
- c += cellInfo.span; //no check on span overflow
-
- if (cellInfo.height == "*" || rowheight[row] == "*") {
- rowheight[row] = "*";
- cellInfo.height = null;
- }
- else if(cellInfo.height && parseInt(cellInfo.height) != cellInfo.height) {
- rowheight[row] = cellInfo.height;
- }
- else if(typeof rowheight[row] != "string") {
- rowheight[row] = Math.max(rowheight[row] || 0,
- parseFloat(cellInfo.height || this.cellheight)
- + cellInfo.m[0] + cellInfo.m[2]);
- }
- }
- var dt = new Date().getTime();
-
- if (nodes.length == 0)
- return;
-
- var total, combCol, fillCol = null, fillRow = null;
- var rule = [
- "var ids = jpf.all[" + this.uniqueId + "].ids",
- "var total = 0, pHeight = ids[0].offsetHeight - "
- + ((rowheight.length - 1) * this.padding + margin[0] + margin[2]),
- "var pWidth = ids[0].offsetWidth - "
- + ((collength - 1) * this.padding + margin[1] + margin[3])
- ];
-
- /*for (i = 0; i < this.ids.length; i++) {
- rule.push("var item" + i + " = ids[" + i + "]");
- }*/
-
- //Set column widths (only support for one *)
- for (total = 0, i = 0; i < collength; i++) {
- if (cols[i] == "*")
- fillCol = i;
- else {
- if (parseFloat(cols[i]) != cols[i]) {
- rule.push("var colw" + i + "; total += colw"
- + i + " = " + cols[i]);
- cols[i] = "colw" + i;
- }
- else
- total += cols[i] = parseFloat(cols[i]);
- }
- }
- if (fillCol !== null) {
- rule.push("var colw" + fillCol + " = " + pWidth
- + " - total - " + total);
- cols[fillCol] = "colw" + fillCol;
- }
-
- //Set column start position
- var colstart = [margin[3]];
- rule.push("var coll0 = " + margin[3]);
- for (i = 1; i < collength; i++) {
- if (typeof colstart[i-1] == "number" && typeof cols[i-1] == "number") {
- colstart[i] = colstart[i-1] + cols[i-1] + this.padding;
- }
- else {
- rule.push("var coll" + i + " = coll" + (i - 1) + " + colw"
- + (i - 1) + " + " + this.padding);
- colstart[i] = "coll" + i;
- }
- }
-
- //Set row heights
- rule.push("total = 0");
- var needcalc = false;
- for (total = 0, i = 0; i < rowheight.length; i++) {
- if (rowheight[i] == "*")
- fillRow = i;
- else {
- if (parseFloat(rowheight[i]) != rowheight[i]) {
- needcalc = true;
- rule.push("var rowh" + i + "; total += rowh"
- + i + " = " + rowheight[i]);
- rowheight[i] = "rowh" + i;
- }
- else
- total += rowheight[i] = parseFloat(rowheight[i]);
- }
- }
- if (fillRow !== null) {
- needcalc = true;
- rule.push("var rowh" + fillRow + " = " + pHeight
- + " - total - " + total);
- rowheight[fillRow] = "rowh" + fillRow;
- }
-
- if (!needcalc)
- this.oExt.style.height = (total + ((rowheight.length-1) * this.padding) + margin[0] + margin[2]) + "px";
-
- //Set column start position
- var rowstart = [margin[0]];
- rule.push("var rowt0 = " + margin[0]);
- for (i = 1; i < rowheight.length; i++) {
- if (typeof rowstart[i-1] == "number" && typeof rowheight[i-1] == "number") {
- rowstart[i] = rowstart[i-1] + rowheight[i-1] + this.padding;
- }
- else {
- rule.push("var rowt" + i + " = rowt" + (i - 1) + " + rowh"
- + (i - 1) + " + " + this.padding);
- rowstart[i] = "rowt" + i;
- }
- }
-
- //Set all cells
- for (c = 0, i = 0; i < nodes.length; i++) {
- cellInfo = nodes[i]
- col = c % collength;
- row = Math.floor(c / collength);
- c += cellInfo.span; //no check on span overflow
- id = cellInfo.id;
-
- //Top
- if (typeof rowstart[row] == "number")
- cellInfo.oHtml.style.top = (rowstart[row] + cellInfo.m[0]) + "px";
- else
- rule.push(id + ".style.top = rowt"
- + row + " + " + cellInfo.m[0] + " + 'px'");
-
- //Left
- if (typeof colstart[col] == "number")
- cellInfo.oHtml.style.left = (colstart[col] + cellInfo.m[3]) + "px";
- else
- rule.push(id + ".style.left = coll"
- + col + " + " + cellInfo.m[3] + " + 'px'");
-
- //Width
- if (cellInfo.span && cellInfo.span > 1 && !cellInfo.width) {
- var cTotal = 0;
- for (combCol = [], j = 0; j < cellInfo.span; j++) {
- if (typeof cols[col + j] == "number") {
- cTotal += cols[col + j];
- }
- else {
- combCol.push("colw" + (col + j));
- cTotal -= 1000000;
- }
-
- //if (j != cellInfo.span - 1)
- //cTotal += this.padding;
- }
-
- var spanPadding = (cellInfo.span - 1) * this.padding;
- if (cTotal > 0) {
- cellInfo.oHtml.style.width = (cTotal
- + spanPadding - (cellInfo.m[1] + cellInfo.m[3]
- + cellInfo.hordiff)) + "px";
- }
- else {
- if (cTotal > -1000000)
- combCol.push(cTotal + 1000000);
- rule.push(id + ".style.width = (" + combCol.join(" + ")
- + " + " + spanPadding + " - " + (cellInfo.m[1] + cellInfo.m[3]
- + cellInfo.hordiff) + ") + 'px'");
- }
- }
- else {
- if (parseFloat(cellInfo.width) == cellInfo.width
- || typeof cols[col] == "number")
- cellInfo.oHtml.style.width = ((cellInfo.width || cols[col])
- - (cellInfo.m[1] + cellInfo.m[3] + cellInfo.hordiff)) + "px";
- else
- rule.push(id + ".style.width = ("
- + (cellInfo.width || "colw" + col) + " - "
- + (cellInfo.m[1] + cellInfo.m[3] + cellInfo.hordiff)
- + ") + 'px'");
- }
-
- //Height
- if (parseFloat(cellInfo.height) == cellInfo.height
- || typeof rowheight[row] == "number")
- cellInfo.oHtml.style.height = ((cellInfo.height || rowheight[row])
- - (cellInfo.m[0] + cellInfo.m[2] + cellInfo.verdiff)) + "px";
- else
- rule.push(id + ".style.height = ("
- + (cellInfo.height || "rowh" + row) + " - "
- + (cellInfo.m[0] + cellInfo.m[2] + cellInfo.verdiff)
- + ") + 'px'");
- }
-
- //rule.join("\n"), true);
- jpf.layout.setRules(this.oExt, "grid", (rule.length
- ? "try{" + rule.join(";}catch(e){};\ntry{") + ";}catch(e){};"
- : ""), true);
-
- //Set size of grid if necesary here...
- update = false;
- };
-
- this.$draw = function(){
- this.oExt = this.pHtmlNode.appendChild(document.createElement("div"));
- this.oExt.className = "grid " + (this.$jml.getAttributeNode("class") || "");
- this.oInt = this.oExt;
-
- if (!this.oExt.getAttribute("id"))
- jpf.setUniqueHtmlId(this.oExt);
-
- id = jpf.hasHtmlIdsInJs
- ? this.oExt.getAttribute("id")
- : "document.getElementById('" + this.oExt.getAttribute("id") + "')";
-
- //this.oExt.style.height = "80%"
- this.oExt.style.top = 0;
- this.oExt.style.position = "relative";
- this.oExt.style.minHeight = "10px";
-
- if (this.$jml.getAttribute("class"))
- jpf.setStyleClass(this.oExt, this.$jml.getAttribute("class"));
-
- if (!jpf.isIE && !jpf.grid.$initedcss) {
- jpf.importCssString(document, ".grid>*{position:absolute}");
- jpf.grid.$initedcss = true;
- }
- };
-
- this.$loadJml = function(x){
- jpf.JmlParser.parseChildren(x, this.oInt, this, true);
-
- if (!this.width && (jpf.getStyle(this.oExt, "position") == "absolute"
- || this.left || this.top || this.right || this.bottom || this.anchors))
- this.oExt.style.width = "100%"
-
- var jmlNode, nodes = this.childNodes;
- for (var i = 0, l = nodes.length; i < l; i++) {
- jmlNode = nodes[i];
- jmlNode.$_hide = jmlNode.$hide;
- jmlNode.$_show = jmlNode.$show;
- jmlNode.$hide = jmlHideShow;
- jmlNode.$show = jmlHideShow;
- }
-
- this.$updateGrid();
- };
-});
-
- - -/*FILEHEAD(/var/lib/jpf/src/elements/teleport.js)SIZE(-1077090856)TIME(1238933683)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -/** - * Element which specifies the ways the application can communicate to remote - * data sources. - * - * @define teleport - * @addnode global - * @allowchild {teleport} - * - * @default_private - */ -jpf.teleport = { - tagName : "teleport", - nodeFunc : jpf.NODE_HIDDEN, - - modules: new Array(), - named: {}, - - register: function(obj){ - var id = false, data = { - obj: obj - }; - - return this.modules.push(data) - 1; - }, - - getModules: function(){ - return this.modules; - }, - - getModuleByName: function(defname){ - return this.named[defname] - }, - - // Load Teleport Definition - loadJml: function(x, parentNode){ - this.$jml = x; - - this.parentNode = parentNode; - jpf.inherit.call(this, jpf.JmlDom); /** @inherits jpf.JmlDom */ - - var id, obj, nodes = this.$jml.childNodes; - for (var i = 0; i < nodes.length; i++) { - if (nodes[i].nodeType != 1) - continue; - - obj = new jpf.BaseComm(nodes[i]); - - if (id = nodes[i].getAttribute("id")) - jpf.setReference(id, obj); - } - - this.loaded = true; - - if (this.onload) - this.onload(); - - return this; - }, - - availHTTP : [], - releaseHTTP: function(http){ - if (jpf.brokenHttpAbort) - return; - if (self.XMLHttpRequestUnSafe && http.constructor == XMLHttpRequestUnSafe) - return; - - http.onreadystatechange = function(){}; - http.abort(); - this.availHTTP.push(http); - }, - - destroy: function(){ - jpf.console.info("Cleaning teleport"); - - for (var i = 0; i < this.availHTTP.length; i++) { - this.availHTTP[i] = null; - } - } -}; - -/** - * @constructor - * @baseclass - * @private - */ -jpf.BaseComm = function(x){ - jpf.makeClass(this); - this.uniqueId = jpf.all.push(this) - 1; - this.$jml = x; - - /** - * Returns a string representation of this object. - */ - this.toString = function(){ - return "[Javeline Teleport Component : " + (this.name || "") - + " (" + this.type + ")]"; - } - - if (this.$jml) { - this.name = x.getAttribute("id"); - this.type = x[jpf.TAGNAME]; - - // Inherit from the specified baseclass - if (!jpf[this.type]) - throw new Error(jpf.formatErrorString(1023, null, "Teleport baseclass", "Could not find Javeline Teleport Component '" + this.type + "'", this.$jml)); - - this.inherit(jpf[this.type]); - if (this.useHTTP) { - // Inherit from HTTP Module - if (!jpf.http) - throw new Error(jpf.formatErrorString(1024, null, "Teleport baseclass", "Could not find Javeline Teleport HTTP Component", this.$jml)); - this.inherit(jpf.http); - } - - if (this.$jml.getAttribute("protocol")) { - // Inherit from Module - var proto = this.$jml.getAttribute("protocol").toLowerCase(); - if (!jpf[proto]) - throw new Error(jpf.formatErrorString(1025, null, "Teleport baseclass", "Could not find Javeline Teleport RPC Component '" + proto + "'", this.$jml)); - this.inherit(jpf[proto]); - } - } - - // Load Comm definition - if (this.$jml) - this.load(this.$jml); -}; - - -jpf.Init.run('Teleport'); - - -/*FILEHEAD(/var/lib/jpf/src/elements/insert.js)SIZE(-1077090856)TIME(1228157748)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-/**
- * Databound element displaying it's textual content directly in the
- * position it's placed without drawing any containing elements.
- *
- * @constructor
- * @define output, insert
- * @addnode elements
- *
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.9
- */
-
-jpf.output =
-jpf.insert = function(pHtmlNode, tagName){
- jpf.register(this, tagName || "insert", jpf.NODE_VISIBLE);/** @inherits jpf.Class */
- this.pHtmlNode = pHtmlNode || document.body;
- this.pHtmlDoc = this.pHtmlNode.ownerDocument;
-
- /* ***********************
- Inheritance
- ************************/
- this.editableParts = {
- "main": [["caption", "text()"]]
- };
- this.inherit(jpf.DataBinding); /** @inherits jpf.DataBinding */
- /* ********************************************************************
- PROPERTIES
- *********************************************************************/
- /* ********************************************************************
- PUBLIC METHODS
- *********************************************************************/
- this.getValue = function(){
- return this.value;
- };
-
- this.setValue = function(value){
- this.value = value;
- //pHtmlNode.innerHTML = value;
- this.oTxt.nodeValue = value;
- };
-
- this.$supportedProperties.push("value");
- this.$propHandlers["value"] = function(value){
- this.oTxt.nodeValue = value;
- };
-
- /* ***************
- DATABINDING
- ****************/
- this.mainBind = "caption";
-
- this.$xmlUpdate = function(action, xmlNode, listenNode, UndoObj){
- //Action Tracker Support
- if (UndoObj)
- UndoObj.xmlNode = this.xmlRoot;
-
- //Refresh Properties
- this.setValue(this.applyRuleSetOnNode("caption", this.xmlRoot) || "");
- };
-
- this.$load = function(node){
- /*
- absolutely weird behaviour when bind="" is set.
- This function is loaded twice. First with some xml,
- dunno why it's selected or called
- */
- //Add listener to XMLRoot Node
- jpf.xmldb.addNodeListener(node, this);
-
- var value = this.applyRuleSetOnNode("caption", node);
- this.setValue(value || typeof value == "string" ? value : "");
- };
-
- /* *********
- INIT
- **********/
- this.inherit(jpf.JmlElement); /** @inherits jpf.JmlElement */
- this.$draw = function(){
- //Build Main Skin
- this.oInt = this.oExt = pHtmlNode;
- this.oTxt = document.createTextNode("");
- pHtmlNode.appendChild(this.oTxt);
- };
-
-
- this.$loadJml = function(x){
- if (x.firstChild) {
- if (x.childNodes.length > 1 || x.firstChild.nodeType == 1) {
- this.setValue("");
- jpf.JmlParser.parseChildren(x, this.oExt, this);
- }
- else
- this.setValue(x.firstChild.nodeValue);
- }
-
- //this.$makeEditable("main", this.oExt, this.$jml);
- };
-}
-
- - -/*FILEHEAD(/var/lib/jpf/src/elements/datagrid.js)SIZE(-1077090856)TIME(1239018292)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -/** - * Element providing a sortable, selectable grid containing scrollable - * information. Grid columns can be reordered and resized. - * - * @constructor - * @define datagrid, spreadsheet, propedit - * @addnode elements - * - * @author Ruben Daniels - * @version %I%, %G% - * @since 0.4 - * - * @inherits jpf.MultiSelect - * @inherits jpf.Cache - * @inherits jpf.Presentation - * @inherits jpf.DataBinding - * @inherits jpf.DragDrop - * @inherits jpf.Rename - * - * @event beforelookup Fires before the value lookup UI is shown.. - * cancellable: Prevents the lookup value from being processed. - * object: - * {String} value the value that has been found. - * {XMLElement} xmlNode the selected node. - * {HTMLElement} htmlNode the node that is updated. - * @event afterlookup Fires after a lookup value is processed. - * object: - * {Mixed} value the value that has been found. - * {XMLElement} xmlNode the selected node. - * {HTMLElement} htmlNode the node that is updated. - * {Nodeset} nodes ???. - * @event multiedit Fires before a multiedit request is done. Used to display the UI. - * object: - * {XMLElement} xmlNode the selected node. - * {XMLElement} dataNode the xml data element. - * Example: - * <code> - * <j:propedit - * lookupjml = "tmpLookup" - * onbeforelookup = "clearLookup(event.xmlNode, event.value)" - * onafterlookup = "loadLookup(event.xmlNode, event.value, this)" - * onmultiedit = "loadMultiEdit(event, this)"> - * <j:bindings> - * <j:template select="self::product" value="mdlProps:product" /> - * </j:bindings> - * </j:propedit> - * - * <j:template id="tmpLookup" autoinit="true"> - * <j:list id="lstLookup" skin="mnulist" style="width:auto;margin-bottom:3px" - * model="mdlLookup" empty-message="No results" height="{lstLookup.length * 20}" - * autoselect="false"> - * <j:bindings> - * <j:caption select="self::picture"><![CDATA[ - * {name} | {description} - * ]]></j:caption> - * <!-- use @descfield --> - * <j:caption><![CDATA[[ - * var field = n.parentNode.getAttribute("descfield"); - * %(value(field) || "[Geen Naam]"); - * ]]]></j:caption> - * <j:icon select="self::product" value="package_green.png" /> - * <j:icon value="table.png" /> - * <j:traverse select="node()[local-name()]" /> - * </j:bindings> - * <j:actions /> - * </j:list> - * - * <j:toolbar> - * <j:bar> - * <j:button id="btnLkpPrev" disabled="true" - * onclick="...">< Previous</j:button> - * <j:spinner id="spnLookup" width="40" - * min="1" max="1" onafterchange="..." /> - * <j:button id="btnLkpNext" disabled="true" - * onclick="...">Next ></j:button> - * </j:bar> - * </j:toolbar> - * </j:template> - * </code> - * @binding caption Determines the caption of a node. - * @binding css Determines a css class for a node. - * Example: - * In this example a node is bold when the folder contains unread messages: - * <code> - * <j:list> - * <j:bindings> - * <j:caption select="@caption" /> - * <j:css select="message[@unread]" value="highlighUnread" /> - * <j:icon select="@icon" /> - * <j:icon select="self::folder" value="icoFolder.gif" /> - * <j:traverse select="folder" /> - * </j:bindings> - * </j:list> - * </code> - * @binding invalidmsg Determines the error message that is shown when a cell is not valid. - * @binding description Determines the text that is displayed under the expanded row. - * @binding template Determines the template that sets the column definition (for the datagrid) or property definition (for property editor). - - */ -jpf.propedit = -jpf.spreadsheet = -jpf.datagrid = jpf.component(jpf.NODE_VISIBLE, function(){ - this.$focussable = true; // This object can get the focus - this.multiselect = true; // Enable MultiSelect - this.bufferselect = false; - - this.startClosed = true; - this.animType = jpf.tween.NORMAL; - this.animSteps = 3; - this.animSpeed = 20; - - var colspan = 0, //@todo unused? - totalWidth = 0, //@todo unused? - _self = this, - curBtn; - - this.headings = []; - - this.$renameStartCollapse = false; - - this.dynCssClasses = []; - - this.$booleanProperties["cellselect"] = true; - this.$booleanProperties["celledit"] = true; - this.$booleanProperties["iframe"] = true; - - this.$propHandlers["template"] = function(value){ - this.smartBinding = value ? true : false; - this.namevalue = true; - - this.$initTemplate(); - this.$loaddatabinding(); - - if (this.bindingRules["traverse"]) - this.parseTraverse(this.bindingRules["traverse"][0]); - }; - - this.$initTemplate = function(){ - if (!this.hasFeature(__VALIDATION__)) { - this.inherit(jpf.Validation); - - var vRules = {}; - var rules = ["required", "datatype", - "pattern", "min", "max", "maxlength", "minlength", "checkequal"]; - - var ruleContext; - this.$fValidate = function(){}; - this.$setRule = function(type, rule){ - var vId = ruleContext.vIds[type]; - - if (!rule) { - if (vId) - ruleContext.vRules[vId] = ""; - return; - } - - if (!vId) - ruleContext.vIds[type] = ruleContext.vRules.push(rule) - 1; - else - ruleContext.vRules[vId] = rule; - } - - this.addEventListener("afterrename", function(e){ - if (this.isValid(null, this.selected)) - this.clearError(); - else - this.setError(); - }); - - this.$propHandlers["required"] = function(value, type){ - if (!type || type == "text") - this.$setRule("required", "value.trim().length > 0"); - else - this.$setRule("required", "valueNode"); - } - - function cacheValidRules(cacheId, nodes){ - var i, j, v, l, r = [], node, type; - for (j = 0; j < rules.length; j++) { - if (_self.bindingRules[rules[j]]) - r.push(rules[j]); - } - var rlength = r.length; - var checkRequired = r.contains("required"); - - var contexts = []; - for (i = 0, l = nodes.length; i < l; i++) { - node = nodes[i]; - type = node.getAttribute("type"); - ruleContext = { - xmlNode : node, - select : node.getAttribute("select"), - vIds : {}, - vRules : [] - }; - contexts.push(ruleContext); - - if (type && type != "text") { - if (checkRequired) { - v = _self.applyRuleSetOnNode("required", node); - if (v) - _self.$propHandlers["required"].call(_self, v, type); - } - continue; - } - - for (j = 0; j < rlength; j++) { - v = _self.applyRuleSetOnNode(r[j], node); - if (v) - _self.$propHandlers[r[j]].call(_self, v); - } - } - - return contexts; - } - - this.isValid = function(checkRequired, node){ - if (!this.xmlRoot || !this.xmlData || this.disabled) - return true; - - var nodes, isValid = true; - var cacheId = this.xmlRoot.getAttribute(jpf.xmldb.xmlIdTag); - if (!vRules[cacheId] || !vRules[cacheId].length) - vRules[cacheId] = cacheValidRules(cacheId, - (nodes = this.getTraverseNodes())); - else - nodes = node ? [node] : (nodes || this.getTraverseNodes()); - - if (!this.xmlData) - return true; - - this.validityState.$reset(); - - var i, l, isValid = true, rule, node, value, type, valueNode; - var rules = vRules[cacheId]; - for (i = 0, l = nodes.length; i < l; i++) { - node = nodes[i]; - rule = rules[i]; - type = node.getAttribute("type"); - valueNode = this.xmlData.selectSingleNode(jpf.getXmlValue(node, "@select|field/@select")); - value = (!type || type == "text") - ? jpf.getXmlValue(valueNode, '.') - : null; - - for (var type in rule.vIds) { - if ((type == "required" && checkRequired || value) - && !eval(rule.vRules[rule.vIds[type]])) { - this.validityState.$set(type); - isValid = false; - } - } - - //@todo make this work for non html5 validation - if (!isValid) { - this.validityState.errorHtml = jpf.xmldb.findHTMLNode(node, this).childNodes[1]; - this.validityState.errorXml = node; - this.invalidmsg = this.applyRuleSetOnNode("invalidmsg", node); - break; - } - } - - - if (!isValid) - this.dispatchEvent("invalid", this.validityState); - else { - this.validityState.valid = true; - isValid = true; - } - - return isValid; - }; - - var vgroup = jpf.xmldb.getInheritedAttribute(this.$jml, "validgroup"); - if (vgroup) - this.$propHandlers["validgroup"].call(this, vgroup); - } - } - - /** - * This method imports a stylesheet defined in a multidimensional array - * @param {Array} def Required Multidimensional array specifying - * @param {Object} win Optional Reference to a window - * @method - * @deprecated - */ - function importStylesheet(def, win){ - for (var i = 0; i < def.length; i++) { - if (!def[i][1]) continue; - - if (jpf.isIE) - (win || window).document.styleSheets[0].addRule(def[i][0], - def[i][1]); - else - (win || window).document.styleSheets[0].insertRule(def[i][0] - + " {" + def[i][1] + "}", 0); - } - } - - function scrollIntoView(){ - var Q = (this.current || this.$selected); - var o = this.oInt; - o.scrollTop = (Q.offsetTop)-21; - } - - /**** Keyboard Support ****/ - - function keyHandler(e){ - var key = e.keyCode; - var ctrlKey = e.ctrlKey; - var shiftKey = e.shiftKey; - var selHtml = this.$selected || this.$indicator; - - if (!e.force && (!selHtml || this.renaming)) //@todo how about allowdeselect? - return; - - var selXml = this.indicator || this.selected; - var oInt = useiframe ? this.oDoc.documentElement : this.oInt; - - switch (key) { - case 13: - if (this.$tempsel) - this.selectTemp(); - - this.choose(selHtml); - break; - case 32: - //if (ctrlKey || this.mode) - this.select(this.indicator, true); - break; - case 109: - case 46: - //DELETE - if (this.disableremove) - return; - - if (this.celledit) { - this.rename(this.indicator || this.selected, ""); - return; - } - - if (this.$tempsel) - this.selectTemp(); - - this.remove(this.mode ? this.indicator : null); //this.mode != "check" - break; - case 36: - //HOME - this.select(this.getFirstTraverseNode(), false, shiftKey); - this.oInt.scrollTop = 0; - break; - case 35: - //END - this.select(this.getLastTraverseNode(), false, shiftKey); - this.oInt.scrollTop = this.oInt.scrollHeight; - break; - case 107: - //+ - if (this.more) - this.startMore(); - break; - case 37: - //LEFT - if (this.$tempsel) - this.selectTemp(); - - if (this.cellselect) { - if (lastcell) { - if (lastcell.previousSibling) { - this.selectCell({target:lastcell.previousSibling}, - this.$selected); - } - } - else { - this.selectCell({target:this.$selected.firstChild}, - this.$selected); - } - } - else if (this.$withContainer) - this.slideToggle(this.$indicator || this.$selected, 2) - break; - case 107: - case 39: - //RIGHT - if (this.$tempsel) - this.selectTemp(); - - if (this.cellselect) { - if (lastcell) { - if (lastcell.nextSibling) { - this.selectCell({target:lastcell.nextSibling}, - this.$selected); - } - } - else { - this.selectCell({target:this.$selected.firstChild}, - this.$selected); - } - } - else if (this.$withContainer) - this.slideToggle(this.$indicator || this.$selected, 1) - - break; - case 38: - //UP - if (!selXml && !this.$tempsel) - return; - - var node = this.$tempsel - ? jpf.xmldb.getNode(this.$tempsel) - : selXml; - - var margin = jpf.getBox(jpf.getStyle(selHtml, "margin")); - var hasScroll = oInt.scrollHeight > oInt.offsetHeight; - var items = Math.floor((oInt.offsetWidth - - (hasScroll ? 15 : 0)) / (selHtml.offsetWidth - + margin[1] + margin[3])); - - node = this.getNextTraverseSelected(node, false, items); - if (node) - this.setTempSelected(node, ctrlKey, shiftKey); - else return; - - selHtml = jpf.xmldb.findHTMLNode(node, this); - if (selHtml.offsetTop < oInt.scrollTop) { - oInt.scrollTop = Array.prototype.indexOf.call(this.getTraverseNodes(), node) < items - ? 0 - : selHtml.offsetTop - margin[0]; - } - break; - case 40: - //DOWN - if (!selXml && !this.$tempsel) - return; - - var node = this.$tempsel - ? jpf.xmldb.getNode(this.$tempsel) - : selXml; - - var margin = jpf.getBox(jpf.getStyle(selHtml, "margin")); - var hasScroll = oInt.scrollHeight > oInt.offsetHeight; - var items = Math.floor((oInt.offsetWidth - - (hasScroll ? 15 : 0)) / (selHtml.offsetWidth - + margin[1] + margin[3])); - - node = this.getNextTraverseSelected(node, true, items); - if (node) - this.setTempSelected(node, ctrlKey, shiftKey); - else return; - - selHtml = jpf.xmldb.findHTMLNode(node, this); - if (selHtml.offsetTop + selHtml.offsetHeight - > oInt.scrollTop + oInt.offsetHeight) // - (hasScroll ? 10 : 0) - oInt.scrollTop = selHtml.offsetTop - - oInt.offsetHeight + selHtml.offsetHeight - + margin[0]; //+ (hasScroll ? 10 : 0) - - break; - case 33: - //PGUP - if (!selXml && !this.$tempsel) - return; - - var node = this.$tempsel - ? jpf.xmldb.getNode(this.$tempsel) - : selXml; - - var margin = jpf.getBox(jpf.getStyle(selHtml, "margin")); - var hasScrollY = oInt.scrollHeight > oInt.offsetHeight; - var hasScrollX = oInt.scrollWidth > oInt.offsetWidth; - var items = Math.floor((oInt.offsetWidth - - (hasScrollY ? 15 : 0)) / (selHtml.offsetWidth - + margin[1] + margin[3])) || 1; - var lines = Math.floor((oInt.offsetHeight - - (hasScrollX ? 15 : 0)) / (selHtml.offsetHeight - + margin[0] + margin[2])); - - node = this.getNextTraverseSelected(node, false, items * lines); - if (!node) - node = this.getFirstTraverseNode(); - if (node) - this.setTempSelected(node, ctrlKey, shiftKey); - else return; - - selHtml = jpf.xmldb.findHTMLNode(node, this); - if (selHtml.offsetTop < oInt.scrollTop) { - oInt.scrollTop = Array.prototype.indexOf.call(this.getTraverseNodes(), node) < items - ? 0 - : selHtml.offsetTop - margin[0]; - } - break; - case 34: - //PGDN - if (!selXml && !this.$tempsel) - return; - - var node = this.$tempsel - ? jpf.xmldb.getNode(this.$tempsel) - : selXml; - - var margin = jpf.getBox(jpf.getStyle(selHtml, "margin")); - var hasScrollY = oInt.scrollHeight > oInt.offsetHeight; - var hasScrollX = oInt.scrollWidth > oInt.offsetWidth; - var items = Math.floor((oInt.offsetWidth - (hasScrollY ? 15 : 0)) - / (selHtml.offsetWidth + margin[1] + margin[3])) || 1; - var lines = Math.floor((oInt.offsetHeight - (hasScrollX ? 15 : 0)) - / (selHtml.offsetHeight + margin[0] + margin[2])); - - node = this.getNextTraverseSelected(selXml, true, items * lines); - if (!node) - node = this.getLastTraverseNode(); - if (node) - this.setTempSelected(node, ctrlKey, shiftKey); - else return; - - selHtml = jpf.xmldb.findHTMLNode(node, this); - if (selHtml.offsetTop + selHtml.offsetHeight - > oInt.scrollTop + oInt.offsetHeight) // - (hasScrollY ? 10 : 0) - oInt.scrollTop = selHtml.offsetTop - - oInt.offsetHeight + selHtml.offsetHeight - + margin[0]; //+ 10 + (hasScrollY ? 10 : 0) - break; - - default: - if (this.celledit) { - if (!ctrlKey && !e.altKey && (key > 46 && key < 112 || key > 123)) - this.startRename(null, true); - return; - } - else if (key == 65 && ctrlKey) { - this.selectAll(); - } - //@todo make this work with the sorted column - else if (this.caption || (this.bindingRules || {})["caption"]) { - if (!this.xmlRoot) return; - - //this should move to a onkeypress based function - if (!this.lookup || new Date().getTime() - - this.lookup.date.getTime() > 300) - this.lookup = { - str : "", - date : new Date() - }; - - this.lookup.str += String.fromCharCode(key); - - var nodes = this.getTraverseNodes(); //@todo start at current indicator - for (var v, i = 0; i < nodes.length; i++) { - v = this.applyRuleSetOnNode("caption", nodes[i]); - if (v && v.substr(0, this.lookup.str.length) - .toUpperCase() == this.lookup.str) { - - if (!this.isSelected(nodes[i])) { - if (this.mode == "check") - this.setIndicator(nodes[i]); - else - this.select(nodes[i]); - } - - if (selHtml) - this.oInt.scrollTop = selHtml.offsetTop - - (this.oInt.offsetHeight - - selHtml.offsetHeight) / 2; - return; - } - } - return; - } - break; - }; - - this.lookup = null; - return false; - } - - this.addEventListener("keydown", keyHandler, true); - - /**** Focus ****/ - // Too slow for IE - - this.$focus = function(){ - if (!this.oExt || (jpf.isIE && useiframe && this.cssfix)) //@todo fix this by fixing focussing for this component - return; - - this.$setStyleClass(this.oFocus || this.oExt, this.baseCSSname + "Focus"); - - if (this.oDoc) - this.$setStyleClass(this.oDoc.documentElement, this.baseCSSname + "Focus"); - }; - - this.$blur = function(){ - if (this.renaming) - this.stopRename(null, true); - - if (!this.oExt || (jpf.isIE && useiframe && this.cssfix)) //@todo fix this by fixing focussing for this component - return; - - this.$setStyleClass(this.oFocus || this.oExt, "", [this.baseCSSname + "Focus"]); - - if (this.oDoc) - this.$setStyleClass(this.oDoc.documentElement, "", [this.baseCSSname + "Focus"]); - }; - - /**** Private methods ****/ - - this.$calcSelectRange = function(xmlStartNode, xmlEndNode){ - var r = []; - var nodes = this.getTraverseNodes(); - for(var f=false,i=0;i<nodes.length;i++){ - if(nodes[i] == xmlStartNode) f = true; - if(f) r.push(nodes[i]); - if(nodes[i] == xmlEndNode) f = false; - } - - if (!r.length || f) { - r = []; - for (var f = false, i = nodes.length - 1; i >= 0; i--) { - if (nodes[i] == xmlStartNode) - f = true; - if (f) - r.push(nodes[i]); - if (nodes[i] == xmlEndNode) - f = false; - } - } - - return r; - }; - - /**** Sliding functions ****/ - - /** - * @private - */ - this.slideToggle = function(htmlNode, force){ - if (this.noCollapse) - return; - - //var id = htmlNode.getAttribute(jpf.xmldb.htmlIdTag); // unused? - var container = htmlNode.nextSibling; - - if (jpf.getStyle(container, "display") == "block") { - if (force == 1) return; - htmlNode.className = htmlNode.className.replace(/min/, "plus"); - this.slideClose(container, jpf.xmldb.getNode(htmlNode)); - } - else { - if (force == 2) return; - htmlNode.className = htmlNode.className.replace(/plus/, "min"); - this.slideOpen(container, jpf.xmldb.getNode(htmlNode)); - } - }; - - var lastOpened = {}; - /** - * @private - */ - this.slideOpen = function(container, xmlNode){ - var htmlNode = jpf.xmldb.findHTMLNode(xmlNode, this); - if (!container) - container = htmlNode.nextSibling; - - if (this.singleopen) { - var pNode = this.getTraverseParent(xmlNode) - var p = (pNode || this.xmlRoot).getAttribute(jpf.xmldb.xmlIdTag); - if (lastOpened[p] && lastOpened[p][1] != xmlNode - && this.getTraverseParent(lastOpened[p][1]) == pNode) - this.slideToggle(lastOpened[p][0], 2);//lastOpened[p][1]); - lastOpened[p] = [htmlNode, xmlNode]; - } - - container.style.display = "block"; - - jpf.tween.single(container, { - type : 'scrollheight', - from : 0, - to : container.scrollHeight, - anim : this.animType, - steps : this.animSteps, - interval: this.animSpeed, - onfinish: function(container){ - if (xmlNode && _self.hasLoadStatus(xmlNode, "potential")) { - setTimeout(function(){ - _self.$extend(xmlNode, container); - }); - container.style.height = "auto"; - } - else { - //container.style.overflow = "visible"; - container.style.height = "auto"; - } - } - }); - }; - - /** - * @private - */ - this.slideClose = function(container, xmlNode){ - if (this.noCollapse) return; - - if (this.singleopen) { - var p = (this.getTraverseParent(xmlNode) || this.xmlRoot) - .getAttribute(jpf.xmldb.xmlIdTag); - lastOpened[p] = null; - } - - container.style.height = container.offsetHeight; - container.style.overflow = "hidden"; - - jpf.tween.single(container, { - type : 'scrollheight', - from : container.scrollHeight, - to : 0, - anim : this.animType, - steps : this.animSteps, - interval: this.animSpeed, - onfinish: function(container, data){ - container.style.display = "none"; - } - }); - }; - - this.$findContainer = function(htmlNode) { - var node = htmlNode.nextSibling; - if (!node) return; - return node.nodeType == 1 ? node : node.nextSibling; - }; - - /**** Databinding ****/ - - var headings = [], cssRules = []; //@todo Needs to be reset - this.$loaddatabinding = function(){ - if (!this.bindingRules) - this.bindingRules = {}; - - //Set Up Headings - var heads = this.bindingRules.column; - - if (this.namevalue && !heads) { - this.bindingRules.column = heads = []; - - var cols = (this.columns || this.$jml.getAttribute("columns") - || "50%,50%").splitSafe(","); - - //@todo ask rik how this can be cached - //@todo get xmlUpdate to be called only once per document update for propedit - var xml = - jpf.getXml('<j:root xmlns:j="' + jpf.ns.jpf + '">\ - <j:column caption="Property" width="' + cols[0] + '" select="@caption" />\ - <j:column caption="Value" width="' + cols[1] + '" css="' + this.baseCSSname + '_{@type}{@multiple}"><![CDATA[[\ - var dg = jpf.lookup(' + this.uniqueId + ');\ - var select = $"@select";\ - var type = $"@type";\ - if (type == "set") {\ - var output = [], sep = $"@separator" || ", ";\ - var z = n;\ - if ($"@mask")\ - %$"@mask";\ - else {\ - n = dg.xmlData;\ - foreach(select) {\ - var v = n.nodeValue || $".";\ - n = z;\ - output.push(value(\'item[@value="\' + v + \'"]\'));\ - }\ - %output.join(sep);\ - }\ - }\ - else if (type == "dropdown") {\ - var v = jpf.getXmlValue(dg.xmlData, select);\ - %value("item[@value=\'" + v + "\']");\ - }\ - else if (type == "lookup" && $"@multiple" == "multiple"){\ - ]<div class="newitem"> </div>[\ - var vs = $"@descfield";\ - if (vs) {\ - n = dg.xmlData;\ - foreach(select) {]\ - <div class="item"><i onclick="jpf.lookup(' + this.uniqueId + ').$removePropItem(\'[%value(vs).replace(/\'/g, "\\\\\'").replace(/"/g, "&quot;");]\')">x</i>[%value(vs)]</div>\ - [}\ - }\ - else {\ - var total = dg.xmlData.selectNodes(select).length;\ - if (total){\ - %("[" + total + " " + $"@caption" + "]");\ - }\ - }]\ - [}\ - else if (type == "children") {\ - var vs = $"@descfield";\ - if (vs) {\ - local(dg.xmlData.selectSingleNode(select)){\ - foreach("node()"){]\ - <div class="item"><i onclick="jpf.lookup(' + this.uniqueId + ').$removePropItem(\'[%value(vs).replace(/\'/g, "\\\\\'").replace(/"/g, "&quot;");]\', \'node()\')">x</i>[%value(vs)]</div>\ - [}\ - }\ - }\ - else {\ - var total = dg.xmlData.selectNodes(select + "/node()").length;\ - if (total){\ - %("[" + total + " " + $"@caption" + "]");\ - }\ - }\ - }\ - else if (type == "lookup") {\ - var vs = $"@descfield";\ - if ($"@multiple" == "single")\ - vs = "node()/" + vs;\ - %jpf.getXmlValue(dg.xmlData, select + (vs ? "/" + vs : ""));\ - }\ - else if (type == "custom") {\ - var sep = $"@separator" || "";\ - var v, output = [];\ - foreach("field"){\ - v = jpf.getXmlValue(dg.xmlData, $"@select");\ - if (v) output.push(v);\ - }\ - if ($"@mask")\ - output.push($"@mask");\ - else if (!output.length && select)\ - output.push(jpf.getXmlValue(dg.xmlData, select));\ - %output.join(sep);\ - }\ - else {\ - %jpf.getXmlValue(dg.xmlData, select);\ - }\ - ]]]></j:column>\ - <j:traverse select="property|prop" />\ - <j:required select="self::node()/@required" />\ - <j:datatype select="@datatype" />\ - <j:pattern><![CDATA[[\ - var validate;\ - if ((validate = $"@decimals"))\ - %("/\\.\\d{" + validate + "}/");\ - else if ((validate = $"@validate") && validate.chartAt(0) == "/")\ - %("/" + validate.replace(/^\\/|\\/$/g, "") + "/");\ - ]]]></j:pattern>\ - <j:maxlength select="@maxlength" />\ - <j:invalidmsg><![CDATA[[\ - out = $"@invalidmsg" || "Invalid entry;Please correct your entry";\ - ]]]></j:invalidmsg>\ - </j:root>'); - <!-- mask --> - - //<j:select select="self::node()[not(@frozen)]" />\ - - if (!this.$removePropItem) { - this.$removePropItem = function(value, xpath){ - var xmlNode = this.xmlData.selectSingleNode( - this.selected.getAttribute("select") - + (xpath ? "/" + xpath : "") + "[" - + (value - ? this.selected.getAttribute("descfield") + "='" + value + "'" - : "string-length(" + this.selected.getAttribute("descfield") + ") = 0") - + "]"); - - this.getActionTracker().execute({ - action : "removeNode", - args : [xmlNode] - }); - } - } - - var nodes = xml.childNodes; - for (var i = 0; i < nodes.length; i++) { - var tagName = nodes[i][jpf.TAGNAME]; - (this.bindingRules[tagName] - || (this.bindingRules[tagName] = [])).push(nodes[i]); - } - } - - if (!heads) { - throw new Error(jpf.formatErrorString(0, this, - "Parsing bindings jml", - "No column definition found")); - } - - var found, options, xml, width, h, fixed = 0, oHead, hId, nodes = []; - for (var i = 0; i < heads.length; i++) { - xml = heads[i]; - width = xml.getAttribute("width") || defaultwidth; - options = xml.getAttribute("options") || this.options || - ("spreadsheet|propedit".indexOf(_self.tagName) > -1 - ? "size" - : "sort|size|move"); - - h = { - width : parseFloat(width), - isPercentage : width.indexOf("%") > -1, - xml : xml, //possibly optimize by recording select attribute only - select : xml.getAttribute("select"), - caption : xml.getAttribute("caption") || "", - icon : xml.getAttribute("icon"), - sortable : options.indexOf("sort") > -1, - resizable : options.indexOf("size") > -1, - movable : options.indexOf("move") > -1, - type : xml.getAttribute("type"), - colspan : xml.getAttribute("span") || 1, //currently not supported - align : xml.getAttribute("align") || "left", - className : "col" + this.uniqueId + i, - css : xml.getAttribute("css") - }; - - hId = headings.push(h) - 1; - - if (!h.width) - throw new Error("missing width"); //temporary check - - if (!h.isPercentage) - fixed += parseFloat(h.width) || 0; - else - found = true; - - //Set css - cssRules.push(["." + this.baseCSSname + " .headings ." + h.className, - "width:" + h.width + (h.isPercentage ? "%;" : "px;") - + "text-align:" + h.align]); - cssRules.push(["." + this.baseCSSname + " .records ." + h.className, - "width:" + h.width + (h.isPercentage ? "%;" : "px;") - + "text-align:" + h.align]); - - //Add to htmlRoot - this.$getNewContext("headitem"); - oHead = this.$getLayoutNode("headitem"); - oHead.setAttribute("class", h.className); - oHead.setAttribute("hid", hId); - - var hCaption = this.$getLayoutNode("headitem", "caption"); - if(h.icon){ - h.sortable = false; - oHead.setAttribute("style", "background-image:url(" - + jpf.getAbsolutePath(this.iconPath, h.icon) - +")"); - hCaption.nodeValue = " "; - } - else - hCaption.nodeValue = h.caption; - - //nodes.push(oHead); - h.htmlNode = jpf.xmldb.htmlImport(oHead, this.oHead); - } - - //jpf.xmldb.htmlImport(nodes, this.oHead); - - if (!found) { //@todo removal??? - this.$isFixedGrid = true; - this.$setStyleClass(this.oExt, "fixed"); - - if (useiframe) - this.$setStyleClass(this.oDoc.documentElement, "fixed"); - } - - if (fixed > 0 && !this.$isFixedGrid) { - var vLeft = fixed + 5; - - //first column has total -1 * fixed margin-left. - 5 - //cssRules[0][1] += ";margin-left:-" + vLeft + "px;"; - //cssRules[1][1] += ";margin-left:-" + vLeft + "px;"; - cssRules.push([".row" + this.uniqueId, "padding-right:" + vLeft - + "px;margin-right:-" + vLeft + "px"]); - - //headings and records have same padding-right - this.oInt.style.paddingRight = - this.oHead.style.paddingRight = vLeft + "px"; - } - - this.$fixed = fixed; - this.$first = 0; - - this.$withContainer = this.bindingRules && this.bindingRules.description; - - //Activate CSS Rules - importStylesheet(cssRules, window); - - if (useiframe) - importStylesheet(cssRules, this.oWin); - }; - - this.$unloaddatabinding = function(){ - //@todo - /*var headParent = this.$getLayoutNode("main", "head", this.oExt); - for(var i=0;i<headParent.childNodes.length;i++){ - headParent.childNodes[i].host = null; - headParent.childNodes[i].onmousedown = null; - headParent.childNodes[i].$isSizingColumn = null; - headParent.childNodes[i].$isSizeableColumn = null; - headParent.childNodes[i].onmousemove = null; - headParent.childNodes[i].onmouseup = null; - headParent.childNodes[i].ondragmove = null; - headParent.childNodes[i].ondragstart = null; - headParent.childNodes[i].onclick = null; - headParent.childNodes[i].ondblclick = null; - } - - this.oInt.onscroll = null; - - jpf.removeNode(this.oDragHeading); - this.oDragHeading = null; - jpf.removeNode(this.oSplitter); - this.oSplitter = null; - jpf.removeNode(this.oSplitterLeft); - this.oSplitterLeft = null; - - headParent.innerHTML = ""; - totalWidth = 0; - this.headings = [];*/ - }; - - this.nodes = []; - this.$add = function(xmlNode, sLid, xmlParentNode, htmlParentNode, beforeNode){ - //Build Row - this.$getNewContext("row"); - var oRow = this.$getLayoutNode("row"); - oRow.setAttribute("id", sLid); - oRow.setAttribute("class", "row" + this.uniqueId);//"width:" + (totalWidth+40) + "px"); - oRow.setAttribute("onmousedown", 'var o = jpf.lookup(' + this.uniqueId + ');\ - var wasSelected = o.$selected == this;\ - o.select(this, event.ctrlKey, event.shiftKey);' - + (this.cellselect || this.namevalue ? 'o.selectCell(event, this, wasSelected);' : ''));//, true;o.dragging=1; - oRow.setAttribute("ondblclick", 'var o = jpf.lookup(' + this.uniqueId + ');o.choose();' - + (this.$withContainer ? 'o.slideToggle(this);' : '') - + (this.celledit && !this.namevalue ? 'o.startRename();' : ''));//, true;o.dragging=1; - //oRow.setAttribute("onmouseup", 'var o = jpf.lookup(' + this.uniqueId + ');o.select(this, event.ctrlKey, event.shiftKey);o.dragging=false;'); - - //Build the Cells - for(var c, h, i = 0; i < headings.length; i++){ - h = headings[i]; - - this.$getNewContext("cell"); - - if (h.css) - jpf.setStyleClass(this.$getLayoutNode("cell"), jpf.JsltInstance.apply(h.css, xmlNode)); - - if (h.type == "icon"){ - var node = this.$getLayoutNode("cell", "caption", - oRow.appendChild(this.$setStyleClass(this.$getLayoutNode("cell"), - h.className))); - jpf.xmldb.setNodeValue(node, " "); - (node.nodeType == 1 && node || node.parentNode) - .setAttribute("style", "background-image:url(" - + jpf.getAbsolutePath(this.iconPath, - this.applyRuleSetOnNode([h.xml], xmlNode)) - + ")"); - } - else { - jpf.xmldb.setNodeValue(this.$getLayoutNode("cell", "caption", - oRow.appendChild(this.$setStyleClass(this.$getLayoutNode("cell"), h.className))), - (this.applyRuleSetOnNode([h.xml], xmlNode) || "").trim() || ""); //@todo for IE but seems not a good idea - } - } - - var cssClass = this.applyRuleSetOnNode("css", xmlNode); - if (cssClass) { - this.$setStyleClass(oRow, cssClass); - if (cssClass) - this.dynCssClasses.push(cssClass); - } - - //return jpf.xmldb.htmlImport(oRow, htmlParentNode || this.oInt, beforeNode); - if (htmlParentNode) - jpf.xmldb.htmlImport(oRow, htmlParentNode, beforeNode); - else - this.nodes.push(oRow); - - if (this.$withContainer) { - var desc = this.applyRuleSetOnNode("description", xmlNode); - this.$getNewContext("container"); - var oDesc = this.$getLayoutNode("container"); - jpf.xmldb.setNodeValue(this.$getLayoutNode("container", "container", - oDesc), desc); - oDesc.setAttribute("class", (oDesc.getAttribute("class") || "") - + " row" + this.uniqueId); - - if(htmlParentNode) - jpf.xmldb.htmlImport(oDesc, htmlParentNode, beforeNode); - else - this.nodes.push(oDesc); - } - }; - - var useTable = false; - this.$fill = function(nodes){ - if (useiframe) - this.pHtmlDoc = this.oDoc; - - if (useTable) { - jpf.xmldb.htmlImport(this.nodes, this.oInt, null, - "<table class='records' cellpadding='0' cellspacing='0'><tbody>", - "</tbody></table>"); - } - else { - jpf.xmldb.htmlImport(this.nodes, this.oInt); - } - - this.nodes.length = 0; - }; - - this.$deInitNode = function(xmlNode, htmlNode){ - if (this.$withContainer) - htmlNode.parentNode.removeChild(htmlNode.nextSibling); - - //Remove htmlNodes from tree - htmlNode.parentNode.removeChild(htmlNode); - }; - - this.$updateNode = function(xmlNode, htmlNode){ - if (!htmlNode) return; - - var nodes = this.oHead.childNodes, - htmlNodes = htmlNode.childNodes, - node; - - for (var i = this.namevalue ? 1 : 0, l = nodes.length; i < l; i++) { - h = headings[nodes[i].getAttribute("hid")]; - - //@todo fake optimization - node = this.$getLayoutNode("cell", "caption", htmlNodes[i]) || htmlNodes[i];//htmlNodes[i].firstChild || - - if (h.type == "icon") { - (node.nodeType == 1 && node || node.parentNode) - .style.backgroundImage = "url(" - + jpf.getAbsolutePath(this.iconPath, - this.applyRuleSetOnNode([h.xml], xmlNode)) - + ")"; - } - else { - node.innerHTML = (this.applyRuleSetOnNode([h.xml], xmlNode) - || "").trim() || ""; //@todo for IE but seems not a good idea - //jpf.xmldb.setNodeValue(node, - //this.applyRuleSetOnNode([h.xml], xmlNode)); - } - } - - //return; //@todo fake optimization - - var cssClass = this.applyRuleSetOnNode("css", xmlNode); - if (cssClass || this.dynCssClasses.length) { - this.$setStyleClass(htmlNode, cssClass, this.dynCssClasses); - if (cssClass && !this.dynCssClasses.contains(cssClass)) - this.dynCssClasses.push(cssClass); - } - - if (this.$withContainer) { - htmlNode.nextSibling.innerHTML - = this.applyRuleSetOnNode("description", xmlNode) || ""; - } - }; - - this.$moveNode = function(xmlNode, htmlNode){ - if (!htmlNode) return; - var oPHtmlNode = htmlNode.parentNode; - var beforeNode = xmlNode.nextSibling - ? jpf.xmldb.findHTMLNode(this.getNextTraverse(xmlNode), this) - : null; - - oPHtmlNode.insertBefore(htmlNode, beforeNode); - - //if(this.emptyMessage && !oPHtmlNode.childNodes.length) this.setEmpty(oPHtmlNode); - }; - - this.$selectDefault = function(XMLRoot){ - this.select(XMLRoot.selectSingleNode(this.traverse)); - }; - - var lastcell, lastcol = 0, lastrow; - this.getColumn = function(nr){ - return headings[nr || lastcol || 0]; - } - - this.selectCell = function(e, rowHtml, wasSelected) { - var htmlNode = e.srcElement || e.target; - if (htmlNode == rowHtml || !jpf.xmldb.isChildOf(rowHtml, htmlNode)) - return; //this is probably not good - - while (htmlNode.parentNode != rowHtml) - htmlNode = htmlNode.parentNode; - - var type = this.selected.getAttribute("type"); - - if (this.namevalue && wasSelected && lastcell - && lastcell.parentNode == htmlNode.parentNode - && htmlNode == htmlNode.parentNode.lastChild) { - lastcell = htmlNode; - lastcol = 1; - - if (this.namevalue - && type == "lookup" - && this.selected.getAttribute("multiple") == "multiple") { - if ((e.srcElement || e.target).className.indexOf("newitem") == -1) - return; - } - - this.startDelayedRename(e, 1); - - return; - } - - if (lastcell == htmlNode) - return; - - if (lastcell && lastcell.parentNode && lastcell.parentNode.nodeType == 1) { - if (this.namevalue) { - jpf.setStyleClass(lastcell.parentNode.childNodes[0], "", ["celllabel"]); - jpf.setStyleClass(lastcell.parentNode.childNodes[1], "", ["cellselected"]); - } - else { - jpf.setStyleClass(lastcell, "", ["cellselected"]); - } - } - - var col = jpf.xmldb.getChildNumber(htmlNode); - var h = headings[this.oHead.childNodes[col].getAttribute("hid")]; - - if (this.namevalue) { - jpf.setStyleClass(htmlNode.parentNode.childNodes[0], "celllabel"); - jpf.setStyleClass(htmlNode.parentNode.childNodes[1], "cellselected"); - - if (jpf.popup.isShowing(this.uniqueId)) - jpf.popup.forceHide(); - - if (curBtn && curBtn.parentNode) - curBtn.parentNode.removeChild(curBtn); - - var type = this.selected.getAttribute("type"); - var multiple = this.selected.getAttribute("multiple") == "multiple"; - if (type && type != "text" && (type != "lookup" || !multiple)) { - if (type == "set") - type = "dropdown"; - if (type != "lookup") { - curBtn = editors[type] || editors["custom"]; - if (curBtn) { - htmlNode.parentNode.appendChild(curBtn); - curBtn.style.display = "block"; //@todo see why only showing this onfocus doesnt work in IE - } - } - } - } - else { - jpf.setStyleClass(htmlNode, "cellselected"); - } - - lastcell = htmlNode; - lastcol = col; - lastrow = rowHtml; - - /*if (this.namevalue && this.hasFocus() - && (!type || type == "text" || type == "lookup") - && htmlNode == htmlNode.parentNode.childNodes[1]) - this.startDelayedRename(e, 1);*/ - }; - - /**** Drag & Drop ****/ - - this.$showDragIndicator = function(sel, e){ - var x = e.offsetX; - var y = e.offsetY; - - this.oDrag.startX = x; - this.oDrag.startY = y; - - document.body.appendChild(this.oDrag); - //this.$updateNode(this.selected, this.oDrag); // Solution should be found to have this on conditionally - - return this.oDrag; - }; - - this.$hideDragIndicator = function(){ - this.oDrag.style.display = "none"; - }; - - this.$moveDragIndicator = function(e){ - this.oDrag.style.left = (e.clientX) + "px";// - this.oDrag.startX - this.oDrag.style.top = (e.clientY + 15) + "px";// - this.oDrag.startY - }; - - this.$initDragDrop = function(){ - if (!this.$hasLayoutNode("dragindicator")) return; - - this.oDrag = jpf.xmldb.htmlImport(this.$getLayoutNode("dragindicator"), - document.body); - - this.oDrag.style.zIndex = 1000000; - this.oDrag.style.position = "absolute"; - this.oDrag.style.cursor = "default"; - this.oDrag.style.display = "none"; - }; - - this.findValueNode = function(el){ - if (!el) return null; - - while(el && el.nodeType == 1 - && !el.getAttribute(jpf.xmldb.htmlIdTag)) { - el = el.parentNode; - } - - return (el && el.nodeType == 1 && el.getAttribute(jpf.xmldb.htmlIdTag)) - ? el - : null; - }; - - this.$dragout = function(dragdata){ - if (this.lastel) - this.$setStyleClass(this.lastel, "", ["dragDenied", "dragInsert", - "dragAppend", "selected", "indicate"]); - this.$setStyleClass(this.$selected, "selected", ["dragDenied", - "dragInsert", "dragAppend", "indicate"]); - - this.lastel = null; - }; - - this.$dragover = function(el, dragdata, extra){ - if(el == this.oExt) return; - - this.$setStyleClass(this.lastel || this.$selected, "", ["dragDenied", - "dragInsert", "dragAppend", "selected", "indicate"]); - - this.$setStyleClass(this.lastel = this.findValueNode(el), extra - ? (extra[1] && extra[1].getAttribute("operation") == "insert-before" - ? "dragInsert" - : "dragAppend") - : "dragDenied"); - }; - - this.$dragdrop = function(el, dragdata, extra){ - this.$setStyleClass(this.lastel || this.$selected, - !this.lastel && (this.$selected || this.lastel == this.$selected) - ? "selected" - : "", - ["dragDenied", "dragInsert", "dragAppend", "selected", "indicate"]); - - this.lastel = null; - }; - - /**** Lookup ****/ - - /* - <prop select="author" descfield="name" datatype="lookupkey" - caption="Author" description="Author id" overview="overview" - maxlength="10" type="lookup" foreign_table="author" /> - */ - this.stopLookup = function(propNode, dataNode){ - if (!dataNode) - return; - - this.stopRename(); - - var multiple = propNode.getAttribute("multiple"), - select = propNode.getAttribute("select"); - - var oldNode = this.xmlData.selectSingleNode(select - + (multiple == "single" ? "/node()" : "")); - var newNode = jpf.xmldb.copyNode(dataNode); - - if (multiple != "multiple") { - var tagName; - - var s = select.split("/"); - if ((tagName = s.pop()).match(/^@|^text\(\)/)) - tagName = s.pop(); - select = s.join("/") || null; - - if (tagName && tagName != newNode.tagName) { - newNode = jpf.xmldb.integrate(newNode, - newNode.ownerDocument.createElement(tagName)); - } - - //@todo this should become the change action - var changes = []; - if (oldNode) { - changes.push({ - func : "removeNode", - args : [oldNode] - }); - } - - changes.push({ - func : "appendChild", - args : [this.xmlData, newNode, null, null, select] - }); - - this.getActionTracker().execute({ - action : "multicall", - args : changes - }); - } - else { - if (multiple) { - if (multiple != "single") { - var s = select.split("/"); - if (s.pop().match(/^@|^text\(\)/)) s.pop(); - select = s.join("/"); - } - } - else - select = null; - - if (!this.xmlData.selectSingleNode(select + "/" - + newNode.tagName + "[@id='" + newNode.getAttribute("id") + "']")) { - //@todo this should become the change action - this.getActionTracker().execute({ - action : "appendChild", - args : [this.xmlData, newNode, null, null, select] - }); - } - } - - if (jpf.popup.isShowing(this.uniqueId)) - jpf.popup.hide(); - }; - - this.$lookup = function(value, isMultiple){ - var oHtml = this.$selected.childNodes[this.namevalue ? 1 : lastcol]; - - if (this.dispatchEvent("beforelookup", { - value : value, - xmlNode : this.selected, - htmlNode : oHtml - }) === false) - return; - - var oContainer = editors["dropdown_container"]; - if (self[this.lookupjml].childNodes.length - && self[this.lookupjml].childNodes[0].parentNode != oContainer) { - self[this.lookupjml].detach(); - oContainer.innerHTML = ""; - } - - var lookupJml = self[this.lookupjml].render(oContainer); - - if (!jpf.popup.isShowing(this.uniqueId)) { - var mirrorNode = oHtml; - //this.$setStyleClass(oContainer, mirrorNode.className); - //oContainer.style.height = "auto"; - oContainer.className = "ddjmlcontainer"; - oContainer.style.display = "block"; - var height = oContainer.scrollHeight; - oContainer.style.display = "none"; - /*oContainer.style[jpf.supportOverflowComponent - ? "overflowY" - : "overflow"] = "hidden";*/ - - var widthdiff = jpf.getWidthDiff(oContainer); - jpf.popup.show(this.uniqueId, { - x : -1, - y : (isMultiple ? mirrorNode.firstChild.firstChild.offsetHeight : mirrorNode.offsetHeight) - 1, - animate : true, - ref : mirrorNode, - width : mirrorNode.offsetWidth - widthdiff + 5, //Math.max(self[this.lookupjml].minwidth, - height : height, - callback: function(){ - oContainer.style.height = "auto"; - /*oContainer.style[jpf.supportOverflowComponent - ? "overflowY" - : "overflow"] = "auto";*/ - } - }); - } - - this.selected.setAttribute("j_lastsearch", value); - - this.dispatchEvent("afterlookup", { - value : value, - xmlNode : this.selected, - htmlNode : oHtml, - nodes : lookupJml - }); - }; - - /**** Rename ****/ - - this.$getCaptionElement = function(){ - if (this.namevalue) { - var type = this.selected.getAttribute("type"); - if (type && type != "text") { - if (type == "lookup") { - this.$autocomplete = true; - var isMultiple = this.selected.getAttribute("multiple") == "multiple"; - this.$lookup(this.selected.getAttribute("j_lastsearch") || "", isMultiple); - } - else - return; - } - else { - this.$autocomplete = false; - } - } - - var node = this.$getLayoutNode("cell", "caption", this.namevalue - ? lastcell.parentNode.childNodes[1] - : lastcell); - - if (this.namevalue && type == "lookup" && isMultiple) - node = node.firstChild; - - return node.nodeType == 1 && node || node.parentNode; - }; - - var lastCaptionCol = null; - this.$getCaptionXml = function(xmlNode){ - if (this.namevalue) { - /* - this.createModel - ? jpf.xmldb.createNodeFromXpath(this.xmlData, this.selected.getAttribute("select")) - : - */ - return this.xmlData.selectSingleNode(this.selected.getAttribute("select")) || - this.selected.getAttribute("lookup") && jpf.getXml("<stub />"); - } - - var h = headings[this.oHead.childNodes[lastcol || 0].getAttribute("hid")]; - lastCaptionCol = lastcol || 0; - return xmlNode.selectSingleNode(h.select || "."); - }; - - var $getSelectFromRule = this.getSelectFromRule; - this.getSelectFromRule = function(setname, cnode){ - if (setname == "caption") { - if (this.namevalue) { - var sel = cnode.getAttribute("select"); - return [sel, this.createModel - ? jpf.xmldb.createNodeFromXpath(this.xmlData, sel) - : this.xmlData.selectSingleNode(sel)]; - } - - var h = headings[this.oHead.childNodes[lastCaptionCol !== null - ? lastCaptionCol - : (lastcol || 0)].getAttribute("hid")]; - lastCaptionCol = null; - return [h.select]; - } - - return $getSelectFromRule.apply(this, arguments); - }; - - - /**** Column management ****/ - - var lastSorted; - this.sortColumn = function(hid){ - var h; - - if (hid == lastSorted) { - jpf.setStyleClass(headings[hid].htmlNode, - this.toggleSortOrder() - ? "ascending" - : "descending", ["descending", "ascending"]); - return; - } - - if (typeof lastSorted != "undefined") { - h = headings[lastSorted]; - jpf.setStyleRule("." + this.baseCSSname + " .records ." + h.className, "background", ""); - jpf.setStyleClass(h.htmlNode, "", ["descending", "ascending"]); - } - - h = headings[hid]; - jpf.setStyleRule("." + this.baseCSSname + " .records ." + h.className, "background", "#f3f3f3"); - jpf.setStyleClass(h.htmlNode, "ascending", ["descending", "ascending"]); - - this.resort({ - order : "ascending", - xpath : h.select - //type : - }); - - lastSorted = hid; - }; - - //@todo optimize but bringing down the string concats - this.resizeColumn = function(nr, newsize){ - var hN, h = headings[nr]; - - if (h.isPercentage) { - var ratio = newsize / (h.htmlNode.offsetWidth - (widthdiff - 3)); //div 0 ?? - var next = []; - var total = 0; - var node = h.htmlNode.nextSibling; - - while(node && node.getAttribute("hid")) { - hN = headings[node.getAttribute("hid")]; - if (hN.isPercentage) { - next.push(hN); - total += hN.width; - } - node = node.nextSibling; - } - - var newPerc = ratio * h.width; - var diffPerc = newPerc - h.width; - var diffRatio = (total - diffPerc) / total; - if (diffRatio < 0.01) { - if (newsize < 20) return; - return this.resizeColumn(nr, newsize - 10); - } - - for (var n, i = 0; i < next.length; i++) { - n = next[i]; - n.width *= diffRatio; - jpf.setStyleRule("." + this.baseCSSname + " .headings ." - + n.className, "width", n.width + "%"); //Set - jpf.setStyleRule("." + this.baseCSSname + " .records ." - + n.className, "width", n.width + "%", null, this.oWin); //Set - } - - h.width = newPerc; - jpf.setStyleRule("." + this.baseCSSname + " .headings ." - + h.className, "width", h.width + "%"); //Set - jpf.setStyleRule("." + this.baseCSSname + " .records ." - + h.className, "width", h.width + "%", null, this.oWin); //Set - } - else { - var diff = newsize - h.width; - h.width = newsize; - if (jpf.isIE && this.oIframe) - h.htmlNode.style.width = newsize + "px"; - else - jpf.setStyleRule("." + this.baseCSSname + " .headings ." - + h.className, "width", newsize + "px"); //Set - jpf.setStyleRule("." + this.baseCSSname + " .records ." - + h.className, "width", newsize + "px", null, this.oWin); //Set - - var hFirst = headings[this.$first]; - this.$fixed += diff; - var vLeft = (this.$fixed + 5) + "px"; - - if (!this.$isFixedGrid) { - //jpf.setStyleRule("." + this.baseCSSname + " .headings ." + hFirst.className, "marginLeft", "-" + vLeft); //Set - //jpf.setStyleRule("." + this.baseCSSname + " .records ." + hFirst.className, "marginLeft", "-" + vLeft); //Set - jpf.setStyleRule(".row" + this.uniqueId, "paddingRight", vLeft, null, this.oWin); //Set - jpf.setStyleRule(".row" + this.uniqueId, "marginRight", "-" + vLeft, null, this.oWin); //Set - - //headings and records have same padding-right - this.oInt.style.paddingRight = - this.oHead.style.paddingRight = vLeft; - } - } - }; - - this.hideColumn = function(nr){ - var h = headings[nr]; - jpf.setStyleRule("." + this.baseCSSname + " .records ." + h.className, - "visibility", "hidden", null, this.oWin); - - //Change percentages here - }; - - this.showColumn = function(nr){ - var h = headings[nr]; - jpf.setStyleRule("." + this.baseCSSname + " .records ." + h.className, - "visibility", "visible", null, this.oWin); - - //Change percentages here - }; - - this.moveColumn = function(from, to){ - if (to && from == to) - return; - - var hFrom = headings[from]; - var hTo = headings[to]; - - var childNrFrom = jpf.xmldb.getChildNumber(hFrom.htmlNode); - var childNrTo = hTo && jpf.xmldb.getChildNumber(hTo.htmlNode); - this.oHead.insertBefore(hFrom.htmlNode, hTo && hTo.htmlNode || null); - - var node, nodes = this.oInt.childNodes; - for (var i = 0; i < nodes.length; i++) { - if (this.$withContainer && ((i+1) % 2) == 0) - continue; - - node = nodes[i]; - node.insertBefore(node.childNodes[childNrFrom], - typeof childNrTo != "undefined" && node.childNodes[childNrTo] || null); - } - - /*if (this.$first == from || this.$first == to) { - var hReset = this.$first == from ? hFrom : hTo; - - jpf.setStyleRule("." + this.baseCSSname + " .headings ." - + hReset.className, "marginLeft", "-5px"); //Reset - jpf.setStyleRule("." + this.baseCSSname + " .records ." - + hReset.className, "marginLeft", "-5px"); //Reset - - this.$first = this.oHead.firstChild.getAttribute("hid"); - var h = headings[this.$first]; - var vLeft = "-" + (this.$fixed + 5) + "px"; - - jpf.setStyleRule("." + this.baseCSSname + " .headings ." - + h.className, "marginLeft", vLeft); //Set - jpf.setStyleRule("." + this.baseCSSname + " .records ." - + h.className, "marginLeft", vLeft); //Set - }*/ - } - - /**** Buttons ****/ - - this.$btndown = function(oHtml, e){ - this.$setStyleClass(oHtml, "down"); - - var type = this.selected.getAttribute("type");//oHtml.getAttribute("type"); - if (type == "dropdown" || type == "set") { - if (jpf.popup.isShowing(this.uniqueId)){ - jpf.popup.forceHide(); - } - else { - var oContainer = editors["dropdown_container"]; - - if (self[this.lookupjml]) - self[this.lookupjml].detach(); - - var mirrorNode = oHtml.parentNode.childNodes[1]; - //this.$setStyleClass(oContainer, mirrorNode.className); - oContainer.className = "propeditcontainer" + type; - oContainer.style[jpf.supportOverflowComponent - ? "overflowY" - : "overflow"] = "hidden"; - - str = []; - var s = this.selected.selectNodes("item"); - if (type == "dropdown") { - for (var i = 0, l = s.length; i < l; i++) { - str.push("<div tag='", s[i].getAttribute("value"), "'>", - s[i].firstChild.nodeValue, "</div>"); - } - } - else { - var select = this.selected.getAttribute("select"); - var values = [], n = this.xmlData.selectNodes(select); - for (var i = 0; i < n.length; i++) { - values.push(n[i].nodeValue || jpf.getXmlValue(n[i], ".")); - } - - for (var v, c, i = 0, l = s.length; i < l; i++) { - c = values.contains(s[i].getAttribute("value")) - ? "checked" : ""; - str.push("<div class='", c, "' tag='", - s[i].getAttribute("value"), "'><span> </span>", - s[i].firstChild.nodeValue, "</div>"); - } - } - - oContainer.innerHTML = "<blockquote style='margin:0'>" - + str.join("") + "</blockquote>"; - - oContainer.firstChild.onmouseover = function(e){ - if (!e) e = event; - var target = e.srcElement || e.target; - - if (target == this) - return; - - while (target.parentNode != this) - target = target.parentNode; - - jpf.setStyleClass(target, "hover"); - }; - - oContainer.firstChild.onmouseout = function(e){ - if (!e) e = event; - var target = e.srcElement || e.target; - - if (target == this) - return; - - while (target.parentNode != this) - target = target.parentNode; - - jpf.setStyleClass(target, "", ["hover"]); - }; - - oContainer.firstChild.onmousedown = function(e){ - if (!e) e = event; - var target = e.srcElement || e.target; - - if (target == this) - return; - - while (target.parentNode != this) - target = target.parentNode; - - if (type == "set") { - if (target.className.indexOf("checked") > -1) - jpf.setStyleClass(target, "", ["checked"]); - else - jpf.setStyleClass(target, "checked"); - } - else { - _self.rename(_self.selected, target.getAttribute("tag")); - jpf.popup.forceHide(); - } - }; - - var sel = this.selected; - jpf.popup.show(this.uniqueId, { - x : -1, - y : mirrorNode.offsetHeight - 1, - animate : true, - ref : mirrorNode, - width : mirrorNode.offsetWidth - this.widthdiff + 3, - height : s.length * this.itemHeight, - onclose : function(e){ - if (type == "set") { - var changes = [], checked = [], nodes = e.htmlNode.firstChild.childNodes; - for (var v, i = 0; i < nodes.length; i++) { - if (nodes[i].className.indexOf("checked") > -1) { - checked.push(v = nodes[i].getAttribute("tag")); - - if (!values.contains(v)) { - changes.push({ - func : "setValueByXpath", - args : [_self.xmlData, v, select, true] - }); - } - } - } - for (i = 0; i < values.length; i++) { - if (!checked.contains(values[i])) { - changes.push({ - func : "removeNode", - args : [n[i].nodeType != 1 - ? n[i].parentNode || n[i].ownerElement || n[i].selectSingleNode("..") - : n[i]] - }); - } - } - - if (changes.length) { - //@todo this should become the change action - //setTimeout(function(){ - _self.$lastUpdated = sel; - _self.getActionTracker().execute({ - action : "multicall", - args : changes - }); - //}); - } - } - } - }); - } - } - }; - - this.$btnup = function(oHtml, force){ - if (!this.selected) - return; - - //var type = oHtml.getAttribute("type"); - var type = this.selected.getAttribute("type");//oHtml.getAttribute("type"); - if (!force && type == "custom" && oHtml.className.indexOf("down") > -1) { - if (this.selected.getAttribute("form")) { - var form = self[this.selected.getAttribute("form")]; - - if (!form) { - throw new Error(jpf.formatErrorString(0, _self, - "Showing form connected to property", - "Could not find form by name '" + this.selected.getAttribute("form") - + "'", this.selected)); - } - - form.show(); - form.bringToFront(); - } - else if (this.selected.getAttribute("exec")) { - try { - var selected = _self.xmlData; - eval(this.selected.getAttribute("exec")); - } - catch(e){ - throw new Error(jpf.formatErrorString(0, _self, - "Executing the code inside the exec property", - "Could not find exec by name '" + this.selected.getAttribute("exec") - + "'\nError: " + e.message, this.selected)); - } - } - } - else if (!force && type == "children") { - var select = this.selected.getAttribute("select"); - var xmlNode = jpf.xmldb.createNodeFromXpath(this.xmlData, select);//newNodes - - this.dispatchEvent("multiedit", { - xmlNode : this.selected, - dataNode : xmlNode - }); - } - - if (force || "dropdown|set".indexOf(oHtml.getAttribute("type")) == -1 - || !jpf.popup.isShowing(this.uniqueId)) - this.$setStyleClass(oHtml, "", ["down"]); - }; - - this.$btnout = function(oHtml, force){ - if (force || "dropdown|set".indexOf(oHtml.getAttribute("type")) == -1 - || !jpf.popup.isShowing(this.uniqueId)) - this.$setStyleClass(oHtml, "", ["down"]); - }; - - this.addEventListener("popuphide", function(){ - if (curBtn) - this.$btnup(curBtn, true); - if (this.rename) - this.stopRename(); - }); - - /**** Init ****/ - - var widthdiff, defaultwidth, useiframe; - this.$draw = function(){ - //Build Main Skin - this.oExt = this.$getExternal(); - this.oInt = this.$getLayoutNode("main", "body", this.oExt); - this.oHead = this.$getLayoutNode("main", "head", this.oExt); - this.oPointer = this.$getLayoutNode("main", "pointer", this.oExt); - - if (this.oHead.firstChild) - this.oHead.removeChild(this.oHead.firstChild); - if (this.oInt.firstChild) - this.oInt.removeChild(this.oInt.firstChild); - - widthdiff = this.$getOption("main", "widthdiff") || 0; - defaultwidth = this.$getOption("main", "defaultwidth") || "100"; - useiframe = jpf.isIE && (jpf.isTrue(this.$getOption("main", "iframe")) || this.iframe); - - jpf.JmlParser.parseChildren(this.$jml, null, this); - - //Initialize Iframe - if (useiframe && !this.oIframe) { - //this.oInt.style.overflow = "hidden"; - //var sInt = this.oInt.outerHTML - var sClass = this.oInt.className; - //this.oInt.parentNode.removeChild(this.oInt); - this.oIframe = this.oInt.appendChild(document.createElement(jpf.isIE - ? "<iframe frameborder='0'></iframe>" - : "iframe")); - this.oIframe.frameBorder = 0; - this.oWin = this.oIframe.contentWindow; - this.oDoc = this.oWin.document; - this.oDoc.write('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\ - <html xmlns="http://www.w3.org/1999/xhtml">\ - <head><script>\ - jpf = {\ - lookup : function(uid){\ - return window.parent.jpf.lookup(uid);\ - },\ - Init : {add:function(){},run:function(){}}\ - };</script>\ - </head>\ - <body></body>\ - </html>'); - //Import CSS - //this.oDoc.body.innerHTML = sInt; - this.oInt = this.oDoc.body;//.firstChild; - this.oInt.className = sClass;//this.oIframe.parentNode.className; - this.oDoc.documentElement.className = this.oExt.className; - //this.oDoc.body.className = this.oExt.className; - - jpf.skins.loadCssInWindow(this.skinName, this.oWin, this.mediaPath, this.iconPath); - - if (jpf.isIE) //@todo this can be removed when focussing is fixed for this component - this.$setStyleClass(this.oDoc.documentElement, this.baseCSSname + "Focus"); - - jpf.convertIframe(this.oIframe, true); - - this.oDoc.body.insertAdjacentHTML("beforeend", this.oTxt.outerHTML); - - var t = this.oTxt; t.refCount--; - this.oTxt = this.oDoc.body.lastChild; - this.oTxt.parentNode.removeChild(this.oTxt); - this.oTxt.select = t.select; - - this.oTxt.ondblclick = - this.oTxt.onselectstart = - this.oTxt.onmouseover = - this.oTxt.onmouseout = - this.oTxt.oncontextmenu = - this.oTxt.onmousedown = function(e){ - (e || (_self.oWin || window).event).cancelBubble = true; - }; - - this.oTxt.onfocus = t.onfocus; - this.oTxt.onblur = t.onblur; - this.oTxt.onkeyup = t.onkeyup; - this.oTxt.refCount = 1; - - if (jpf.getStyle(this.oDoc.documentElement, jpf.isIE - ? "overflowY" : "overflow-y") == "auto") { - //@todo ie only - this.oIframe.onresize = function(){ - _self.oHead.style.marginRight = - _self.oDoc.documentElement.scrollHeight > _self.oDoc.documentElement.offsetHeight - ? "16px" : "0"; - } - - this.addEventListener("afterload", this.oIframe.onresize); - this.addEventListener("xmlupdate", this.oIframe.onresize); - } - - this.oDoc.documentElement.onmousedown = function(e){ - if (!e) e = _self.oWin.event; - if ((e.srcElement || e.target).tagName == "HTML") - jpf.popup.forceHide(); - } - - this.oDoc.documentElement.onscroll = - function(){ - if (_self.$isFixedGrid) - _self.oHead.scrollLeft = _self.oDoc.documentElement.scrollLeft; - }; - } - else { - if (jpf.getStyle(this.oInt, jpf.isIE - ? "overflowY" : "overflow-y") == "auto") { - this.$resize = function(){ - _self.oHead.style.marginRight = - _self.oInt.scrollHeight > _self.oInt.offsetHeight - ? "16px" : "0"; - } - - jpf.layout.setRules(this.oExt, this.uniqueId + "_datagrid", - "jpf.all[" + this.uniqueId + "].$resize()"); - jpf.layout.activateRules(this.oExt); - - this.addEventListener("afterload", this.$resize); - this.addEventListener("xmlupdate", this.$resize); - } - - this.oInt.onmousedown = function(e){ - if (!e) e = event; - if ((e.srcElement || e.target) == this) - jpf.popup.forceHide(); - } - - this.oInt.onscroll = - function(){ - if (_self.$isFixedGrid) - _self.oHead.scrollLeft = _self.oInt.scrollLeft; - }; - } - - this.oTxt.onkeydown = function(e){ - if ("datagrid|spreadsheet|propedit".indexOf(_self.tagName) == -1) - return; - - if (!e) e = (_self.oWin || window).event; - if (_self.celledit && !_self.namevalue && e.keyCode == 9) { - _self.stopRename(null, true); - keyHandler.call(_self, {keyCode:39, force:true}); - e.cancelBubble = true; - e.returnValue = true; - return false; - } - } - - var dragging = false; - - this.oHead.onmouseover = function(e){ - if (!e) e = event; - var target = e.srcElement || e.target; - - if (target == this) return; - - while (target.parentNode != this) - target = target.parentNode; - - jpf.setStyleClass(target, "hover", ["down"]); - }; - - this.oHead.onmouseup = function(e){ - if (!e) e = event; - var target = e.srcElement || e.target; - - if (target == this || !jpf.xmldb.isChildOf(dragging, target, true)) - return; - - while (target.parentNode != this) - target = target.parentNode; - - jpf.setStyleClass(target, "hover", ["down"]); - - if (headings[target.getAttribute("hid")].sortable) - _self.sortColumn(parseInt(target.getAttribute("hid"))); - }; - - this.oHead.onmousedown = function(e){ - if (!e) e = event; - var target = e.srcElement || e.target; - - if (target == this) return; - - while (target.parentNode != this) - target = target.parentNode; - - dragging = target; - - //Resizing - var pos = jpf.getAbsolutePosition(target), - sLeft = _self.oHead.scrollLeft; - var d = e.clientX - pos[0] + sLeft; - if (d < 4 || target.offsetWidth - d - 8 < 3) { - var t = d < 4 && target.previousSibling || target; - - if (headings[t.getAttribute("hid")].resizable) { - pos = jpf.getAbsolutePosition(t); - jpf.setStyleClass(_self.oPointer, "size_pointer", ["move_pointer"]); - _self.oPointer.style.display = "block"; - _self.oPointer.style.left = (t.offsetLeft - sLeft - 1) + "px"; - _self.oPointer.style.width = (t.offsetWidth - widthdiff + 1) + "px"; - - jpf.plane.show(_self.oPointer, null, true); - - dragging = true; - document.onmouseup = function(){ - if (!e) e = event; - - document.onmouseup = - document.onmousemove = null; - - _self.resizeColumn(t.getAttribute("hid"), - _self.oPointer.offsetWidth); - - dragging = false; - _self.oPointer.style.display = "none"; - - jpf.plane.hide(); - - }; - - document.onmousemove = function(e){ - if (!e) e = event; - - _self.oPointer.style.width = Math.max(10, - Math.min(_self.oInt.offsetWidth - _self.oPointer.offsetLeft - 20, - e.clientX - pos[0] - 1 + sLeft)) + "px"; - }; - - return; - } - } - - jpf.setStyleClass(target, "down", ["hover"]); - - //Moving - if (!headings[target.getAttribute("hid")].movable) { - document.onmouseup = function(e){ - document.onmouseup = null; - dragging = false; - }; - - return; - } - - jpf.setStyleClass(_self.oPointer, "move_pointer", ["size_pointer"]); - - var x = e.clientX - target.offsetLeft, sX = e.clientX, - y = e.clientY - target.offsetTop, sY = e.clientY, - copy; - - document.onmouseup = function(e){ - if (!e) e = event; - - document.onmouseup = - document.onmousemove = null; - - dragging = false; - _self.oPointer.style.display = "none"; - - if (!copy) - return; - - copy.style.top = "-100px"; - - var el = document.elementFromPoint(e.clientX, e.clientY); - if (el.parentNode == copy.parentNode) { - var pos = jpf.getAbsolutePosition(el); - var beforeNode = (e.clientX - pos[0] > el.offsetWidth / 2 - ? el.nextSibling - : el); - - _self.moveColumn(target.getAttribute("hid"), - beforeNode ? beforeNode.getAttribute("hid") : null); - } - - jpf.removeNode(copy); - }; - - document.onmousemove = function(e){ - if (!e) e = event; - - if (!copy) { - if (Math.abs(e.clientX - sX) < 3 && Math.abs(e.clientY - sY) < 3) - return; - - copy = target.cloneNode(true); - copy.style.position = "absolute"; - var diff = jpf.getWidthDiff(target); - copy.style.width = (target.offsetWidth - diff - - widthdiff + 2) + "px"; - copy.style.left = target.offsetLeft; - copy.style.top = target.offsetTop; - copy.style.margin = 0; - copy.removeAttribute("hid") - - jpf.setStyleClass(copy, "drag", ["ascending", "descending"]); - target.parentNode.appendChild(copy); - } - - copy.style.top = "-100px"; - _self.oPointer.style.display = "none"; - - var el = document.elementFromPoint(e.clientX, e.clientY); - if (el.parentNode == copy.parentNode) { - var pos = jpf.getAbsolutePosition(el); - _self.oPointer.style.left = (el.offsetLeft - + ((e.clientX - pos[0] > el.offsetWidth / 2) - ? el.offsetWidth - 8 - : 0)) + "px"; - _self.oPointer.style.display = "block"; - } - - copy.style.left = (e.clientX - x) + 'px'; - copy.style.top = (e.clientY - y) + 'px'; - }; - }; - - this.oHead.onmouseout = function(e){ - if (!e) e = event; - var target = e.srcElement || e.target; - - if (target == this) return; - - while (target.parentNode != this) - target = target.parentNode; - - jpf.setStyleClass(target, "", ["hover", "down"]); - }; - - this.oHead.onmousemove = function(e){ - if (dragging) - return; - - if (!e) - e = event; - var target = e.srcElement || e.target; - - if (target == this) return; - - while (target.parentNode != this) - target = target.parentNode; - - var pos = jpf.getAbsolutePosition(target), - sLeft = _self.oHead.scrollLeft; - var d = e.clientX - pos[0] + sLeft; - - if (d < 4 || target.offsetWidth - d - widthdiff < 3) { - var t = d < 4 ? target.previousSibling : target; - this.style.cursor = t && headings[t.getAttribute("hid")].resizable - ? "w-resize" - : "default"; - } - else { - this.style.cursor = "default"; - } - }; - }; - - var editors = {}; - this.$loadJml = function(x){ - if (x.getAttribute("message")) - this.clearMessage = x.getAttribute("message"); - - //@todo add options attribute - - if (this.tagName == "spreadsheet" || this.tagName == "propedit") { - this.celledit = true; - this.cellselect = true; - - if (this.tagName == "propedit") - this.namevalue = true; - } - - //@todo move this to the handler of the namevalue attribute - if (this.namevalue) { - var edits = ["dropdown", "custom", "dropdown_container"]; - - for (var edit, c, i = 0; i < edits.length; i++) { - c = this.$getLayoutNode(edits[i]); - edit = edits[i]; - - if (i < edits.length - 1) { - c.setAttribute("onmousedown", "jpf.lookup(" + this.uniqueId - + ").$btndown(this, event);"); - c.setAttribute("onmouseup", "jpf.lookup(" + this.uniqueId - + ").$btnup(this)"); - c.setAttribute("onmouseout", "jpf.lookup(" + this.uniqueId - + ").$btnout(this)"); - c.setAttribute("type", edit); - - editors[edit] = jpf.xmldb.htmlImport(c, this.oInt) - } - else { - editors[edit] = c = jpf.xmldb.htmlImport(c, this.oExt) - editors[edit].style.zIndex = 100000; - - jpf.popup.setContent(this.uniqueId, editors[edit], - jpf.skins.getCssString(this.skinName)); - - //if (jpf.isTrue(this.$getOption(edit, "jml"))) - //continue; - - this.itemHeight = this.$getOption(edit, "item-height") || 18.5; - this.widthdiff = this.$getOption(edit, "width-diff") || 0; - } - } - - var changeListener = { - $xmlUpdate : function(action, xmlNode, loopNode, undoObj, oParent){ - if (!_self.xmlRoot) - return; - - /*if (action == "redo-remove") - oParent.appendChild(xmlNode); - - var lstUpdate = [], nodes = _self.xmlRoot.selectNodes("node()[@select]|node()/field[@select]"); - for (var node, s, i = 0, l = nodes.length; i < l; i++) { - node = nodes[i]; - s = node.getAttribute("select"); - //action == "insert" || action == "update" - if (jpf.xmldb.isChildOf(xmlNode, _self.xmlData.selectSingleNode(s), true) || - jpf.xmldb.isChildOf(_self.xmlData.selectSingleNode(s), xmlNode, true)){ - lstUpdate.pushUnique(node.tagName == "field" - ? node.parentNode - : node); - } - } - - if (action == "redo-remove") - oParent.removeChild(xmlNode); - - for (var i = 0, l = lstUpdate.length; i < l; i++) { - _self.$updateNode(lstUpdate[i], - jpf.xmldb.findHTMLNode(lstUpdate[i], _self)); - }*/ - - if (_self.$lastUpdated) { - _self.$updateNode(_self.$lastUpdated, - jpf.xmldb.findHTMLNode(_self.$lastUpdated, _self)); - _self.$lastUpdated = null - } - else { - var nodes = _self.getTraverseNodes(); - for (var i = 0, l = nodes.length; i < l; i++) { - _self.$updateNode(nodes[i], - jpf.xmldb.findHTMLNode(nodes[i], _self)); - } - } - - _self.dispatchEvent("xmlupdate", { - action : action, - xmlNode: xmlNode - }); - } - }; - changeListener.uniqueId = jpf.all.push(changeListener) - 1; - - var vRules = {}; - this.$_load = this.load; - this.load = function(xmlRoot, cacheId){ - var template = this.template || this.applyRuleSetOnNode("template", xmlRoot); - - //@todo need caching of the template - - if (template) { - this.$initTemplate(); - - this.xmlData = xmlRoot; - if (xmlRoot) - this.$loadSubData(xmlRoot); - - //@todo This is never removed - if (xmlRoot) - jpf.xmldb.addNodeListener(xmlRoot, changeListener); - - jpf.setModel(template, { - $xmlUpdate : function(){ - //debugger; - }, - - load: function(xmlNode){ - if (!xmlNode || this.isLoaded) - return; - - // retrieve the cacheId - if (!cacheId) { - cacheId = xmlNode.getAttribute(jpf.xmldb.xmlIdTag) || - jpf.xmldb.nodeConnect(jpf.xmldb.getXmlDocId(xmlNode), xmlNode); - } - - if (!_self.isCached(cacheId)) { - _self.$_load(xmlNode); - } - else { - //this.xmlRoot = null; - _self.$_load(xmlNode); - - var nodes = _self.getTraverseNodes(); - for (var s, i = 0, htmlNode, l = nodes.length; i < l; i++) { - htmlNode = jpf.xmldb.findHTMLNode(nodes[i], _self); - if (!htmlNode) - break; - - _self.$updateNode(nodes[i], htmlNode); - } - } - - _self.setProperty("disabled", _self.xmlData ? false : true); - this.isLoaded = true; //@todo how about cleanup? - }, - - setModel: function(model, xpath){ - model.register(this, xpath); - } - }); - } - else { - this.$_load.apply(this, arguments); - } - } - } - - if (this.cellselect) { - this.multiselect = false; - this.bufferselect = false; - - this.$select = function(o, xmlNode){ - if (this.renaming) - this.stopRename(null, true); - - if (!o || !o.style) - return; - - if (lastrow != o) { - this.selected = xmlNode; - this.selectCell({target:o.childNodes[lastcol || 0]}, o); - } - - return this.$setStyleClass(o, "selected"); - }; - - /*this.addEventListener("onafterselect", function(e){ - if (lastrow != this.$selected && this.$selected) - this.selectCell({target:this.$selected.childNodes[lastcol || 0]}, - this.$selected); - });*/ - } - }; - - this.$destroy = function(){ - jpf.popup.removeContent(this.uniqueId); - - //@todo destroy this.oTxt here - - if (editors["dropdown_container"]) { - editors["dropdown_container"].onmouseout = - editors["dropdown_container"].onmouseover = - editors["dropdown_container"].onmousedown = null; - } - - jpf.removeNode(this.oDrag); - this.oDrag = this.oExt.onclick = this.oInt.onresize = null; - - jpf.layout.removeRule(this.oInt, "dg" + this.uniqueId); - jpf.layout.activateRules(this.oInt); - }; - - this.counter = 0; -}).implement( - jpf.Rename, - jpf.DragDrop, - jpf.MultiSelect, - jpf.Cache, - jpf.DataBinding, - jpf.Presentation -); - - -jpf.convertIframe = function(iframe, preventSelect){ - var win = iframe.contentWindow; - var doc = win.document; - var pos; - - if (!jpf.isIE) - jpf.importClass(jpf.runNonIe, true, win); - - //Load Browser Specific Code - if (this.isSafari) - this.importClass(jpf.runSafari, true, win); - if (this.isOpera) - this.importClass(jpf.runOpera, true, win); - if (this.isGecko || !this.isIE && !this.isSafari && !this.isOpera) - this.importClass(jpf.runGecko, true, win); - - doc.onkeydown = function(e){ - if (!e) e = win.event; - - if (document.onkeydown) - return document.onkeydown.call(document, e); - //return false; - }; - - doc.onmousedown = function(e){ - if (!e) e = win.event; - - if (!pos) - pos = jpf.getAbsolutePosition(iframe); - - var q = { - offsetX : e.offsetX, - offsetY : e.offsetY, - x : e.x + pos[0], - y : e.y + pos[1], - button : e.button, - clientX : e.x + pos[0], - clientY : e.y + pos[1], - srcElement : iframe, - target : iframe, - targetElement : iframe - } - - if (document.body.onmousedown) - document.body.onmousedown(q); - if (document.onmousedown) - document.onmousedown(q); - - if (preventSelect && !jpf.isIE) - return false; - }; - - if (preventSelect) { - doc.onselectstart = function(e){ - return false; - }; - } - - doc.onmouseup = function(e){ - if (!e) e = win.event; - if (document.body.onmouseup) - document.body.onmouseup(e); - if (document.onmouseup) - document.onmouseup(e); - }; - - doc.onclick = function(e){ - if (!e) e = win.event; - if (document.body.onclick) - document.body.onclick(e); - if (document.onclick) - document.onclick(e); - }; - - //all these events should actually be piped to the events of the container.... - doc.documentElement.oncontextmenu = function(e){ - if (!e) e = win.event; - if (!pos) - pos = jpf.getAbsolutePosition(iframe); - - var q = { - offsetX : e.offsetX, - offsetY : e.offsetY, - x : e.x + pos[0], - y : e.y + pos[1], - button : e.button, - clientX : e.x + pos[0], - clientY : e.y + pos[1], - srcElement : e.srcElement, - target : e.target, - targetElement : e.targetElement - }; - - //if(this.host && this.host.oncontextmenu) this.host.oncontextmenu(q); - if (document.body.oncontextmenu) - document.body.oncontextmenu(q); - if (document.oncontextmenu) - document.oncontextmenu(q); - - return false; - }; - - doc.documentElement.onmouseover = function(e){ - pos = jpf.getAbsolutePosition(iframe); - }; - - doc.documentElement.onmousemove = function(e){ - if (!e) e = win.event; - if (!pos) - pos = jpf.getAbsolutePosition(iframe); - - var q = { - offsetX : e.offsetX, - offsetY : e.offsetY, - x : e.x + pos[0], - y : e.y + pos[1], - button : e.button, - clientX : e.x + pos[0], - clientY : e.y + pos[1], - srcElement : e.srcElement, - target : e.target, - targetElement : e.targetElement - } - - if (iframe.onmousemove) - iframe.onmousemove(q); - if (document.body.onmousemove) - document.body.onmousemove(q); - if (document.onmousemove) - document.onmousemove(q); - - return e.returnValue; - }; - - return doc; -}; - - -/*FILEHEAD(/var/lib/jpf/src/elements/checkbox.js)SIZE(-1077090856)TIME(1238944817)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -/** - * Element displaying a clickable rectangle having two states which - * can be toggled by user interaction. - * Example: - * <code> - * <j:checkbox values="full|empty">the glass is full</j:checkbox> - * </code> - * - * @constructor - * - * @define checkbox - * @addnode elements - * - * @author Ruben Daniels - * @version %I%, %G% - * @since 0.4 - * - * @inherits jpf.Presentation - * @inherits jpf.BaseButton - * @inherits jpf.Validation - * @inherits jpf.XForms - * @inherits jpf.DataBinding - * - * @binding value Determines the way the value for the element is retrieved - * from the bound data. - * Example: - * Sets the value of the checkbox based on data loaded into this component. - * <code> - * <j:checkbox> - * <j:bindings> - * <j:value select="@answer" /> - * </j:bindings> - * </j:checkbox> - * </code> - * Example: - * A shorter way to write this is: - * <code> - * <j:checkbox ref="@answer" /> - * </code> - */ -jpf.checkbox = jpf.component(jpf.NODE_VISIBLE, function(){ - this.editableParts = {"main" : [["label","text()"]]}; - - //Options - this.$notfromext = true; - this.$focussable = true; // This object can get the focus - this.checked = false; - - /**** Properties and Attributes ****/ - - this.$booleanProperties["checked"] = true; - this.$supportedProperties.push("value", "checked", "label", "values"); - - /** - * @attribute {String} value the value of this element. - */ - this.$propHandlers["value"] = function(value){ - value = (typeof value == "string" ? value.trim() : value); - - this.checked = (value !== undefined - && value.toString() == this.$values[0].toString()); - - if (!jpf.isNull(value) && value.toString() == this.$values[0].toString()) - this.$setStyleClass(this.oExt, this.baseCSSname + "Checked"); - else - this.$setStyleClass(this.oExt, "", [this.baseCSSname + "Checked"]); - }; - - /** - * @attribute {Boolean} checked whether the element is in the checked state. - */ - this.$propHandlers["checked"] = function(value) { - if (!this.$values) { - if (this.$jml.getAttribute("values")) - this.$propHandler["values"].call(this, this.$jml.getAttribute("values")); - else - this.$values = [false, true]; - } - this.setProperty("value", this.$values[value ? 0 : 1]); - }; - - /** - * @attribute {String} label the caption of the label explaining what - * the meaning of the checked state of this element is. - */ - this.$propHandlers["label"] = function(value){ - jpf.xmldb.setNodeValue( - this.$getLayoutNode("main", "label", this.oExt), value); - }; - - /** - * @attribute {String} values a pipe seperated list of two values which - * correspond to the two states of the checkbox. The first for the checked - * state, the second for the unchecked state. Defaults to "true|false". - */ - this.$propHandlers["values"] = function(value){ - this.$values = typeof value == "string" - ? value.split("\|") - : (value || [1, 0]); - }; - - /**** Public Methods ****/ - - /** - * Sets the value of this element. This should be one of the values - * specified in the values attribute. - * @param {String} value the new value of this element - */ - this.setValue = function(value){ - if (!this.$values) return; - this.setProperty("value", value); - }; - - /** - * Returns the current value - */ - this.getValue = function(){ - return this.xmlRoot ? this.$values[this.checked ? 0 : 1] : this.value; - }; - - /** - * Sets the checked state and related value - */ - this.check = function(){ - this.setProperty("value", this.$values[0]); - }; - - /** - * Sets the unchecked state and related value - */ - this.uncheck = function(){ - this.setProperty("value", this.$values[1]); - }; - - /**** Private state handling methods ****/ - - this.$clear = function(){ - this.setProperty("value", this.$values[1]); - } - - this.$enable = function(){ - if (this.oInt) this.oInt.disabled = false; - this.$doBgSwitch(1); - }; - - this.$disable = function(){ - if (this.oInt) this.oInt.disabled = true; - this.$doBgSwitch(4); - }; - - this.$setState = function(state, e, strEvent){ - if (this.disabled) return; - - this.$doBgSwitch(this.states[state]); - this.$setStyleClass(this.oExt, (state != "Out" ? this.baseCSSname + state : ""), - [this.baseCSSname + "Down", this.baseCSSname + "Over"]); - this.state = state; // Store the current state so we can check on it coming here again. - - this.dispatchEvent(strEvent, e); - - /*if (state == "Down") - jpf.cancelBubble(e, this); - else - e.cancelBubble = true;*/ - }; - - this.$clickHandler = function(){ - //this.checked = !this.checked; - this.change(this.$values[(!this.checked) ? 0 : 1]); - - this.validate(true); - - return true; - }; - - /**** Init ****/ - - this.$draw = function(){ - //Build Main Skin - this.oExt = this.$getExternal(); - this.oInt = this.$getLayoutNode("main", "input", this.oExt); - - this.$setupEvents(); - }; - - this.$loadJml = function(x){ - if (!this.label && x.firstChild) - this.setProperty("label", x.firstChild.nodeValue); - - this.$makeEditable("main", this.oExt, this.$jml); - - if (this.$values === undefined) - this.$values = [1, 0]; - }; - - this.$skinchange = function(){ - if (this.label) - this.$propHandlers["label"].call(this, this.label); - } -}).implement( - jpf.Validation, - jpf.DataBinding, - jpf.Presentation, - jpf.BaseButton -); - - - -/*FILEHEAD(/var/lib/jpf/src/elements/label.js)SIZE(-1077090856)TIME(1238944817)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-/**
- * Element displaying a text in the user interface, usually specifying
- * a description of another element. When the user clicks on the label it
- * can set the focus to the connected jml element.
- * Example:
- * The jml label element is used in the same way as the html label element. This
- * example shows the label as a child of a form element. It is rendered outside
- * to the element.
- * <code>
- * <j:textbox ref="address">
- * <j:label>Address</j:label>
- * </j:textbox>
- * </code>
- * Example:
- * This example uses the for attribute to connect the label to the form element.
- * <code>
- * <j:label for="txtAddress">Address</j:label>
- * <j:textbox id="txtAddress" ref="address" />
- * </code>
- *
- * @constructor
- * @allowchild {smartbinding}
- * @addnode elements
- *
- * @inherits jpf.BaseSimple
- *
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.4
- *
- * @binding value Determines the way the value for the element is retrieved
- * from the bound data.
- * Example:
- * Sets the label text based on data loaded into this component.
- * <code>
- * <j:label>
- * <j:bindings>
- * <j:value select="@text" />
- * </j:bindings>
- * </j:label>
- * </code>
- * Example:
- * A shorter way to write this is:
- * <code>
- * <j:label ref="@text" />
- * </code>
- */
-
-jpf.label = jpf.component(jpf.NODE_VISIBLE, function(){
- var _self = this;
-
- this.$focussable = false;
-
- this.editableParts = {
- "main": [["caption", "text()"]]
- };
-
- /** - * @copy Widget#setValue - */
- this.setValue = function(value){
- this.setProperty("value", value);
- };
-
- /** - * @copy Widget#getValue - */
- this.getValue = function(){
- return this.value;
- }
-
- /**
- * @attribute {String} value the text displayed in the area defined by this
- * element. Using the value attribute provides an alternative to using
- * the text using a text node.
- *
- * @attribute {String} for the id of the element that receives the focus
- * when the label is clicked on.
- */
- this.$supportedProperties.push("value", "for");
- this.$propHandlers["value"] = function(value){
- this.oInt.innerHTML = value;
- };
-
- this.$draw = function(){
- //Build Main Skin
- this.oExt = this.$getExternal();
- this.oInt = this.$getLayoutNode("main", "caption", this.oExt);
- if (this.oInt.nodeType != 1)
- this.oInt = this.oInt.parentNode;
-
- this.oExt.onmousedown = function(){
- var forElement = self[this["for"]];
- if (forElement && forElement.$focussable && forElement.focussable)
- forElement.focus();
- }
- };
-
- this.$loadJml = function(x){
- if (jpf.xmldb.isOnlyChild(x.firstChild, [3,4]))
- this.$handlePropSet("value", x.firstChild.nodeValue.trim());
- else
- jpf.JmlParser.parseChildren(this.$jml, this.oInt, this);
-
- this.$makeEditable("main", this.oExt, this.$jml);
- };
-}).implement(
- jpf.DataBinding,
- jpf.BaseSimple
-)
-
- - -/*FILEHEAD(/var/lib/jpf/src/elements/state.js)SIZE(-1077090856)TIME(1238944817)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-/**
- * @private
- */
-jpf.StateServer = {
- states: {},
- groups: {},
- locs : {},
-
- removeGroup: function(name, elState){
- this.groups[name].remove(elState);
- if (!this.groups[name].length) {
- if (self[name]) {
- self[name].destroy();
- self[name] = null;
- }
-
- delete this.groups[name];
- }
- },
-
- addGroup: function(name, elState, pNode){
- if (!this.groups[name]) {
- this.groups[name] = [];
-
- var pState = new jpf.state(null, "state");
- pState.parentNode = pNode;
- pState.inherit(jpf.JmlDom);
- pState.name = name;
- pState.toggle = function(){
- for (var next = 0, i = 0; i < jpf.StateServer.groups[name].length; i++) {
- if (jpf.StateServer.groups[name][i].active) {
- next = i + 1;
- break;
- }
- }
-
- jpf.StateServer.groups[name][
- (next == jpf.StateServer.groups[name].length) ? 0 : next
- ].activate();
- }
-
- this.groups[name].pState = self[name] = pState;
- }
-
- if (elState)
- this.groups[name].push(elState);
-
- return this.groups[name].pState;
- },
-
- removeState: function(elState){
- delete this.states[elState.name];
- },
-
- addState: function(elState){
- this.states[elState.name] = elState;
- }
-}
-
-/**
- * Element that specifies a certain state of (a part of) the application. With
- * state we mean a collection of properties on objects that have a certain
- * value at one time. This element allows you to specify which properties on
- * which elements should be set when this state is actived. This element can
- * belong to a state-group containing multiple elements with a default state.
- * Example:
- * This example shows a log in window and four state elements in a state-group.
- * <code>
- * <j:window id="winLogin" title="Log in"> - * ... - * - * <j:text id="loginMsg" height="20" left="10" bottom="10" /> - * <j:button>Log in</j:button> - * </j:window>
- *
- * <j:state-group - * loginMsg.visible = "false" - * winLogin.disabled = "false"> - * <j:state id="stFail" - * loginMsg.value = "Username or password incorrect" - * loginMsg.visible = "true" /> - * <j:state id="stError" - * loginMsg.value = "An error has occurred. Please check your network." - * loginMsg.visible = "true" /> - * <j:state id="stLoggingIn" - * loginMsg.value = "Please wait while logging in..." - * loginMsg.visible = "true" - * winLogin.disabled = "true" /> - * <j:state id="stIdle" /> - * </j:state-group>
- * </code>
- * Example:
- * This example shows a label using property binding to get it's caption
- * based on the current state.
- * <code>
- * <j:state group="stRole" id="stUser" caption="You are a user" active="true" />
- * <j:state group="stRole" id="stAdmin" caption="You have super powers" />
- *
- * <j:label value="{stRole.caption}" />
- * <j:button onclick="stAdmin.activate()">Become admin</j:button>
- * </code>
- *
- * @event change Fires when the active property of this element changes.
- *
- * @constructor
- * @define state
- * @addnode global
- *
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.9
- */
-jpf.state = jpf.component(jpf.NODE_HIDDEN, function(){
-
- /**** Properties and Attributes ****/
-
- this.$supportedProperties.push("active");
-
- /**
- * @attribute {Boolean} active whether this state is the active state
- */
- this.$propHandlers["active"] = function(value){
- //Activate State
- if (jpf.isTrue(value)) {
- if (this.group) {
- var nodes = jpf.StateServer.groups[this.group];
- for (var i = 0; i < nodes.length; i++) {
- if (nodes[i] != this && nodes[i].active !== false)
- nodes[i].deactivate();
- }
- }
-
- var q = this.$signalElements;
- for (var i = 0; i < q.length; i++) {
- if (!self[q[i][0]] || !self[q[i][0]].setProperty) {
- throw new Error(jpf.formatErrorString(1013, this,
- "Setting State",
- "Could not find object to give state: '"
- + q[i][0] + "' on property '" + q[i][1] + "'"));
- }
-
- self[q[i][0]].setProperty(q[i][1], this[q[i].join(".")]);
- }
-
- if (this.group) {
- var attr = this.$jml.attributes;
- for (var i = 0; i < attr.length; i++) {
- if (attr[i].nodeName.match(/^on|^(?:group|id)$|^.*\..*$/))
- continue;
- self[this.group].setProperty(attr[i].nodeName,
- attr[i].nodeValue);
- }
- }
-
- this.dispatchEvent("change");
-
- jpf.console.info("Setting state '" + this.name + "' to ACTIVE");
- }
-
- //Deactivate State
- else {
- this.setProperty("active", false);
- this.dispatchEvent("change");
-
- jpf.console.info("Setting state '" + this.name + "' to INACTIVE");
- }
- };
-
-
- /**** Public methods ****/
-
- /**
- * @copy Widget#setValue
- */
- this.setValue = function(value){
- this.active = 9999;
- this.setProperty("active", value);
- };
-
- /**
- * Actives this state, setting all the properties on the elements that
- * were specified.
- */
- this.activate = function(){
- this.active = 9999;
- this.setProperty("active", true);
- };
-
- /**
- * Deactivates the state of this element. This is mostly a way to let all
- * elements that have property bound to this state know it is no longer
- * active.
- */
- this.deactivate = function(){
- this.setProperty("active", false);
- };
-
- /**** Init ****/
-
- this.$signalElements = [];
-
- this.$loadJml = function(x){
- jpf.StateServer.addState(this);
-
- this.group = x.getAttribute("group");
- if (this.group)
- jpf.StateServer.addGroup(this.group, this);
-
- if (x.getAttribute("location"))
- jpf.StateServer.locs[x.getAttribute("location")] = this;
-
- //Properties initialization
- var attr = x.attributes;
- for (var s, i = 0; i < attr.length; i++) {
- if (attr[i].nodeName.match(/^on|^(?:group|id)$/))
- continue;
-
- s = attr[i].nodeName.split(".");
- if (s.length == 2)
- this.$signalElements.push(s);
-
- this[attr[i].nodeName] = attr[i].nodeValue;
- }
- };
-
- this.$destroy = function(){
- this.$signalElements = null;
- jpf.StateServer.removeState(this);
- if (this.group)
- jpf.StateServer.removeGroup(this.group, this);
- };
-});
-
- - -/*FILEHEAD(/var/lib/jpf/src/elements/appsettings.js)SIZE(-1077090856)TIME(1238933683)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * Element specifying the settings of the application.
- * @define appsettings
- * @addnode global
- * @attribute {Boolean} debug whether the debug screen is shown and debug logging is enabled.
- * @attribute {Boolean} debug-teleport whether teleport messages are displayed in the log.
- * @attribute {String} name the name of the application, used by many different services to uniquely identify the application.
- * @attribute {Boolean} disable-right-click whether a user can get the browsers contextmenu when the right mouse button is clicked.
- * @attribute {Boolean} allow-select whether any text in the application can be selected.
- * @attribute {Boolean} allow-blur whether it's possible to blur an element while not giving the focus to another element
- * @attribute {Boolean} auto-disable-actions whether smartbinding actions are by default disabled.
- * @attribute {Boolean} auto-disable whether elements that don't have content loaded are automatically disabled.
- * @attribute {Boolean} disable-f5 whether the F5 key for refreshing is disabled.
- * @attribute {Boolean} auto-hide-loading whether the load screen defined j:loader is automatically hidden.
- * @attribute {Boolean} disable-space whether the space button default behaviour of scrolling the page is disabled.
- * @attribute {Boolean} disable-backspace whether the backspace button default behaviour of going to the previous history state is disabled.
- * @attribute {Boolean} undokeys whether the undo and redo keys (in windows they are ctrl-Z and ctrl-Y) are enabled.
- * @attribute {String, Boolean} outline whether an outline of an element is shown while dragging or resizing.
- * @attribute {String, Boolean} drag-outline whether an outline of an element is shown while dragging.
- * @attribute {String, Boolean} resize-outline whether an outline of an element is shown while resizing.
- * @attribute {String} layout a datainstruction which retrieves a layout xml node or string
- * @attribute {String} baseurl The basepath for any relative url used throughout your application. This included teleport definitions and data instrutions.
- * @attribute {String} loading-message Specifying the global value for the loading message of elements during a loading state.
- * @attribute {String} offline-message Specifying the global value for the offline message of elements not able to display content while offline.
- * @attribute {String} empty-message Specifying the global value for the empty message of elements containing no contents.
- * @attribute {String} model Specifying the default model for this application.
- * @attribute {String} realtime Specifying the global value which enables or disabled realtime updating of bound data while changing the value. When set to false elements don't update until they loose focus.
- * @attribute {String} skinset the skin set used by the application.
- * @attribute {String} storage the storage provider to be used for key/value storage.
- * @attribute {String} offline the storage provider to be used for offline support.
- * @attribute {String} login the datainstruction which logs a user into the application.
- * @attribute {String} logout the datainstruction which logs a user out of the application.
- * @attribute {String} iepngfix whether the fix for PNG images with transparency should applied
- * @allowchild auth, authentication, offline, printer, defaults
- * @todo describe defaults
- */
-jpf.appsettings = {
- tagName : "appsettings",
- nodeType : jpf.NODE_ELEMENT,
- nodeFunc : jpf.NODE_HIDDEN,
-
-
- //Defaults
- disableRightClick : false,
- allowSelect : false,
- allowBlur : false,
- autoDisableActions : false,
- autoDisable : false, /** @todo fix this to only autodisable when createmodel is not true */
- disableF5 : true,
- autoHideLoading : true,
- disableSpace : true,
- disableBackspace : true,
- useUndoKeys : false,
- outline : false,
- dragOutline : false,
- resizeOutline : false,
- disableTabbing : false,
- resourcePath : null,
- iePngFix : false,
- skinset : "default",
- name : "",
-
- tags : {},
- defaults : {},
- baseurl : "",
-
- init : function(){
- if (jpf.isParsingPartial) {
- this.disableRightClick = false;
- this.allowSelect = true;
- this.autoDisableActions = true;
- this.autoDisable = false;
- this.disableF5 = false;
- this.autoHideLoading = true;
- this.disableSpace = false;
- this.disableBackspace = false;
- this.useUndoKeys = false;
- this.disableTabbing = true;
- this.allowBlur = true;
- }
- },
-
- getDefault : function(type, prop){
- var d = this.defaults[type];
- if (!d)
- return;
-
- for (var i = d.length - 1; i >= 0; i--) {
- if (d[i][0] == prop)
- return d[i][1];
- }
- },
-
- setProperty : function(name, value){
- if (name == "outline") {
- this.dragOutline =
- this.resizeOutline =
- this.outline = value;
- }
- else if (name == "skinset") {
- this.skinset = value;
- jpf.skins.changeSkinset(value);
- }
- },
-
- //@todo adhere to defaults (loop attributes)
- loadJml: function(x, parentNode){
- this.$jml = x;
-
- this.parentNode = parentNode;
- jpf.inherit.call(this, jpf.JmlDom); /** @inherits jpf.JmlDom */
-
- //Set Globals
- jpf.debug = jpf.isTrue(x.getAttribute("debug"));
- if (x.getAttribute("debug-type"))
- jpf.debugType = x.getAttribute("debug-type");
-
- var nodes = x.attributes;
- for (var i = 0, l = nodes.length; i < l; i++) {
- this.tags[nodes[i].nodeName] = nodes[i].nodeValue;
- }
-
- jpf.debugFilter = jpf.isTrue(x.getAttribute("debug-teleport")) ? "" : "!teleport";
-
- if (jpf.debug) {
- jpf.addEventListener("load", function(){
- setTimeout("jpf.debugwin.activate();", 200) //@todo has a bug in gecko, chrome
- });
- }
-
- this.name = x.getAttribute("name")
- || window.location.href.replace(/[^0-9A-Za-z_]/g, "_");
-
- this.baseurl = jpf.parseExpression(x.getAttribute("baseurl") || "");
- this.resourcePath = jpf.parseExpression(x.getAttribute("resource-path") || "").replace(/resources\/?/, '');
- if (this.resourcePath && this.resourcePath.charAt(this.resourcePath.length - 1) != "/")
- this.resourcePath = this.resourcePath + "/";
- this.disableRightClick = jpf.isTrue(x.getAttribute("disable-right-click"));
- this.allowSelect = jpf.isTrue(x.getAttribute("allow-select"));
- this.allowBlur = !jpf.isFalse(x.getAttribute("allow-blur"));
-
- this.autoDisableActions = jpf.isTrue(x.getAttribute("auto-disable-actions"));
- this.autoDisable = jpf.isTrue(x.getAttribute("auto-disable")); //@todo temporarily changed default
- this.disableF5 = jpf.isTrue(x.getAttribute("disable-f5"));
- this.autoHideLoading = !jpf.isFalse(x.getAttribute("auto-hide-loading"));
-
- this.disableSpace = !jpf.isFalse(x.getAttribute("disable-space"));
- this.disableBackspace = jpf.isTrue(x.getAttribute("disable-backspace"));
- this.useUndoKeys = jpf.isTrue(x.getAttribute("undokeys"));
-
- this.queryAppend = x.getAttribute("query-append");
-
- if (x.getAttribute("outline")) {
- this.dragOutline =
- this.resizeOutline =
- this.outline = jpf.isTrue(jpf.parseExpression(x.getAttribute("outline")));
- }
- else {
- this.dragOutline = x.getAttribute("drag-outline")
- ? jpf.isTrue(jpf.parseExpression(x.getAttribute("drag-outline")))
- : false;
- this.resizeOutline = x.getAttribute("resize-outline")
- ? !jpf.isFalse(jpf.parseExpression(x.getAttribute("resize-outline")))
- : false;
- }
-
- this.iePngFix = (!jpf.supportPng24
- && (jpf.isTrue(x.getAttribute("iepngfix"))
- || x.getAttribute("iepngfix-elements")));
- if (this.iePngFix) {
- // run after the init() has finished, otherwise the body of the
- // document will still be empty, thus no elements found.
- setTimeout(function() {
- jpf.iepngfix.limitTo(x.getAttribute("iepngfix-elements") || "").run();
- });
- }
-
- if (jpf.isDeskrun && this.disableF5)
- shell.norefresh = true;
-
- //Application features
- this.layout = x.getAttribute("layout") || null;
- this.skinset = x.getAttribute("skinset") || "default";
-
- this.storage = x.getAttribute("storage") || null;
- if (this.storage)
- jpf.storage.init(this.storage);
-
- this.offline = x.getAttribute("offline");
- if (this.offline && typeof jpf.offline != "undefined")
- jpf.offline.init(this.offline);
-
- if (x.getAttribute("login"))
- jpf.auth.init(x);
-
- var oFor, attr, d, j, i, l, node, nodes = x.childNodes;
- for (i = 0, l = nodes.length; i < l; i++) {
- node = nodes[i];
- if (node.nodeType != 1)
- continue;
-
- var tagName = node[jpf.TAGNAME];
- switch(tagName){
- case "auth":
- case "authentication":
- this.auth = node;
- jpf.auth.init(node);
- break;
- case "offline":
- this.offline = node;
- jpf.offline.init(node);
- break;
- case "printer":
- jpf.printer.init(node);
- break;
- case "defaults":
- oFor = node.getAttribute("for");
- attr = node.attributes;
- d = this.defaults[oFor] = [];
- for (j = attr.length - 1; j >= 0; j--)
- d.push([attr[j].nodeName, attr[j].nodeValue]);
- break;
- default:
- break;
- }
- }
-
- return this;
- }
-};
-
-
-/**
- * @constructor
- */
-jpf.settings = function(){
- jpf.register(this, "settings", jpf.NODE_HIDDEN);/** @inherits jpf.Class */
- var oSettings = this;
-
- /* ********************************************************************
- PROPERTIES
- *********************************************************************/
- this.inherit(jpf.DataBinding); /** @inherits jpf.DataBinding */
- /* ********************************************************************
- PUBLIC METHODS
- *********************************************************************/
- this.getSetting = function(name){
- return this[name];
- };
-
- this.setSetting = function(name, value){
- this.setProperty(name, value);
- };
-
- this.isChanged = function(name){
- if (!savePoint)
- return true;
- return this.getSettingsNode(savePoint, name) != this[name];
- };
-
- this.exportSettings = function(instruction){
- if (!this.xmlRoot)
- return;
-
- jpf.saveData(instruction, this.xmlRoot, null, function(data, state, extra){
- if (state != jpf.SUCCESS) {
- var oError;
-
- oError = new Error(jpf.formatErrorString(0,
- oSettings, "Saving settings",
- "Error saving settings: " + extra.message));
-
- if (extra.tpModule.retryTimeout(extra, state, null, oError) === true)
- return true;
-
- throw oError;
- }
- });
-
- this.savePoint();
- };
-
- this.importSettings = function(instruction, def_instruction){
- jpf.getData(instruction, null, null, function(xmlData, state, extra){
- if (state != jpf.SUCCESS) {
- var oError;
-
- oError = new Error(jpf.formatErrorString(0, oSettings,
- "Loading settings",
- "Error loading settings: " + extra.message));
-
- if (extra.tpModule.retryTimeout(extra, state, this, oError) === true)
- return true;
-
- throw oError;
- }
-
- if (!xmlData && def_instruction)
- oSettings.importSettings(def_instruction);
- else
- oSettings.load(xmlData);
- });
- };
-
- var savePoint;
- this.savePoint = function(){
- savePoint = jpf.xmldb.copyNode(this.xmlRoot);
- };
-
- //Databinding
- this.smartBinding = true;//Hack to ensure that data is loaded, event without smartbinding
- this.$load = function(XMLRoot){
- jpf.xmldb.addNodeListener(XMLRoot, this);
-
- for (var prop in settings) {
- this.setProperty(prop, null); //Maybe this should be !and-ed
- delete this[prop];
- delete settings[prop];
- }
-
- var nodes = this.xmlRoot.selectNodes(this.traverseRule || "node()[text()]");
- for (var i = 0; i < nodes.length; i++) {
- this.setProperty(this.applyRuleSetOnNode("name", nodes[i])
- || nodes[i].tagName, this.applyRuleSetOnNode("value", nodes[i])
- || getXmlValue(nodes[i], "text()"));
- }
- };
-
- this.$xmlUpdate = function(action, xmlNode, listenNode){
- //Added setting
- var nodes = this.xmlRoot.selectNodes(this.traverseRule || "node()[text()]");
- for (var i = 0; i < nodes.length; i++) {
- var name = this.applyRuleSetOnNode("name", nodes[i]) || nodes[i].tagName;
- var value = this.applyRuleSetOnNode("value", nodes[i])
- || getXmlValue(nodes[i], "text()");
- if (this[name] != value)
- this.setProperty(name, value);
- }
-
- //Deleted setting
- for (var prop in settings) {
- if (!this.getSettingsNode(this.xmlRoot, prop)) {
- this.setProperty(prop, null);
- delete this[prop];
- delete settings[prop];
- }
- }
- };
-
- this.reset = function(){
- if (!savePoint) return;
-
- this.load(jpf.xmldb.copyNode(savePoint));
- };
-
- //Properties
- this.getSettingsNode = function(xmlNode, prop, create){
- if (!xmlNode)
- xmlNode = this.xmlRoot;
-
- var nameNode = this.getNodeFromRule("name", this.xmlRoot);
- var valueNode = this.getNodeFromRule("value", this.xmlRoot);
- nameNode = nameNode ? nameNode.getAttribute("select") : "@name";
- valueNode = valueNode ? valueNode.getAttribute("select") || "text()" : "text()";
- var traverse = this.traverseRule + "[" + nameNode + "='" + prop + "']/"
- + valueNode || prop + "/" + valueNode;
-
- return create
- ? jpf.xmldb.createNodeFromXpath(xmlNode, traverse)
- : jpf.getXmlValue(this.xmlNode, traverse);
- };
-
- this.$handlePropSet = function(prop, value, force){
- if (!force && this.xmlRoot)
- return jpf.xmldb.setNodeValue(this.getSettingsNode(
- this.xmlRoot, prop, true), true);
-
- this[prop] = value;
- settings[prop] = value;
- };
-
- /**
- * @private
- */
- this.loadJml = function(x){
- this.importSettings(x.getAttribute("get"), x.getAttribute("default"));
- this.exportInstruction = x.getAttribute("set");
-
- this.$jml = x;
- jpf.JmlParser.parseChildren(this.$jml, null, this);
-
- //Model handling in case no smartbinding is used
- var modelId = jpf.xmldb.getInheritedAttribute(x, "model");
-
- for (var i = 0; i < jpf.JmlParser.modelInit.length; i++)
- if (jpf.JmlParser.modelInit[i][0] == this)
- return;
-
- jpf.setModel(modelId, this);
- };
-
- //Destruction
- this.destroy = function(){
- if (this.exportInstruction)
- this.exportSettings(this.exportInstruction);
- };
-};
-
- - -/*FILEHEAD(/var/lib/jpf/src/elements/palette.js)SIZE(-1077090856)TIME(1238944817)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - -/** - * Element displaying a set of choices to the user which allows - * him/her to pick a specific color. This element also gives the - * user a choice to add a custom color. - * - * @constructor - * @define palette - * @allowchild {smartbinding} - * @addnode elements - * - * @inherits jpf.XForms - * @inherits jpf.Presentation - * @inherits jpf.Validation - * @inherits jpf.DataBinding - * - * @author Ruben Daniels - * @version %I%, %G% - * @since 0.4 - * - * @binding value Determines the way the value for the element is retrieved - * from the bound data. - * Example: - * Sets the color based on data loaded into this component. - * <code> - * <j:palette> - * <j:bindings> - * <j:value select="@color" /> - * </j:bindings> - * </j:palette> - * </code> - * Example: - * A shorter way to write this is: - * <code> - * <j:palette ref="@color" /> - * </code> - */ -jpf.palette = jpf.component(jpf.NODE_VISIBLE, function(){ - - /**** Properties and Attributes ****/ - - this.$focussable = true; // This object can get the focus - this.value = null; - this.direction = "down"; - - this.$supportedProperties.push("value"); - /** - * The selected color of the palette - */ - this.$propHandlers["value"] = function(value){ - this.oViewer.style.backgroundColor = value; - }; - - /**** Public methods ****/ - - /** - * @copy Widget#setValue - */ - this.setValue = function(value){ - this.setProperty("value", value); - }; - - /** - * @copy Widget#getValue - */ - this.getValue = function(){ - return this.value ? this.value.nodeValue : ""; - }; - - /**** Private state handling methods ****/ - - this.$addColor = function(clr, oContainer){ - if (!oContainer) - oContainer = this.oCustom; - - var oItem = this.$getLayoutNode("item"); - - if (oContainer == this.oCustom) { - oItem.setAttribute("onmousedown", "jpf.lookup(" - + this.uniqueId + ").$doCustom(this)"); - oItem.setAttribute("ondblclick", "jpf.lookup(" - + this.uniqueId + ").$doCustom(this, true)"); - } - else - oItem.setAttribute("onmousedown", "jpf.lookup(" + this.uniqueId - + ").change(this.style.backgroundColor.replace(/^#/, ''))"); - - oItem = jpf.xmldb.htmlImport(oItem, oContainer, null, true); - this.$getLayoutNode("item", "background", oItem).style.backgroundColor = clr; - }; - - this.$setCustom = function(oItem, clr){ - oItem.style.backgroundColor = clr; - this.change(clr); - }; - - /** - * @event createcustom Fires when a custom color is choosen. This event allows the developer to display a color picker to fill the palette's color. - * object: - * {HTMLElement} htmlNode the rectangle in the palette to be filled. - */ - this.$doCustom = function(oItem, force_create){ - if (force_create || oItem.style.backgroundColor == "#ffffff") { - this.dispatchEvent("createcustom", { - htmlNode: oItem - }); - } - else - this.change(oItem.style.backgroundColor.replace(/^#/, "")); - }; - - this.defaultValue = "ff0000"; - - this.colors = ["fc0025", "ffd800", "7dff00", "32ffe0", "0026ff", - "cd00ff", "ffffff", "e5e5e5", "d9d9d9", "de003a", - "ffc600", "009022", "00bee1", "003e83", "dc0098", - "737373", "666666", "000000"]; - - this.$draw = function(){ - //Build Main Skin - this.oExt = this.$getExternal(); - this.oViewer = this.$getLayoutNode("main", "viewer", this.oExt); - this.oStandard = this.$getLayoutNode("main", "standard", this.oExt); - this.oCustom = this.$getLayoutNode("main", "custom", this.oExt); - - var i; - for (i = 0; i < this.colors.length; i++) - this.$addColor(this.colors[i], this.oStandard); - for (i = 0; i < 9; i++) - this.$addColor("ffffff"); - - //this.oViewer.setAttribute("ondblclick", "jpf.lookup(" + this.uniqueId + ").openColorPicker()"); - }; -}).implement( - jpf.DataBinding, - jpf.Validation, - jpf.Presentation -); - - - -/*FILEHEAD(/var/lib/jpf/src/elements/video/type_silverlight.js)SIZE(-1077090856)TIME(1238933680)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -/** - * Element displaying a Silverlight video - * - * @classDescription This class creates a new Silverlight video player - * @return {TypeSilverlight} Returns a new Silverlight video player - * @type {TypeSilverlight} - * @constructor - * @addnode elements:video - * - * @author Mike de Boer - * @version %I%, %G% - * @since 1.0 - */ -jpf.video.TypeSilverlight = function(oVideo, node, options) { - this.oVideo = oVideo; - if (!jpf.video.TypeSilverlight.INITED) { - jpf.silverlight.startup(); - jpf.video.TypeSilverlight.INITED = true; - } - - this.DEFAULT_PLAYER = (jpf.appsettings.resourcePath || jpf.basePath) + "resources/wmvplayer.xaml"; - this.htmlElement = node; - this.options = { - backgroundcolor: "000000", - windowless: "false", - file: "", - image: "", - backcolor: "000000", - frontcolor: "FFFFFF", - lightcolor: "FFFFFF", - screencolor: "FFFFFF", - width: "100%", - height: "100%", - logo: "", - overstretch: "true", - shownavigation: "false", - showstop: "false", - showdigits: "true", - usefullscreen: "true", - usemute: "false", - autostart: "true", - bufferlength: "3", - duration: "0", - repeat: "false", - sender: "", - start: "0", - volume: "90", - link: "", - linkfromdisplay: "false", - linktarget: "_self" - }; - this.options.file = options.src; - - for (var itm in this.options) { - if (options[itm] != undefined) { - if (itm.indexOf("color") > 0) - this.options[itm] = options[itm].substr(options[itm].length - 6); - else - this.options[itm] = options[itm]; - } - } - - jpf.silverlight.createObjectEx({ - id: this.oVideo.uniqueId + "_Player", - source: this.DEFAULT_PLAYER, - parentElement: node, - properties: { - width: "100%", - height: "100%", - version: "1.0", - inplaceInstallPrompt: true, - isWindowless: this.options["windowless"], - background: "#" + this.options["backgroundcolor"] - }, - events: { - onLoad: this.onLoadHandler, - onError: jpf.silverlight.default_error_handler - }, - context: this - }); - - //jpf.extend(this, jpf.video.TypeInterface); - jpf.layout.setRules(this.oVideo.oExt, this.oVideo.uniqueId + "_silverlight", - "jpf.all[" + this.oVideo.uniqueId + "].player.resizePlayer()"); -}; - -jpf.video.TypeSilverlight.isSupported = function(){ - return jpf.silverlight.isAvailable("1.0"); -}; - -jpf.video.TypeSilverlight.INITED = false; - -jpf.video.TypeSilverlight.prototype = { - /** - * Play a WMV movie. Does a call to the XAML Silverlight player to load or - * load & play the video, depending on the 'autoPlay' flag (TRUE for play). - * - * @param {String} videoPath Path to the movie. - * @type {Object} - */ - load: function(videoPath) { - this.video.Source = this.options["file"]; - - this.oVideo.$readyHook({ type: "ready" }); - - if (this.options["usemute"] == "true") - this.setVolume(0); - else - this.setVolume(this.options["volume"]); - if (this.options["autostart"] == "true") - this.play(); - else - this.pause(); - - return this; - }, - - /** - * Play and/ or resume a video that has been loaded already - * - * @type {Object} - */ - play: function() { - if (this.state == "buffering" || this.state == "playing") { - if (this.options["duration"] == 0) - this.stop(); - else - this.pause(); - } - else { - this.video.Visibility = "Visible"; - this.preview.Visibility = "Collapsed"; - if (this.state == "closed") - this.video.Source = this.options["file"]; - else - this.video.play(); - } - return this; - }, - - /** - * Toggle the pause state of the video. - * - * @type {Object} - */ - pause: function() { - if (!this.video) return this; - this.video.pause(); - return this; - //this.oVideo.$changeHook({ - // type : "change", - // playheadTime: Math.round(this.video.Position.Seconds * 10) / 10 - //}); - }, - - /** - * Stop playback of the video. - * - * @type {Object} - */ - stop: function() { - if (!this.video) return; - this.stopPlayPoll(); - this.video.Visibility = "Collapsed"; - this.preview.Visibility = "Visible"; - this.pause().seek(0); - this.video.Source = "null"; - return this; - }, - - /** - * Seek the video to a specific position. - * - * @param {Number} iTo The number of seconds to seek the playhead to. - * @type {Object} - */ - seek: function(iTo) { - if (!this.video) return; - this.stopPlayPoll(); - if (iTo < 2) - iTo = 0; - else if (iTo > this.options["duration"] - 4) - iTo = this.options["duration"] - 4; - //this.play(); - if (!isNaN(iTo)) { - try{ //@todo added by ruben - this.video.Position = this.oVideo.getCounter(iTo, "%H:%M:%S");//this.spanstring(iTo); - } - catch(e){} - } - if (this.state == "buffering" || this.state == "playing") - this.play(); - else - this.pause(); - return this; - }, - - /** - * Set the volume of the video to a specific range (0 - 100) - * - * @param {Number} iVolume - * @type {Object} - */ - setVolume: function(iVolume) { - if (!this.video) return; - this.video.Volume = iVolume / 100; - return this; - }, - - /** - * Retrieve the total playtime of the video, in seconds. - * - * @type {Number} - */ - getTotalTime: function() { - if (!this.video) return 0; - return this.options["duration"] || 0; - }, - - /** - * Format a number of seconds to a format the player groks: - * HH:MM:SS - * - * @param {Number} stp In seconds - * @type {String} - */ - spanstring: function(stp) { - var hrs = Math.floor(stp / 3600); - var min = Math.floor(stp % 3600 / 60); - var sec = Math.round(stp % 60 * 10) / 10; - var str = hrs + ":" + min + ":" + sec; - return str; - }, - - /** - * Fired when the XAML player object has loaded its resources (including - * the video file inside the <MediaElement> object and is ready to play. - * Captures the reference to the player object. - * - * @param {String} pId - * @param {Object} _self Context of the player ("this") - * @param {Object} sender XAML Player object instance - * @type {void} - */ - onLoadHandler: function(pId, _self, sender) { - // 'o = this' in this case, sent back to us from the Silverlight helper script - - _self.options["sender"] = sender; - _self.video = _self.options["sender"].findName("VideoWindow"); - _self.preview = _self.options["sender"].findName("PlaceholderImage"); - var str = { - "true" : "UniformToFill", - "false": "Uniform", - "fit" : "Fill", - "none" : "None" - } - _self.state = _self.video.CurrentState.toLowerCase(); - _self.pollTimer; - _self.video.Stretch = str[_self.options["overstretch"]]; - _self.preview.Stretch = str[_self.options["overstretch"]]; - - _self.display = sender.findName("PlayerDisplay"); - _self.display.Visibility = "Visible"; - - _self.video.BufferingTime = _self.spanstring(_self.options["bufferlength"]); - _self.video.AutoPlay = true; - - _self.video.AddEventListener("CurrentStateChanged", function() { - _self.handleState("CurrentStateChanged"); - }); - _self.video.AddEventListener("MediaEnded", function() { - _self.handleState("MediaEnded"); - }); - // BufferProgressChanged is of no use in XAML - _self.video.AddEventListener("DownloadProgressChanged", function(o) { - _self.oVideo.$progressHook({ - bytesLoaded: Math.round(o.downloadProgress * 100), //percentage - totalBytes : 100 - }); - }); - if (_self.options["image"] != "") - _self.preview.Source = _self.options["image"]; - - _self.resizePlayer(); - - _self.oVideo.$initHook({state: _self.state}); - }, - - /** - * Process a 'CurrentStateChanged' event when the player fired it or a - * 'MediaEnded' event when the video stopped playing. - * - * @param {Object} sEvent Name of the event that was fired (either 'CurrentStateChanged' or 'MediaEnded') - * @type void - */ - handleState: function(sEvent) { - var state = this.video.CurrentState.toLowerCase(); - if (sEvent == "MediaEnded") { - this.stopPlayPoll(); - this.oVideo.$changeHook({ - type : "change", - playheadTime: Math.round(this.video.Position.Seconds * 1000) - }); - if (this.options["repeat"] == "true") { - this.seek(0).play(); - } else { - this.state = "completed"; - this.video.Visibility = "Collapsed"; - this.preview.Visibility = "Visible"; - this.seek(0).pause().oVideo.$completeHook({ type: "complete" }); - } - } - //CurrentStateChanged: - else if (state != this.state) { - this.state = state; - this.options["duration"] = Math.round(this.video.NaturalDuration.Seconds * 1000); - if (state != "playing" && state != "buffering" && state != "opening") { - this.oVideo.$stateChangeHook({type: "stateChange", state: "paused"}); - this.stopPlayPoll(); - } - else { - this.oVideo.$stateChangeHook({type: "stateChange", state: "playing"}); - this.startPlayPoll(); - } - } - }, - - /** - * Start the polling mechanism that checks for progress in playtime of the - * video. - * - * @type {Object} - */ - startPlayPoll: function() { - clearTimeout(this.pollTimer); - var _self = this; - this.pollTimer = setTimeout(function() { - if (_self.oVideo && !_self.oVideo.ready && _self.video.CanSeek) - _self.oVideo.setProperty("readyState", jpf.Media.HAVE_ENOUGH_DATA); - _self.oVideo.$changeHook({ - type : "change", - playheadTime: Math.round(_self.video.Position.Seconds * 1000) - }); - _self.startPlayPoll(); - }, 100); - return this; - }, - - /** - * Stop the polling mechanism, started by startPlayPoll(). - * - * @type {Object} - */ - stopPlayPoll: function() { - clearTimeout(this.pollTimer); - return this; - }, - - /** - * Resize the dimensions of the player object to the ones specified by the - * <VIDEO> tag width and height properties. The video will be scaled/ stretched - * accordingly - * - * @type {Object} - */ - resizePlayer: function() { - var oSender = this.options["sender"]; - if (!oSender) return; - var oContent = this.display.getHost().content; - var width = oContent.actualWidth; - var height = oContent.actualHeight; - - this.stretchElement("PlayerDisplay", width, height) - .stretchElement("VideoWindow", width,height) - .stretchElement("PlaceholderImage", width, height) - .centerElement("BufferIcon", width, height) - .centerElement("BufferText", width, height) - this.display.findName("OverlayCanvas")["Canvas.Left"] = width - - this.display.findName("OverlayCanvas").Width - 10; - this.display.Visibility = "Visible"; - - return this; - }, - - /** - * Position a XAML element in the center of the canvas it is a member of - * - * @param {String} sName Name or ID of the element - * @param {Number} iWidth Current width of the canvas - * @param {Number} iHeight Current height of the canvas - * @type {Object} - */ - centerElement: function(sName, iWidth, iHeight) { - var elm = this.options["sender"].findName(sName); - elm["Canvas.Left"] = Math.round(iWidth / 2 - elm.Width / 2); - elm["Canvas.Top"] = Math.round(iHeight / 2 - elm.Height / 2); - return this; - }, - - /** - * Set the dimensions of a XAML element to be the same of the canvas it is - * a member of. - * - * @param {Object} sName Name or ID of the element - * @param {Number} iWidth Current width of the canvas - * @param {Number} iHeight Current height of the canvas. Optional. - * @type {Object} - */ - stretchElement: function(sName, iWidth, iHeight) { - var elm = this.options["sender"].findName(sName); - elm.Width = iWidth; - if (iHeight != undefined) - elm.Height = iHeight; - return this; - }, - - $destroy: function() { - jpf.layout.removeRule(this.oVideo.oExt, this.oVideo.uniqueId + "_silverlight"); - this.stopPlayPoll(); - if (this.player) { - this.player = this.video = this.preview = null; - delete this.player; - delete this.video; - delete this.preview - } - this.htmlElement.innerHTML = ""; - this.oVideo = this.htmlElement = null; - delete this.oVideo; - delete this.htmlElement; - } -}; - - -/*FILEHEAD(/var/lib/jpf/src/elements/video/type_flv.js)SIZE(-1077090856)TIME(1238933680)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - -/** - * Element displaying a Flash video - * - * @classDescription This class creates a new Flash video player - * @return {TypeFlv} Returns a new Flash video player - * @type {TypeFlv} - * @constructor - * @addnode elements:video - * - * @author Mike de Boer - * @version %I%, %G% - * @since 1.0 - */ -jpf.video.TypeFlv = function(oVideo, node, options) { - this.oVideo = oVideo; - this.DEFAULT_SWF_PATH = (jpf.appsettings.resourcePath || jpf.basePath) + "resources/FAVideo.swf"; - //this.DEFAULT_WIDTH = "100%"; - //this.DEFAULT_HEIGHT = "100%"; - - this.id = jpf.flash.addPlayer(this); // Manager manages multiple players - this.inited = false; - this.resizeTimer = null; - - // Div name, flash name, and container name - this.divName = this.oVideo.uniqueId; - this.htmlElement = node; - this.name = "FAVideo_" + this.oVideo.uniqueId; - - // Video props - this.videoPath = options.src; - this.width = "100%"; //(options.width > 0) ? options.width : this.DEFAULT_WIDTH; - this.height = "100%"; //(options.height > 0) ? options.height : this.DEFAULT_HEIGHT; - - // Initialize player - this.player = null; - jpf.extend(this, jpf.video.TypeInterface); - - this.initProperties().setOptions(options).createPlayer(); -} - -jpf.video.TypeFlv.isSupported = function() { - return jpf.flash.isAvailable(); -}; - -jpf.video.TypeFlv.prototype = { - /** - * Play an FLV. Does a call to the flash player to load or load & play the - * video, depending on the 'autoPlay' flag (TRUE for play). - * - * @param {String} videoPath Path to the FLV. If the videoPath is null, and the FLV is playing, it will act as a play/pause toggle. - * @param {Number} totalTime Optional totalTime to override the FLV's built in totalTime - * @type {Object} - */ - load: function(videoPath, totalTime) { - videoPath = videoPath.splitSafe(",")[this.oVideo.$lastMimeType] || videoPath; - - if (totalTime != null) - this.setTotalTime(totalTime); - if (videoPath != null) - this.videoPath = videoPath; - if (this.videoPath == null && !this.firstLoad) - return this.oVideo.$errorHook({type:"error", error:"FAVideo::play - No videoPath has been set."}); - - if (videoPath == null && this.firstLoad && !this.autoLoad) // Allow play(null) to toggle playback - videoPath = this.videoPath; - - this.firstLoad = false; - if (this.autoPlay) - this.callMethod("playVideo", videoPath, totalTime); - else - this.callMethod("loadVideo", this.videoPath); - return this; - }, - - /** - * Play and/ or resume a video that has been loaded already - * - * @type {Object} - */ - play: function() { - return this.pause(false); - }, - - /** - * Toggle the pause state of the video. - * - * @param {Boolean} pauseState The pause state. Setting pause state to true will pause the video. - * @type {Object} - */ - pause: function(pauseState) { - if (typeof pauseState == "undefined") - pauseState = true; - this.callMethod("pause", pauseState); - return this; - }, - - /** - * Stop playback of the video. - * - * @type {Object} - */ - stop: function() { - this.callMethod("stop"); - return this; - }, - - /** - * Seek the video to a specific position. - * - * @param {Number} millis The number of milliseconds to seek the playhead to. - * @type {Object} - */ - seek: function(millis) { - this.callMethod("seek", millis / 1000); - return this; - }, - - /** - * Set the volume of the video to a specific range (0 - 100) - * - * @param {Number} iVolume - * @type {Object} - */ - setVolume: function(iVolume) { - this.callMethod("setVolume", iVolume); - return this; - }, - - /** - * Resize event handler, used by the layoutManager hook - * - * @type {void} - */ - onResize: function() { - clearTimeout(this.resizeTimer); - var _self = this; - this.resizeTimer = window.setTimeout(function() { - _self.setSize(); - }, 20); - }, - - /** - * Set the size of the video. - * - * @type {Object} - */ - setSize: function() { - this.callMethod("setSize", this.htmlElement.offsetWidth, - this.htmlElement.offsetHeight); - return this; - }, - - /** - * Retrive the position of the playhead, in seconds. - * - * @type {Number} - */ - getPlayheadTime: function() { - return this.playheadTime; - }, - - /** - * Specifies the position of the playhead, in seconds. - * - * @default null - * @type {Object} - */ - setPlayheadTime: function(value) { - return this.setProperty("playheadTime", value); - }, - - /** - * Retrieve the total playtime of the video, in seconds. - * - * @type {Number} - */ - getTotalTime: function() { - return this.totalTime; - }, - - /** - * Determines the total time of the video. The total time is automatically determined - * by the player, unless the user overrides it. - * - * @default null - * @type {Object} - */ - setTotalTime: function(value) { - return this.setProperty("totalTime", value); - }, - - /*setFullscreen: function(value) { - jpf.console.info('j:video::flash - going fullscreen = ' + value); - return this.callMethod('setFullscreen', value); - },*/ - - /** - * All public methods use this proxy to make sure that methods called before - * initialization are properly called after the player is ready. - * Supply three arguments maximum, because function.apply does not work on - * the flash object. - * - * @param {String} param1 - * @param {String} param2 - * @param {String} param3 - * @type {Object} - */ - callMethod: function(param1, param2, param3) { - if (this.inited && this.player && this.player.callMethod) - this.player.callMethod(param1, param2, param3); // function.apply does not work on the flash object - else - this.delayCalls.push(arguments); - }, - - /** - * Call methods that were made before the player was initialized. - * - * @type {Object} - */ - makeDelayCalls: function() { - for (var i = 0; i < this.delayCalls.length; i++) - this.callMethod.apply(this, this.delayCalls[i]); - return this; - }, - - /** - * Callback from flash; synchronizes the state of properties of the Flash - * movie with the properties of the javascript object - * - * @param {Object} props - * @type {void} - */ - update: function(props) { - for (var n in props) { - if (n.indexOf("Time") != -1 && typeof props[n] == "number") - props[n] = props[n] * 1000; - this[n] = props[n]; // Set the internal property - } - props.type = "change"; - this.oVideo.$changeHook(props); // This needs to have an array of changed props. - }, - - /** - * Callback from flash; whenever the Flash movie bubbles an event up to the - * javascript interface, it passes through to this function. - * Events dispatched by FAVideo instances: - * > init: The player is initialized - * > ready: The video is ready - * > progress: The video is downloading. Properties: bytesLoaded, bytesTotal - * > playHeadUpdate: The video playhead has moved. Properties: playheadTime, totalTime - * > stateChange: The state of the video has changed. Properties: state - * > change: The player has changed. - * > complete: Playback is complete. - * > metaData: The video has returned meta-data. Properties: infoObject - * > cuePoint: The video has passed a cuePoint. Properties: infoObject - * > error: An error has occurred. Properties: error - * - * @param {Object} eventName - * @param {Object} evtObj - * @type {void} - */ - event: function(eventName, evtObj) { - switch (eventName) { - case "progress": - this.bytesLoaded = evtObj.bytesLoaded; - this.totalBytes = evtObj.bytesTotal; - this.oVideo.$progressHook({ - type : "progress", - bytesLoaded: this.bytesLoaded, - totalBytes : this.totalBytes - }); - break; - case "playheadUpdate": - this.playheadTime = evtObj.playheadTime * 1000; - this.totalTime = evtObj.totalTime * 1000; - this.oVideo.$playheadUpdateHook({ - type : "playheadUpdate", - playheadTime: this.playheadTime, - totalTime : this.totalTime - }); - break; - case "stateChange": - this.state = evtObj.state; - this.oVideo.$stateChangeHook({type:"stateChange", state:this.state}); - break; - case "change": - this.oVideo.$changeHook({type:"change"}); - break; - case "complete": - this.oVideo.$completeHook({type:"complete"}); - break; - case "ready": - this.oVideo.$readyHook({type:"ready"}); - break; - case "metaData": - this.oVideo.$metadataHook({type:"metadata", infoObject:evtObj}); - break; - case "cuePoint": - this.oVideo.$cuePointHook({type:"cuePoint", infoObject:evtObj}); - break; - case "fullscreen": - jpf.console.log('fullscreen: ', evtObj.state); - this.oVideo.fullscreen = false; - case "init": - this.inited = true; - // There is a bug in IE innerHTML. Tell flash what size it is. - // This will probably not work with liquid layouts in IE. - this.invalidateProperty("clickToTogglePlay", "skinVisible", - "skinAutoHide", "autoPlay", "autoLoad", "volume", "bufferTime", - "videoScaleMode", "videoAlign", "playheadUpdateInterval", - "previewImagePath").validateNow().makeDelayCalls(); - - this.oVideo.$initHook({type:"init"}); - this.onResize(); - var node = this.oVideo.oInt; - setTimeout(function() { - jpf.layout.forceResize(node); - }, 1000); - break; - case "debug": - jpf.console.log('Flash debug: ' + evtObj.msg); - break; - } - }, - - /** - * Mark out the properties, so they are initialized, and documented. - * - * @type {Object} - */ - initProperties: function() { - this.delayCalls = []; - - // Properties set by flash player - this.videoWidth = this.videoHeight = this.totalTime = this.bytesLoaded = this.totalBytes = 0; - this.state = null; - - // Internal properties that match get/set methods - this.clickToTogglePlay = this.autoPlay = this.autoLoad = this.skinVisible = true; - this.volume = 50; - this.skinVisible = false; - this.skinAutoHide = false; - this.playheadTime = null; - this.bufferTime = 0.1; - this.videoScaleMode = "maintainAspectRatio"; //maintainAspectRatio || exactFit || noScale - this.videoAlign = "center"; - this.playheadUpdateInterval = 1000; - this.previewImagePath = this.themeColor = null - - this.firstLoad = true; - this.pluginError = false; - - this.properties = ["volume", "skinAutoHide", "showControls", "autoPlay", - "clickToTogglePlay", "autoLoad", "playHeadTime", "totalTime", - "bufferTime", "videoScaleMode", "videoAlign", "playheadUpdateInterval", - "previewImagePath"]; - - jpf.layout.setRules(this.oVideo.oExt, this.oVideo.uniqueId + "_favideo", - "(jpf.all[" + this.oVideo.uniqueId + "].player || {onResize:jpf.K}).onResize()"); - jpf.layout.activateRules(this.oVideo.oExt); - - return this; - }, - - /** - * Create the HTML to render the player. - * - * @type {Object} - */ - createPlayer: function() { - var content = jpf.flash.buildContent( - "src", this.DEFAULT_SWF_PATH, - "width", "100%", - "height", "100%", - "align", "middle", - "id", this.name, - "quality", "high", - "bgcolor", "#000000", - "allowFullScreen", "true", - "name", this.name, - "flashvars", "playerID=" + this.id + "&volume=" + this.volume - , - "allowScriptAccess","always", - "type", "application/x-shockwave-flash", - "pluginspage", "http://www.adobe.com/go/getflashplayer", - "menu", "true"); - - if (this.htmlElement == null) return this; - - this.pluginError = false; - this.htmlElement.innerHTML = content; - - this.player = this.getElement(this.name); - this.container = this.getElement(this.name + "_Container"); - -// var _self = this; -// setTimeout(function() { -// _self.onResize(); -// }); - - return this; - }, - - /** - * Mark a property as invalid, and create a timeout for redraw - * - * @type {Object} - */ - invalidateProperty: function() { - if (this.invalidProperties == null) - this.invalidProperties = {}; - - for (var i = 0; i < arguments.length; i++) - this.invalidProperties[arguments[i]] = true; - - if (this.validateInterval == null && this.inited) { - var _this = this; - this.validateInterval = setTimeout(function() { - _this.validateNow(); - }, 100); - } - - return this; - }, - - /** - * Updated player with properties marked as invalid. - * - * @type {Object} - */ - validateNow: function() { - this.validateInterval = null; - var props = {}; - for (var n in this.invalidProperties) - props[n] = this[n]; - this.invalidProperties = {}; - this.callMethod("update", props); - return this; - }, - - /** - * All public properties use this proxy to minimize player updates - * - * @param {String} property - * @param {String} value - * @type {Object} - */ - setProperty: function(property, value) { - this[property] = value; // Set the internal property - if (this.inited) - this.invalidateProperty(property); // Otherwise, it is already invalidated on init. - return this; - }, - - $destroy: function() { - jpf.layout.removeRule(this.oVideo.oExt, this.oVideo.uniqueId + "_favideo"); - if (this.player) { - try { - this.stop(); - } - catch(e) {} - this.player = this.container = null; - delete this.player; - delete this.container; - } - this.htmlElement.innerHTML = ""; - this.oVideo = this.htmlElement = null; - delete this.oVideo; - delete this.htmlElement; - } -}; - - -/*FILEHEAD(/var/lib/jpf/src/elements/video/type_wmp.js)SIZE(-1077090856)TIME(1238933680)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -jpf.video.TypeWmpCompat = (function() { - var hasWMP = false; - - /** - * Windows Media Player checking code adapted from - * eMedia Communications Strategies information and Microsoft documentation - * see http://www.learningapi.com/sm5/articlesm5.html - * and http://support.microsoft.com/default.aspx?scid=kb;en-us;279022 - * - * Note: Windows Media Player version 7+ ships with the old 6.4 - * control as well as the newest version. For this reason, - * is_WMP64 will remain true even if is_WMP7up - * is set to true. - * - * @type {Number} - */ - function WMP_getVersion() { - var is_WMP64 = false, - is_WMP7up = false; - - if (jpf.isWin && jpf.isIE) { //use ActiveX test - var oMP; - try { - oMP = new ActiveXObject("MediaPlayer.MediaPlayer.1"); - hasWMP = true; - is_WMP64 = true; - } - catch (objError) { - hasWMP = false; - is_WMP64 = false; - } - - if (hasWMP) { - try { - oMP = new ActiveXObject("WMPlayer.OCX"); - is_WMP7up = true; - } - catch (objError) { - is_WMP7up = false; - } - } - } - else { //use plugin test (this not tested yet) - for (var i = 0, j = navigator.plugins.length; i < j; i++) { - if (navigator.plugins[i].name.indexOf("Windows Media Player") != -1) { - hasWMP = true; - is_WMP64 = true; - is_WMP7up = true; //no way to know this with certainty, because M$ doesn't provide version info... - oMP = { versionInfo: "7.3" }; - } - } - } - - var WMPVer; - if (is_WMP7up) { - WMPVer = oMP.versionInfo; - oMP = null; - } - else - WMPVer = "6.4"; - - return parseFloat(WMPVer); - } - - /** - * Create the HTML for a <PARAM> tag inside the <OBJECT> tag of the player. - * - * @param {String} name - * @param {String} value - * @type {String} - */ - function WMP_generateParamTag(name, value) { - if (!name || !value) return ""; - return '<param name="' + name + '" value="' + value + '" />'; - } - - /** - * Create the HTML for the Windows Media Player <OBJECT> HTML tag. - * - * @param {String} id - * @param {String} url - * @param {Number} width - * @param {Number} height - * @param {Object} params - * @type {String} - */ - function WMP_generateOBJECTText(id, url, width, height, params) { - params.URL = url; - params.src = url; - params.SendPlayStateChangeEvents = "true"; - params.StretchToFit = "true"; - var out = ['<object id="', id, '" width="', width, '" height="', height, '" \ - classid="clsid:6BF52A52-394A-11d3-B153-00C04F79FAA6" \ - type="application/x-oleobject">']; - var emb = ['<embed id="', id, 'emb" width="', width, '" height="', height, '"']; - for (var param in params) { - if (!param || !params[param]) continue; - out.push('<param name="', param, '" value="', params[param], '" />'); - emb.push(' ', param, '="', params[param], '"'); - } - return out.join("") + emb.join("") + " /></object>"; - } - - var bIsAvailable = null; - /* - * Checks whether a valid version of Windows Media Player is available on - * the clients' system. The version number needs to be higher than 7 in order - * to be able to control the movie with JScript. - * - * @type {Boolean} - */ - function WMP_isAvailable() { - if (bIsAvailable === null) - bIsAvailable = WMP_getVersion() >= 7 && hasWMP; - return bIsAvailable; - } - - return { - isAvailable : WMP_isAvailable, - generateOBJECTText: WMP_generateOBJECTText - } -})(); - -/** - * Element displaying a Windows Media Player video - * - * @classDescription This class creates a new Windows Media Player video player - * @return {TypeWmp} Returns a new Windows Media Player video player - * @type {TypeWmp} - * @constructor - * @addnode elements:video - * - * @author Mike de Boer - * @version %I%, %G% - * @since 1.0 - */ -jpf.video.TypeWmp = function(oVideo, node, options) { - this.oVideo = oVideo; - this.name = "WMP_" + this.oVideo.uniqueId; - this.htmlElement = node; - - this.player = this.pollTimer = null; - this.volume = 50; //default WMP - this.videoPath = options.src; - jpf.extend(this, jpf.video.TypeInterface); - - this.setOptions(options); - var _self = this; - window.setTimeout(function() { - _self.oVideo.$initHook({state: 1}); - }, 1); -}; - -jpf.video.TypeWmp.isSupported = function(){ - return jpf.video.TypeWmpCompat.isAvailable(); -}; - -jpf.video.TypeWmp.prototype = { - /** - * Play a Quicktime movie. Does a call to the embedded QT object to load or - * load & play the video, depending on the 'autoPlay' flag (TRUE for play). - * - * @param {String} videoPath Path to the movie. - * @type {Object} - */ - load: function(videoPath) { - this.videoPath = videoPath.splitSafe(",")[this.oVideo.$lastMimeType] || videoPath; - return this.$draw(); - }, - - /** - * Play and/ or resume a video that has been loaded already - * - * @type {Object} - */ - play: function() { - if (this.player) - this.player.controls.play(); - - return this; - }, - - /** - * Toggle the pause state of the video. - * - * @type {Object} - */ - pause: function() { - if (this.player) - this.player.controls.pause(); - return this; - }, - - /** - * Stop playback of the video. - * - * @type {Object} - */ - stop: function() { - if (this.player) - this.player.controls.stop(); - return this; - }, - - /** - * Seek the video to a specific position. - * - * @param {Number} iTo The number of seconds to seek the playhead to. - * @type {Object} - */ - seek: function(iTo) { - if (this.player) { - this.player.controls.pause(); //@todo fix by ruben to enable seeking in wmp - this.player.controls.currentPosition = iTo / 1000; - if (!this.oVideo.paused) - this.player.controls.play(); //@todo fix by ruben to enable seeking in wmp - } - return this; - }, - - fullscreen : function(value){ - this.player.fullscreen = value ? true : false; - }, - - /** - * Set the volume of the video to a specific range (0 - 100) - * - * @param {Number} iVolume - * @type {Object} - */ - setVolume: function(iVolume) { - if (this.player) - this.player.settings.volume = iVolume; - return this; - }, - - /** - * Retrieve the total playtime of the video, in seconds. - * - * @type {Number} - */ - getTotalTime: function() { - if (!this.player) - return 0; - return Math.round(this.player.controls.currentItem.duration * 1000); - }, - - /** - * Draw the HTML for a Windows Media Player video control (<OBJECT> tag) - * onto the browser canvas into a container element (usually a <DIV>). - * When set, it captures the reference to the newly created object. - * - * @type {Object} - */ - $draw: function() { - if (this.player) { - this.stopPlayPoll(); - delete this.player; - this.player = null; - } - - var playerId = this.name + "_Player"; - - this.htmlElement.innerHTML = jpf.video.TypeWmpCompat.generateOBJECTText(playerId, - this.videoPath, "100%", "100%", { - "AutoStart": this.autoPlay.toString(), - "uiMode" : this.showControls ? "mini" : "none", - "PlayCount": 1 //@todo: implement looping - }); - - this.player = this.getElement(playerId);//.object; - var _self = this; - try { - this.player[window.addEventListener ? "addEventListener" : "attachEvent"]("PlayStateChange", function(iState) { - _self.handleEvent(iState); - }); - } catch (e) { - this.player.onplaystatechange = function(iState) { - _self.handleEvent(iState); - } - } - - return this; - }, - - /** - * Callback from flash; whenever the Window Media Player video bubbles an - * event up to the javascript interface, it passes through to this function. - * - * @param {Number} iState - * @type {Object} - */ - handleEvent: function(iState) { - switch (iState) { - case 1: //Stopped - Playback of the current media clip is stopped. - case 8: //MediaEnded - Media has completed playback and is at its end. - this.oVideo.$completeHook({type: "complete"}); - this.stopPlayPoll(); - break; - case 2: //Paused - Playback of the current media clip is paused. When media is paused, resuming playback begins from the same location. - this.oVideo.$stateChangeHook({type: "stateChange", state: "paused"}); - this.stopPlayPoll(); - break; - case 3: //Playing - The current media clip is playing. - this.oVideo.$stateChangeHook({type: "stateChange", state: "playing"}) - if (!this.oVideo.ready) - this.oVideo.setProperty("readyState", jpf.Media.HAVE_ENOUGH_DATA); - this.startPlayPoll(); - break; - case 10: //Ready - Ready to begin playing. - this.oVideo.$stateChangeHook({type: "ready"}); - break; - case 4: //ScanForward - The current media clip is fast forwarding. - case 5: //ScanReverse - The current media clip is fast rewinding. - case 6: //Buffering - The current media clip is getting additional data from the server. - case 7: //Waiting - Connection is established, however the server is not sending bits. Waiting for session to begin. - case 9: //Transitioning - Preparing new media. - case 11: //Reconnecting - Reconnecting to stream. - break; - } - return this; - }, - - /** - * Start the polling mechanism that checks for progress in playtime of the - * video. - * - * @type {Object} - */ - startPlayPoll: function() { - clearTimeout(this.pollTimer); - var _self = this; - this.pollTimer = setTimeout(function() { - if (!_self.player || !_self.player.controls) return; - _self.oVideo.$changeHook({ - type : "change", - playheadTime: Math.round(_self.player.controls.currentPosition * 1000) - }); - _self.startPlayPoll(); - }, 200); - return this; - }, - - /** - * Stop the polling mechanism, started by startPlayPoll(). - * - * @type {Object} - */ - stopPlayPoll: function() { - clearTimeout(this.pollTimer); - return this; - }, - - $destroy: function() { - this.stopPlayPoll(); - if (this.player) { - try { - this.player.controls.stop(); - } catch(e) {} - this.player = null; - delete this.player; - } - this.htmlElement.innerHTML = ""; - this.oVideo = this.htmlElement = null; - delete this.oVideo; - delete this.htmlElement; - } -}; - - -/*FILEHEAD(/var/lib/jpf/src/elements/video/type_qt.js)SIZE(-1077090856)TIME(1238933680)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -jpf.video.TypeQTCompat = (function(){ - var gTagAttrs = null; - var gQTBehaviorID = "qt_event_source"; - var gQTEventsEnabled = true; - - /** - * Create an <OBJECT> tag for Internet Explorer only, that will enable us to - * capture events from the Quicktime Player object. - * - * @type {String} - */ - function _QTGenerateBehavior(){ - return jpf.isIE - ? '<object id="' + gQTBehaviorID - + '" classid="clsid:CB927D12-4FF7-4a9e-A169-56E4B8A75598" \ - codebase="http://www.apple.com/qtactivex/qtplugin.cab#version=7,3,0,0"></object>' - : ''; - } - - /** - * Check if the behavior object from _QTGenerateBehavior() has been inserted - * into the DOM already. - * - * @param {String} callingFcnName - * @param {Object} args - * @type {Boolean} - */ - function _QTPageHasBehaviorObject(callingFcnName, args){ - var haveBehavior = false; - var objects = document.getElementsByTagName("object"); - - for (var ndx = 0, obj; obj = objects[ndx]; ndx++) { - if (obj.getAttribute("classid") == "clsid:CB927D12-4FF7-4a9e-A169-56E4B8A75598") { - if (obj.getAttribute("id") == gQTBehaviorID) - haveBehavior = false; - break; - } - } - - return haveBehavior; - } - - /** - * Check if we should insert an object tag for behaviors seperately, in order - * to be able to catch events. - * - * @type {Boolean} - */ - function _QTShouldInsertBehavior(){ - var shouldDo = false; - - if (gQTEventsEnabled && jpf.isIE && !_QTPageHasBehaviorObject()) - shouldDo = true; - - return shouldDo; - } - - /** - * Apple function soup. - * - * @param {String} prefix - * @param {String} slotName - * @param {String} tagName - */ - function _QTAddAttribute(prefix, slotName, tagName){ - var value; - - value = gTagAttrs[prefix + slotName]; - if (null == value) - value = gTagAttrs[slotName]; - - if (null != value) { - if (0 == slotName.indexOf(prefix) && (null == tagName)) - tagName = slotName.substring(prefix.length); - if (null == tagName) - tagName = slotName; - return ' ' + tagName + '="' + value + '"'; - } - else - return ""; - } - - /** - * Apple function soup. - * - * @param {String} slotName - * @param {String} tagName - */ - function _QTAddObjectAttr(slotName, tagName){ - // don't bother if it is only for the embed tag - if (0 == slotName.indexOf("emb#")) - return ""; - - if (0 == slotName.indexOf("obj#") && (null == tagName)) - tagName = slotName.substring(4); - - return _QTAddAttribute("obj#", slotName, tagName); - } - - /** - * Create and parse an attribute of the <EMBED> that is created. - * - * @param {String} slotName - * @param {String} tagName - * @type {String} - */ - function _QTAddEmbedAttr(slotName, tagName){ - // don't bother if it is only for the object tag - if (0 == slotName.indexOf("obj#")) - return ""; - - if (0 == slotName.indexOf("emb#") && (null == tagName)) - tagName = slotName.substring(4); - - return _QTAddAttribute("emb#", slotName, tagName); - } - - /** - * Create a <PARAM> tag to be placed inside an <OBJECT> tag - * - * @param {String} slotName - * @param {Boolean} generateXHTML - * @type {String} - */ - function _QTAddObjectParam(slotName, generateXHTML){ - var paramValue; - var paramStr = ""; - var endTagChar = (generateXHTML) ? " />" : ">"; - - if (-1 == slotName.indexOf("emb#")) { - // look for the OBJECT-only param first. if there is none, look for a generic one - paramValue = gTagAttrs["obj#" + slotName]; - if (null == paramValue) - paramValue = gTagAttrs[slotName]; - - if (0 == slotName.indexOf("obj#")) - slotName = slotName.substring(4); - - if (null != paramValue) - paramStr = '<param name="' + slotName + '" value="' + paramValue + '"' + endTagChar; - } - - return paramStr; - } - - /** - * Unset all globally declared attributes to its original values. - * - * @type {void} - */ - function _QTDeleteTagAttrs(){ - for (var ndx = 0; ndx < arguments.length; ndx++) { - var attrName = arguments[ndx]; - delete gTagAttrs[attrName]; - delete gTagAttrs["emb#" + attrName]; - delete gTagAttrs["obj#" + attrName]; - } - } - - /** - * Generate an embed and object tag, return as a string - * - * @param {String} callingFcnName - * @param {Boolean} generateXHTML - * @param {Array} args - * @type {String} - */ - function _QTGenerate(callingFcnName, generateXHTML, args){ - // allocate an array, fill in the required attributes with fixed place params and defaults - gTagAttrs = { - src : args[0], - width : args[1], - height : args[2], - classid : "clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B", - //Important note: It is recommended that you use this exact classid in order to ensure a seamless experience for all viewers - pluginspage: "http://www.apple.com/quicktime/download/" - }; - - // set up codebase attribute with specified or default version before parsing args so - // anything passed in will override - var activexVers = args[3] - if ((null == activexVers) || ("" == activexVers)) - activexVers = "7,3,0,0"; - gTagAttrs["codebase"] = "http://www.apple.com/qtactivex/qtplugin.cab#version=" + activexVers; - - var attrName, attrValue; - - // add all of the optional attributes to the array - for (var ndx = 4; ndx < args.length; ndx += 2) { - attrName = args[ndx].toLowerCase(); - attrValue = args[ndx + 1]; - - gTagAttrs[attrName] = attrValue; - - if (("postdomevents" == attrName) && (attrValue.toLowerCase() != "false")) { - gQTEventsEnabled = true; - if (jpf.isIE) - gTagAttrs["obj#style"] = "behavior:url(#" + gQTBehaviorID + ")"; - } - } - - // init both tags with the required and "special" attributes - var objTag = ["<object ", - _QTAddObjectAttr("classid"), - _QTAddObjectAttr("width"), - _QTAddObjectAttr("height"), - _QTAddObjectAttr("codebase"), - _QTAddObjectAttr("name"), - _QTAddObjectAttr("id"), - _QTAddObjectAttr("tabindex"), - _QTAddObjectAttr("hspace"), - _QTAddObjectAttr("vspace"), - _QTAddObjectAttr("border"), - _QTAddObjectAttr("align"), - _QTAddObjectAttr("class"), - _QTAddObjectAttr("title"), - _QTAddObjectAttr("accesskey"), - _QTAddObjectAttr("noexternaldata"), - _QTAddObjectAttr("obj#style"), - ">", - _QTAddObjectParam("src", generateXHTML)]; - var embedTag = ["<embed ", - _QTAddEmbedAttr("src"), - _QTAddEmbedAttr("width"), - _QTAddEmbedAttr("height"), - _QTAddEmbedAttr("pluginspage"), - _QTAddEmbedAttr("name"), - _QTAddEmbedAttr("id"), - _QTAddEmbedAttr("align"), - _QTAddEmbedAttr("tabindex")]; - - // delete the attributes/params we have already added - _QTDeleteTagAttrs("src", "width", "height", "pluginspage", "classid", - "codebase", "name", "tabindex", "hspace", "vspace", "border", - "align", "noexternaldata", "class", "title", "accesskey", "id", "style"); - - // and finally, add all of the remaining attributes to the embed and object - for (var attrName in gTagAttrs) { - attrValue = gTagAttrs[attrName]; - if (null != attrValue) { - embedTag.push(_QTAddEmbedAttr(attrName)); - objTag.push(_QTAddObjectParam(attrName, generateXHTML)); - } - } - - // end both tags, we're done - return objTag.join("") + embedTag.join("") + "></em" + "bed></ob" + "ject" + ">"; - } - - /** - * Generate an embed and object tag, return as a string and append a behavior - * script if necessary. - * - * @type {String} - */ - function QT_GenerateOBJECTText(){ - var txt = _QTGenerate("QT_GenerateOBJECTText_XHTML", true, arguments); - if (_QTShouldInsertBehavior()) - txt = _QTGenerateBehavior() + txt; - return txt; - } - - /** - * Checks if Apple QuickTime has been installed and is accessible on the - * client's browser. - * - * @type {Boolean} - */ - function QT_IsInstalled(){ - var U = false; - if (navigator.plugins && navigator.plugins.length) { - for(var M = 0; M < navigator.plugins.length; M++) { - var g = navigator.plugins[M]; - if (g.name.indexOf("QuickTime") > -1) - U = true; - } - } - else { - qtObj = false; - execScript("on error resume next: qtObj = IsObject(CreateObject(\"QuickTimeCheckObject.QuickTimeCheck.1\"))", "VBScript"); - U = qtObj; - } - return U; - } - - /** - * Retrieve the version number of the Apple Quicktime browser plugin. - * - * @type {String} - */ - function QT_GetVersion() { - var U = "0"; - if (navigator.plugins && navigator.plugins.length) { - for (var g = 0; g < navigator.plugins.length; g++) { - var S = navigator.plugins[g]; - var M = S.name.match(/quicktime\D*([\.\d]*)/i); - if (M && M[1]) - U = M[1]; - } - } - else { - ieQTVersion = null; - execScript("on error resume next: ieQTVersion = CreateObject(\"QuickTimeCheckObject.QuickTimeCheck.1\").QuickTimeVersion", "VBScript"); - if (ieQTVersion) { - var temp = ""; - U = (ieQTVersion).toString(16) / 1000000 + "";//(ieQTVersion>>24).toString(16); - temp += parseInt(U) + "."; - temp += ((parseFloat(U) - parseInt(U)) * 1000) / 100 + ""; - U = temp; - } - } - return U; - } - - /** - * Check if the currently installed version of Apple Quicktime is compatible - * with the version specified with major number as g and minor as j. - * - * @param {String} g - * @param {String} j - * @type {Boolean} - */ - function QT_IsCompatible(g, j){ - function M(w, R) { - var i = parseInt(w[0], 10); - if (isNaN(i)) - i = 0; - var V = parseInt(R[0], 10); - if (isNaN(V)) - V = 0; - if (i === V) { - if (w.length > 1) - return M(w.slice(1), R.slice(1)); - else - return true; - } - else - return (i < V); - } - var S = g.split(/\./); - var U = j ? j.split(/\./) : QT_GetVersion().split(/\./); - return M(S, U); - } - - var aIsAvailable = {}; - /* - * Checks whether a valid version of Apple Quicktime is available on the - * clients' system. Default version to check for is 7.2.1, because that was - * the first version that supported the scripting interface. - * - * @param {String} sVersion - * @type {Boolean} - */ - function QT_IsValidAvailable(sVersion) { - if (typeof sVersion == "undefined") - sVersion = "7.2.1"; - if (typeof aIsAvailable[sVersion] == "undefined") - aIsAvailable[sVersion] = QT_IsInstalled() && QT_IsCompatible(sVersion); - return aIsAvailable[sVersion]; - } - - return { - generateOBJECTText: QT_GenerateOBJECTText, - isAvailable : QT_IsValidAvailable - }; -})(); - -/** - * Element displaying a Apple Quicktime video (.mov) - * - * @classDescription This class creates a new Quicktime video player - * @return {TypeQT} Returns a new Quicktime video player - * @type {TypeQT} - * @constructor - * @addnode elements:video - * - * @author Mike de Boer - * @version %I%, %G% - * @since 1.0 - */ -jpf.video.TypeQT = function(oVideo, node, options) { - this.oVideo = oVideo; - this.name = "QT_" + this.oVideo.uniqueId; - this.htmlElement = node; - - // Properties set by QT player - this.videoWidth = this.videoHeight = this.totalTime = - this.bytesLoaded = this.totalBytes = 0; - this.state = null; - - // Internal properties that match get/set methods - this.autoPlay = this.autoLoad = this.showControls = true; - this.volume = 50; - this.mimeType = "video/quicktime"; - - this.firstLoad = true; - this.pluginError = false; - - this.pollTimer = null; - this.videoPath = options.src; - - this.player = null; - jpf.extend(this, jpf.video.TypeInterface); - - this.setOptions(options); - var _self = this; - window.setTimeout(function() { - _self.oVideo.$initHook({state: 1}); - }, 1); -} - -jpf.video.TypeQT.isSupported = function() { - // QuickTime 7.2.1 is the least we'd expect, no? - return jpf.video.TypeQTCompat.isAvailable(); -} - -jpf.video.TypeQT.prototype = { - /** - * Play a Quicktime movie. Does a call to the embedded QT object to load or - * load & play the video, depending on the 'autoPlay' flag (TRUE for play). - * - * @param {String} videoPath Path to the movie. - * @type {Object} - */ - load: function(videoPath) { - this.videoPath = videoPath.splitSafe(",")[this.oVideo.$lastMimeType] || videoPath; - return this.$draw().attachEvents(); - }, - - /** - * Play and/ or resume a video that has been loaded already - * - * @type {Object} - */ - play: function() { - if (this.player) { - try { - this.player.Play(); - if (jpf.isIE) - this.handleEvent({type: "qt_play"}); - } - catch(e) { - this.oVideo.$stateChangeHook({type: "stateChange", state: "connectionError"}); - } - } - return this; - }, - - /** - * Toggle the pause state of the video. - * - * @type {Object} - */ - pause: function() { - if (this.player) { - try { - this.player.Stop(); - if (jpf.isIE) - this.handleEvent({type: "qt_pause"}); - } - catch(e) { - this.oVideo.$stateChangeHook({type: "stateChange", state: "connectionError"}); - } - } - return this; - }, - - /** - * Stop playback of the video. - * - * @type {Object} - */ - stop: function() { - return this.pause(); - }, - - /** - * Seek the video to a specific position. - * - * @param {Number} iTo The number of seconds to seek the playhead to. - * @type {Object} - */ - seek: function(iTo) { - if (!this.player) return; - try { - this.player.SetTime(iTo); - } - catch(e) { - this.oVideo.$stateChangeHook({type: "stateChange", state: "connectionError"}); - } - return this; - }, - - /** - * Set the volume of the video to a specific range (0 - 100) - * - * @param {Number} iVolume - * @type {Object} - */ - setVolume: function(iVolume) { - if (this.player) { - try { - this.player.SetVolume(Math.round((iVolume / 100) * 256)); - } - catch(e) { - this.oVideo.$stateChangeHook({type: "stateChange", state: "connectionError"}); - } - } - return this; - }, - - /** - * Retrieve the total playtime of the video, in seconds. - * - * @type {Number} - */ - getTotalTime: function() { - if (!this.player) return 0; - return this.player.GetDuration(); - }, - - /** - * Draw the HTML for an Apple Quicktime video control (<OBJECT> tag) - * onto the browser canvas into a container element (usually a <DIV>). - * When set, it captures the reference to the newly created object. - * - * @type {Object} - */ - $draw: function() { - if (this.player) { - this.stopPlayPoll(); - delete this.player; - this.player = null; - } - - this.htmlElement.innerHTML = jpf.video.TypeQTCompat.generateOBJECTText( - this.videoPath, "100%", "100%", "", - "autoplay", jpf.isIE ? "false" : this.autoPlay.toString(), //Not unloading of plugin, bad bad bad hack by Ruben - "controller", this.showControls.toString(), - "kioskmode", "true", - "showlogo", "true", - "bgcolor", "black", - "scale", "aspect", - "align", "middle", - "EnableJavaScript", "True", - "postdomevents", "True", - "target", "myself", - "cache", "false", - "qtsrcdontusebrowser", "true", - "type", this.mimeType.splitSafe(",")[this.oVideo.$lastMimeType] || this.mimeType, - "obj#id", this.name, - "emb#NAME", this.name, - "emb#id", this.name + "emb"); - - this.player = document[this.name]; - - return this; - }, - - events: ["qt_begin", "qt_abort", "qt_canplay", "qt_canplaythrough", - "qt_durationchange", "qt_ended", "qt_error", "qt_load", - "qt_loadedfirstframe", "qt_loadedmetadata", "qt_pause", "qt_play", - "qt_progress", "qt_stalled", "qt_timechanged", "qt_volumechange", - "qt_waiting"], - - /** - * Subscribe to events that will be fired by the Quicktime player during playback - * of the mov file. - * - * @type {Object} - */ - attachEvents: function() { - var nodeEvents = document.getElementById(this.name); - if (!nodeEvents) //try the embed otherwise ;) - nodeEvents = document.getElementById(this.name + "emb"); - var _self = this; - function exec(e) { - if (!e) e = window.event; - _self.handleEvent(e); - } - - var hook = nodeEvents.addEventListener ? "addEventListener" : "attachEvent"; - var pfx = nodeEvents.addEventListener ? "" : "on"; - this.events.forEach(function(evt) { - nodeEvents[hook](pfx + evt, exec, false); - }); - - if (jpf.isIE && this.autoPlay) - this.handleEvent({type: "qt_play"}); - - return this; - }, - - /** - * Callback from Quicktime plugin; whenever the player bubbles an event up - * to the javascript interface, it passes through to this function. - * - * @param {Object} e - * @type {Object} - */ - handleEvent: function(e) { - switch (e.type) { - case "qt_play": - this.oVideo.$stateChangeHook({type: "stateChange", state: "playing"}); - this.startPlayPoll(); - break; - case "qt_pause": - this.oVideo.$stateChangeHook({type: "stateChange", state: "paused"}); - this.stopPlayPoll(); - break; - case "qt_volumechange": - // volume has to be normalized to 100 (Apple chose a range from 0-256) - this.oVideo.$changeHook({ - type : "change", - volume: Math.round((this.player.GetVolume() / 256) * 100) - }); - break; - case "qt_timechanged": - this.oVideo.$changeHook({ - type : "change", - playheadTime: this.player.GetTime() - }); - break; - case "qt_stalled": - this.oVideo.$completeHook({type: "complete"}); - this.stopPlayPoll(); - break; - case "qt_canplay": - this.oVideo.$readyHook({type: "ready"}); - break; - // unique QT stuff: - //case "qt_loadedmetadata": - // this.oVideo.$metadataHook(); - // break; - case "qt_load": - case "qt_canplaythrough": - this.oVideo.setProperty("readyState", jpf.Media.HAVE_ENOUGH_DATA); - if (this.autoPlay && jpf.isIE) //Not unloading of plugin, bad bad bad hack by Ruben - this.player.Play(); - break; - } - return this; - }, - - /** - * Start the polling mechanism that checks for progress in playtime of the - * video. - * - * @type {Object} - */ - startPlayPoll: function() { - clearTimeout(this.pollTimer); - var _self = this; - this.pollTimer = setTimeout(function() { - if (!_self.player) return; - try { - _self.handleEvent({type: "qt_timechanged"}); - var iLoaded = _self.player.GetMaxBytesLoaded(); - var iTotal = _self.player.GetMovieSize(); - _self.oVideo.$progressHook({ - bytesLoaded: iLoaded, - totalBytes : iTotal - }); - if (!_self.oVideo.ready && Math.abs(iLoaded - iTotal) <= 20) - _self.handleEvent({type: "qt_load"}); - } - catch (e) {} - _self.startPlayPoll(); - }, 100); - return this; - }, - - /** - * Stop the polling mechanism, started by startPlayPoll(). - * - * @type {Object} - */ - stopPlayPoll: function() { - clearTimeout(this.pollTimer); - return this; - }, - - $destroy: function() { - this.stopPlayPoll(); - if (this.player) { - try { - this.player.Stop(); - } - catch (e) {} - this.player = null; - delete this.player; - } - this.oVideo = this.htmlElement = null; - delete this.oVideo; - delete this.htmlElement; - } -}; - - -/*FILEHEAD(/var/lib/jpf/src/elements/video/type_vlc.js)SIZE(-1077090856)TIME(1238933680)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - - -/*FILEHEAD(/var/lib/jpf/src/elements/textbox/autocomplete.js)SIZE(-1077090856)TIME(1225628612)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -/** - * Adds autocomplete to the textbox element - * - * @define textbox - * @allowchild autocomplete - * @define autocomplete
- * @attribute {String} [nodeset] how to retrieve the nodeset. This is a combination of model name and an xpath statement seperated by a colon (i.e. mdlUsers:users) - * @attribute {String} [method] the name of a function that returns a nodeset. - * @attribute {String} value an xpath which selects the value of each node in the nodeset. - * @attribute {String} [count] the number of visible items in the list at the same time. - * @attribute {String} [sort] an xpath on which the list is ordered. - *
- * @constructor - * @private - */ - -jpf.textbox.autocomplete = function(){ - /* - missing features: - - web service based autocomplete - */ - var autocomplete = {}; - - this.initAutocomplete = function(ac){ - ac.parentNode.removeChild(ac); - autocomplete.nodeset = ac.getAttribute("nodeset").split(":"); - autocomplete.method = ac.getAttribute("method"); - autocomplete.value = ac.getAttribute("value"); - autocomplete.count = parseInt(ac.getAttribute("count")) || 5; - autocomplete.sort = ac.getAttribute("sort"); - autocomplete.lastStart = -1; - - this.oContainer = jpf.xmldb.htmlImport(this.$getLayoutNode("container"), - this.oExt.parentNode, this.oExt.nextSibling); - }; - - this.fillAutocomplete = function(keyCode){ - if (keyCode) { - switch(keyCode){ - case 9: - case 27: - case 13: - return this.oContainer.style.display = "none"; - case 40: //DOWN - if(autocomplete.suggestData - && autocomplete.lastStart < autocomplete.suggestData.length){ - this.clear(); - var value = autocomplete.suggestData[autocomplete.lastStart++]; - this.oInt.value = value; //hack! - this.change(value); - //this.oInt.select(); this.oInt.focus(); - this.oContainer.style.display = "none"; - return; - } - break; - case 38: //UP - if (autocomplete.lastStart > 0) { - if(autocomplete.lastStart >= autocomplete.suggestData.length) - autocomplete.lastStart = autocomplete.suggestData.length - 1; - - this.clear(); - var value = autocomplete.suggestData[autocomplete.lastStart--]; - this.oInt.value = value; //hack! - this.change(value); - //this.oInt.select(); this.oInt.focus(); - this.oContainer.style.display = "none"; - return; - } - break; - } - - if (keyCode > 10 && keyCode < 20) return; - } - - if (autocomplete.method) { - var start = 0, suggestData = self[autocomplete.method](); - autocomplete.count = suggestData.length; - } - else { - if (this.oInt.value.length == 0){ - this.oContainer.style.display = "none"; - return; - } - if (!autocomplete.suggestData) { - //Get data from model - var nodes = self[autocomplete.nodeset[0]].data.selectNodes(autocomplete.nodeset[1]); - for(var value, suggestData = [], i = 0; i < nodes.length; i++) { - value = jpf.getXmlValue(nodes[i], autocomplete.value); - if (value) - suggestData.push(value.toLowerCase()); - } - if (autocomplete.sort) - suggestData.sort(); - autocomplete.suggestData = suggestData; - } - else { - suggestData = autocomplete.suggestData; - } - - //Find Startpoint in lookup list - var value = this.oInt.value.toUpperCase(); - for(var start = suggestData.length - autocomplete.count, i = 0; i < suggestData.length; i++) { - if (value <= suggestData[i].toUpperCase()) { - start = i; - break; - } - } - autocomplete.lastStart = start; - } - - //Create html items - this.oContainer.innerHTML = ""; - - for (var arr = [], j = start; j < Math.min(start + autocomplete.count, suggestData.length); j++) { - this.$getNewContext("item") - var oItem = this.$getLayoutNode("item"); - jpf.xmldb.setNodeValue(this.$getLayoutNode("item", "caption"), suggestData[j]); - - oItem.setAttribute("onmouseover", 'this.className = "hover"'); - oItem.setAttribute("onmouseout", 'this.className = ""'); - oItem.setAttribute("onmousedown", 'event.cancelBubble = true'); - oItem.setAttribute("onclick", - "var o = jpf.lookup(" + this.uniqueId + ");\ - o.oInt.value = this.innerHTML;\ - o.change(this.innerHTML);\ - o.oInt.select();\ - o.oInt.focus();\ - o.oContainer.style.display = 'none';"); - - arr.push(this.$getLayoutNode("item")); - } - jpf.xmldb.htmlImport(arr, this.oContainer); - - this.oContainer.style.display = "block"; - }; - - this.setAutocomplete = function(model, traverse, value){ - autocomplete.lastStart = -1; - autocomplete.suggestData = null; - - autocomplete.nodeset = [model, traverse]; - autocomplete.value = value; - this.oContainer.style.display = "none"; - }; -}; - - - -/*FILEHEAD(/var/lib/jpf/src/elements/textbox/masking.js)SIZE(-1077090856)TIME(1239027646)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -/** - * @constructor - * @private - */ -jpf.textbox.masking = function(){ - /* - Special Masking Values: - - PASSWORD - - <j:Textbox name="custref" mask="CS20999999" maskmsg="" validation="/CS200[3-5]\d{4}/" invalidmsg="" bind="custref/text()" /> - */ - - var _FALSE_ = 9128748732; - - var _REF = { - "0" : "\\d", - "1" : "[12]", - "9" : "[\\d ]", - "#" : "[\\d +-]", - "L" : "[A-Za-z]", - "?" : "[A-Za-z ]", - "A" : "[A-Za-z0-9]", - "a" : "[A-Za-z0-9 ]", - "X" : "[0-9A-Fa-f]", - "x" : "[0-9A-Fa-f ]", - "&" : "[^\s]", - "C" : "." - }; - - var lastPos = -1; - var masking = false; - var oExt = this.oExt - var initial, pos = [], myvalue, format, fcase, replaceChar; - - this.setPosition = function(setpos){ - setPosition(setpos || lastPos || 0); - }; - - this.$clear = function(){ - this.value = ""; - if (this.mask) - return this.setValue(""); - }; - - this.$propHandlers["value"] = function(value){ - var data = ""; - if (this.includeNonTypedChars) { - for (var i = 0; i < initial.length; i++) { - if (initial.substr(i, 1) != value.substr(i, 1)) - data += value.substr(i, 1);//initial.substr(i,1) == replaceChar - } - } - - this.$insertData(data || value); - }; - - /* *********************** - Keyboard Support - ************************/ - - this.addEventListener("keydown", function(e){ - var key = e.which || e.keyCode; - var ctrlKey = e.ctrlKey; - var shiftKey = e.shiftKey; - - switch (key) { - case 39: - //RIGHT - setPosition(lastPos+1); - break; - case 37: - //LEFT - setPosition(lastPos-1); - break; - case 35: - case 34: - setPosition(myvalue.length); - break; - case 33: - case 36: - setPosition(0); - break; - case 8: - //BACKSPACE - deletePosition(lastPos-1); - setPosition(lastPos-1); - break; - case 46: - //DEL - deletePosition(lastPos); - setPosition(lastPos); - break; - default: - if (key == 67 && ctrlKey) - window.clipboardData.setData("Text", this.getValue()); - /* - else if ((key == 86 && ctrlKey) || (shiftKey && key == 45)) { - this.setValue(window.clipboardData.getData("Text")); - setPosition(lastPos); - } - */ - else - return; - break; - } - - return false; - }, true); - - /* *********************** - Init - ************************/ - - this.$initMasking = function(){ - ///this.keyHandler = this._keyHandler; - this.$keyHandler = null; //temp solution - masking = true; - - this.oInt.onkeypress = function(e){ - e = e || window.event; - var chr = String.fromCharCode(e.which || e.keyCode); - chr = (e.shiftKey ? chr.toUpperCase() : chr.toLowerCase()); - - if (setCharacter(chr)) - setPosition(lastPos + 1); - - return false; - }; - - this.oInt.onmouseup = function(){ - var pos = Math.min(calcPosFromCursor(), myvalue.length); - setPosition(pos); - return false; - }; - - this.oInt.onpaste = function(e){ - e = e || window.event; - e.returnValue = false; - this.host.setValue(window.clipboardData.getData("Text") || ""); - //setPosition(lastPos); - setTimeout(function(){ - setPosition(lastPos); - }, 1); //HACK good enough for now... - }; - - this.getValue = function(){ - if (this.includeNonTypedChars) - return initial == this.oInt.value - ? "" - : this.oInt.value.replace(new RegExp(replaceChar, "g"), ""); - else - return myvalue.join(""); - }; - - this.setValue = function(value){ - if (this.includeNonTypedChars) { - for (var data = "", i = 0; i < initial.length; i++) { - if (initial.substr(i,1) != value.substr(i,1)) - data += value.substr(i, 1);//initial.substr(i,1) == replaceChar - } - } - this.$insertData(data); - }; - }; - - this.setMask = function(m){ - if (!masking) - this.$initMasking(); - - m = m.split(";"); - replaceChar = m.pop(); - this.includeNonTypedChars = parseInt(m.pop()) !== 0; - var mask = m.join(""); //why a join here??? - var validation = "", - visual = "", - mode_case = "-", - strmode = false, - startRight = false, - chr; - pos = [], format = "", fcase = ""; - - for (var looppos = -1, i = 0; i < mask.length; i++) { - chr = mask.substr(i,1); - - if (!chr.match(/[\!\'\"\>\<\\]/)) - looppos++; - else { - if (chr == "!") - startRight = true; - else if (chr == "<" || chr == ">") - mode_case = chr; - else if (chr == "'" || chr == "\"") - strmode = !strmode; - continue; - } - - if (!strmode && _REF[chr]) { - pos.push(looppos); - visual += replaceChar; - format += chr; - fcase += mode_case; - validation += _REF[chr]; - } - else - visual += chr; - } - - this.oInt.value = visual; - initial = visual; - //pos = pos; - myvalue = []; - //format = format; - //fcase = fcase; - replaceChar = replaceChar; - - //setPosition(0);//startRight ? pos.length-1 : 0); - - //validation.. - //forgot \ escaping... - }; - - function checkChar(chr, p){ - var f = format.substr(p, 1); - var c = fcase.substr(p, 1); - - if (chr.match(new RegExp(_REF[f])) == null) - return _FALSE_; - if (c == ">") - return chr.toUpperCase(); - if (c == "<") - return chr.toLowerCase(); - return chr; - } - - function setPosition(p){ - if (p < 0) - p = 0; - - - if (jpf.hasMsRangeObject) { - var range = oExt.createTextRange(); - range.expand("textedit"); - range.select(); - - if (pos[p] == null) { - range.collapse(false); - range.select(); - lastPos = pos.length; - return false; - } - - range.collapse(); - range.moveStart("character", pos[p]); - range.moveEnd("character", 1); - range.select(); - } - else { - if (typeof pos[p] == "undefined") - p = pos.length - 1; - oExt.selectionStart = pos[p]; - oExt.selectionEnd = pos[p] + 1; - } - - lastPos = p; - } - - function setCharacter(chr){ - if (pos[lastPos] == null) return false; - - chr = checkChar(chr, lastPos); - if (chr == _FALSE_) return false; - - if (jpf.hasMsRangeObject) { - var range = oExt.createTextRange(); - range.expand("textedit"); - range.select(); - - range.moveStart("character", pos[lastPos]); - range.moveEnd("character", 1); - range.text = chr; - if (jpf.window.focussed == this) - range.select(); - } - else { - var val = oExt.value, - start = oExt.selectionStart, - end = oExt.selectionEnd; - oExt.value = val.substr(0, start) + chr + val.substr(end); - oExt.selectionStart = start; - oExt.selectionEnd = end; - } - - myvalue[lastPos] = chr; - - return true; - } - - function deletePosition(p){ - if(pos[p] == null) return false; - - if (jpf.hasMsRangeObject) { - var range = oExt.createTextRange(); - range.expand("textedit"); - range.select(); - - range.moveStart("character", pos[p]); - range.moveEnd("character", 1); - range.text = replaceChar; - range.select(); - } - else { - var val = oExt.value, - start = pos[p], - end = pos[p] + 1; - oExt.value = val.substr(0, start) + replaceChar + val.substr(end); - oExt.selectionStart = start; - oExt.selectionEnd = end; - } - - //ipv lastPos - myvalue[p] = " "; - } - - this.$insertData = function(str){ - if (oExt.selectionStart == oExt.selectionEnd) { - setPosition(0); // is this always correct? practice will show... - } - - if (str == this.getValue()) return; - str = this.dispatchEvent("insert", { data : str }) || str; - - var i, j; - if (!str) { - if (!this.getValue()) return; //maybe not so good fix... might still flicker when content is cleared - for (i = this.getValue().length - 1; i >= 0; i--) - deletePosition(i); - setPosition(0); - return; - } - - for (i = 0, j = str.length; i < j; i++) { - lastPos = i; - setCharacter(str.substr(i, 1)); - if (!jpf.hasMsRangeObject) - setPosition(i + 1); - } - if (str.length) - lastPos++; - }; - - function calcPosFromCursor(){ - var range, lt = 0; - - if (!jpf.hasMsRangeObject) { - lt = oExt.selectionStart; - } - else { - range = document.selection.createRange(); - var r2 = range.duplicate(); - r2.expand("textedit"); - r2.setEndPoint("EndToStart", range); - lt = r2.text.length; - } - - for (var i = 0; i < pos.length; i++) { - if (pos[i] > lt) - return (i == 0) ? 0 : i - 1; - } - - return 0; // always return -a- value... - } -}; - - - -/*FILEHEAD(/var/lib/jpf/src/elements/audio/type_flash.js)SIZE(-1077090856)TIME(1238933680)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - -/** - * Element displaying a Flash audio - * - * @classDescription This class creates a new Flash audio player - * @return {TypeFlash} Returns a new Flash audio player - * @type {TypeFlash} - * @constructor - * @addnode elements:audio - * - * @author Mike de Boer - * @version %I%, %G% - * @since 1.0 - */ - -jpf.audio.TypeFlash = function(oAudio, oNode, options) { - this.oAudio = oAudio; - this.isNine = jpf.flash.isAvailable('9.0.0'); - - this.DEFAULT_SWF_PATH = (jpf.appsettings.resourcePath || jpf.basePath) + "resources/soundmanager2" - + (this.isNine ? "_flash9" : "") + ".swf"; - this.NULL_MP3_PATH = (jpf.appsettings.resourcePath || jpf.basePath) + "resources/null.mp3"; - - this.id = jpf.flash.addPlayer(this); // Manager manages multiple players - this.inited = false; - - // Div name, flash name, and container name - this.divName = oAudio.uniqueId; - this.htmlElement = oNode; - this.name = "soundmgr_" + oAudio.uniqueId; - - // Audio props - this.audioPath = options.src; - this.paused = false; - - // Initialize player - this.player = null; - jpf.extend(this, jpf.audio.TypeInterface); - - this.initProperties().setOptions(options).createPlayer(); -} - -jpf.audio.TypeFlash.isSupported = function() { - return jpf.flash.isAvailable(); -}; - -jpf.audio.TypeFlash.prototype = { - /** - * Load an audio file. - * - * @param {String} audioPath Path to the mp3 file. If the audioPath is null, and the mp3 is playing, it will act as a play/pause toggle. - * @param {Number} totalTime Optional totalTime to override the mp3's built in totalTime - */ - load: function(audioPath, totalTime) { - if (totalTime != null) - this.setTotalTime(totalTime); - if (audioPath != null) - this.audioPath = audioPath; - if (this.audioPath == null && !this.firstLoad) - return this.oAudio.$errorHook({type:"error", error:"SoundManager::play - No audioPath has been set."}); - - if (audioPath == null && this.firstLoad && !this.autoLoad) // Allow play(null) to toggle playback - audioPath = this.audioPath; - this.firstLoad = false; - this.callMethod('unloadSound', this.NULL_MP3_PATH); - if (this.isNine) - this.callMethod("createSound", this.audioPath, 0, true, true, true, false, false); - else - this.callMethod("createSound", 0); - this.callMethod("setVolume", this.volume) - .callMethod("loadSound", this.audioPath, true, this.autoPlay); - return this; - }, - - /** - * Play and/ or resume a audio that has been loaded already - * - * @type {Object} - */ - play: function() { - if (!this.paused) - return this.callMethod("startSound", 1, 0); - return this.pause(); //toggle pause - }, - - /** - * Toggle the pause state of the audio. - * - * @param {Boolean} pauseState The pause state. Setting pause state to true will pause the audio. - * @type {Object} - */ - pause: function() { - this.paused = !this.paused; - return this.callMethod("pauseSound"); - }, - - /** - * Stop playback of the audio. - * - * @type {Object} - */ - stop: function() { - return this.callMethod("stopSound", true); - }, - - /** - * Seek the audio to a specific position. - * - * @param {Number} seconds The number of seconds to seek the playhead to. - * @type {Object} - */ - seek: function(seconds) { - return this.callMethod("setPosition", seconds, this.paused); - }, - - /** - * Not supported. - * - * @type {Object} - */ - setVolume: function(iVol) { - return this.callMethod("setVolume", iVol); - }, - - /** - * Retrive the position of the playhead, in seconds. - * - * @type {Number} - */ - getPlayheadTime: function() { - return this.playheadTime; - }, - - /** - * Specifies the position of the playhead, in seconds. - * - * @default null - * @type {Object} - */ - setPlayheadTime: function(value) { - return this.setProperty("playheadTime", value); - }, - - /** - * Retrieve the total playtime of the audio, in seconds. - * - * @type {Number} - */ - getTotalTime: function() { - return this.totalTime; - }, - - /** - * Determines the total time of the audio. The total time is automatically determined - * by the player, unless the user overrides it. - * - * @default null - * @type {Object} - */ - setTotalTime: function(value) { - return this.setProperty("totalTime", value); - }, - - /** - * All public methods use this proxy to make sure that methods called before - * initialization are properly called after the player is ready. - * Supply three arguments maximum, because function.apply does not work on - * the flash object. - * - * @param {String} param1 - * @param {String} param2 - * @param {String} param3 - * @param {String} param4 - * @param {String} param5 - * @param {String} param6 - * @type {Object} - */ - callMethod: function() { - if (this.inited && this.player && this.player.callMethod) { - var args = arguments, l = args.length; - switch (l) { - case 1: - this.player.callMethod(args[0]); - break; - case 2: - this.player.callMethod(args[0], args[1]); - break; - case 3: - this.player.callMethod(args[0], args[1], args[2]); - break; - case 4: - this.player.callMethod(args[0], args[1], args[2], args[3]); - break; - case 5: - this.player.callMethod(args[0], args[1], args[2], args[3], args[4]); // function.apply does not work on the flash object - break; - case 6: - this.player.callMethod(args[0], args[1], args[2], args[3], args[4], args[5]); - break; - case 7: - this.player.callMethod(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); - break; - case 8: - this.player.callMethod(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]); - break; - } - } - else - this.delayCalls.push(arguments); - return this; - }, - - /** - * Call methods that were made before the player was initialized. - * - * @type {Object} - */ - makeDelayCalls: function() { - for (var i = 0; i < this.delayCalls.length; i++) - this.callMethod.apply(this, this.delayCalls[i]); - return this; - }, - - /** - * Callback from flash; whenever the Flash movie bubbles an event up to the - * javascript interface, it passes through to this function. - * Events dispatched by SoundManager instances: - * > init: The player is initialized - * > ready: The audio is ready - * > progress: The audio is downloading. Properties: bytesLoaded, totalBytes - * > playHeadUpdate: The audio playhead has moved. Properties: playheadTime, totalTime - * > stateChange: The state of the audio has changed. Properties: state - * > change: The player has changed. - * > complete: Playback is complete. - * > metaData: The audio has returned meta-data. Properties: infoObject - * > cuePoint: The audio has passed a cuePoint. Properties: infoObject - * > error: An error has occurred. Properties: error - * - * @param {Object} eventName - * @param {Object} evtObj - * @type {void} - */ - event: function(eventName, evtObj) { - switch (eventName) { - case "progress": - this.bytesLoaded = evtObj.bytesLoaded; - this.totalBytes = evtObj.totalBytes; - this.oAudio.$progressHook({ - type : "progress", - bytesLoaded: this.bytesLoaded, - totalBytes : this.totalBytes - }); - break; - case "playheadUpdate": - this.playheadTime = evtObj.playheadTime; - this.totalTime = evtObj.totalTime; - this.oAudio.$changeHook({ - type : "change", - playheadTime: this.playheadTime, - totalTime : this.totalTime - }); - if (evtObj.waveData || evtObj.peakData || evtObj.eqData) - this.oAudio.$metadataHook({ - type : "metadata", - waveData: evtObj.waveData, - peakData: evtObj.peakData, - eqData : evtObj.eqData - }); - break; - case "stateChange": - this.state = evtObj.state; - this.oAudio.$stateChangeHook({type:"stateChange", state:this.state}); - break; - case "change": - this.oAudio.$changeHook({type:"change"}); - break; - case "complete": - this.oAudio.$completeHook({type:"complete"}); - break; - case "ready": - this.callMethod("setPan", 0); - if (this.paused && this.autoPlay) - this.paused = false; - this.oAudio.$readyHook({type:"ready"}); - break; - case "metaData": - this.oAudio.$metadataHook({type:"metaData", infoObject:evtObj}); - break; - case "cuePoint": - this.oAudio.$cuePointHook({type:"cuePoint", infoObject:evtObj}); - break; - case "init": - this.inited = true; - this.invalidateProperty("autoPlay", "autoLoad", "volume", "bufferTime", - "playheadUpdateInterval").validateNow().makeDelayCalls(); - this.oAudio.$initHook(jpf.extend(evtObj, jpf.flash.getSandbox(evtObj.sandboxType))); - break; - case "id3": - this.oAudio.$metadataHook({ - type: 'metadata', - id3Data: evtObj - }); - break; - case "debug": - jpf.console.log(">> SWF DBUG: " + evtObj.msg); - break; - } - }, - - /** - * Mark out the properties, so they are initialized, and documented. - * - * @type {Object} - */ - initProperties: function() { - this.delayCalls = []; - - // Properties set by flash player - this.totalTime = this.bytesLoaded = this.totalBytes = 0; - this.state = null; - - // Internal properties that match get/set methods - this.autoPlay = this.autoLoad = true; - this.volume = 50; - this.playheadTime = null; - this.bufferTime = 0.1; - this.playheadUpdateInterval = 1000; - - this.firstLoad = true; - this.pluginError = false; - - this.properties = ["volume", "autoPlay", "autoLoad", "playHeadTime", - "totalTime", "bufferTime", "playheadUpdateInterval"]; - - return this; - }, - - /** - * Create the HTML to render the player. - * - * @type {Object} - */ - createPlayer: function() { - var div = this.htmlElement; - if (div == null) return this; - - this.pluginError = false; - - // place the HTML node outside of the viewport - div.style.position = "absolute"; - div.style.width = "1px"; - div.style.height = "1px"; - div.style.left = "-2000px"; - div.innerHTML = jpf.flash.buildContent( - "src", this.DEFAULT_SWF_PATH, - "width", "1", - "height", "1", - "align", "middle", - "id", this.name, - "quality", "high", - "bgcolor", "#000000", - "allowFullScreen", "true", - "name", this.name, - "flashvars", "playerID=" + this.id, - "allowScriptAccess","always", - "type", "application/x-shockwave-flash", - "pluginspage", "http://www.adobe.com/go/getflashplayer", - "menu", "true"); - this.player = this.getElement(this.name); - - return this; - }, - - /** - * Mark a property as invalid, and create a timeout for redraw - * - * @type {Object} - */ - invalidateProperty: function() { - if (this.invalidProperties == null) - this.invalidProperties = {}; - - for (var i = 0; i < arguments.length; i++) - this.invalidProperties[arguments[i]] = true; - - if (this.validateInterval == null && this.inited) { - var _this = this; - this.validateInterval = setTimeout(function() { - _this.validateNow(); - }, 100); - } - - return this; - }, - - /** - * Updated player with properties marked as invalid. - * - * @type {Object} - */ - validateNow: function() { - this.validateInterval = null; - var props = {}; - for (var n in this.invalidProperties) - props[n] = this[n]; - this.invalidProperties = {}; - this.player.callMethod("setPolling", true); - return this; - }, - - /** - * All public properties use this proxy to minimize player updates - * - * @param {String} property - * @param {String} value - * @type {Object} - */ - setProperty: function(property, value) { - this[property] = value; // Set the internal property - if (this.inited) - this.invalidateProperty(property); // Otherwise, it is already invalidated on init. - return this; - }, - - $destroy: function() { - this.callMethod('destroySound'); - if (this.player) { - delete this.player; - this.player = null; - } - } -}; - - -/*FILEHEAD(/var/lib/jpf/src/elements/editor/plugins.js)SIZE(-1077090856)TIME(1238944817)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -/** - * @class Plugins - * @constructor - * @extends editor - * @namespace jpf - * @author Mike de Boer <mike@javeline.com> - */ -jpf.editor.plugins = function(coll, editor) { - // the collections that are simple lookup tables so we don't need to use - // for-loops to do plugin lookups... - this.coll = {}; - this.collHooks = {}; - this.collTypes = {}; - this.collKeys = []; - - this.active = null; - - /** - * Add a plugin to the collection IF an implementation actually exists. - * - * @param {String} sPlugin The plugin identifier/ name - * @type {jpf.editor.plugin} - */ - this.add = function(sPlugin) { - if (!jpf.editor.plugin[sPlugin]) return null; - // yay, plugin does exist, so we can instantiate it for the editor - var plugin = new jpf.editor.plugin[sPlugin](sPlugin); - // add it to main plugin collection - this.coll[plugin.name] = plugin; - - if (plugin.type) { - // a type prop is set, push it up the type-collection - if (!this.collTypes[plugin.type]) - this.collTypes[plugin.type] = []; - this.collTypes[plugin.type].push(plugin); - } - if (plugin.subType) { - // a subType prop is set, push it up the type-collection - if (!this.collTypes[plugin.subType]) - this.collTypes[plugin.subType] = []; - this.collTypes[plugin.subType].push(plugin); - } - if (plugin.hook) { - // a hook prop is set, push it up the event hooks-collection - plugin.hook = plugin.hook.toLowerCase(); - if (!this.collHooks[plugin.hook]) - this.collHooks[plugin.hook] = []; - this.collHooks[plugin.hook].push(plugin); - } - - if (typeof plugin.keyBinding == "string") { - // a keyBinding prop has been set, parse it and push it up the - // keys-collection - plugin.keyBinding = { - meta : (plugin.keyBinding.indexOf('meta') > -1), - control: (plugin.keyBinding.indexOf('ctrl') > -1), - alt : (plugin.keyBinding.indexOf('alt') > -1), - shift : (plugin.keyBinding.indexOf('shift') > -1), - key : plugin.keyBinding.charAt(plugin.keyBinding.length - 1).toLowerCase() - }; - plugin.keyHash = createKeyHash(plugin.keyBinding); - if (!this.collKeys[plugin.keyHash]) - this.collKeys[plugin.keyHash] = []; - this.collKeys[plugin.keyHash].push(plugin); - } - return plugin; - }; - - /** - * Check if an item is actually a plugin (more specific: an ENABLED plugin) - * - * @param {String} name - * @type {Boolean} - */ - this.isPlugin = function(name) { - return this.coll[name] ? true : false; - }; - - /** - * Check if a plugin is currently active, or being executed. - * - * @param {String} name - * @type {Boolean} - */ - this.isActive = function(name) { - var o = (typeof name == "string") ? this.get(name) : name; - if (!o) return false; - - var res = false; - if (jpf.isArray(this.active)) { - for (i = this.active.length - 1; i >= 0 && !res; i--) - res = (this.active[i] === o); - } - else - res = (this.active === o); - return res; - }; - - /** - * API; Get a plugin object - * - * @param {String} name - * @type {jpf.editor.plugin} - */ - this.get = function(name) { - if (arguments.length == 1) - return this.coll[name] || null; - var arg, ret = []; - for (var i = 0, j = arguments.length; i < j; i++) { - arg = arguments[i]; - if (this.coll[arg]) - ret.push(this.coll[arg]); - } - return ret; - }; - - /** - * API; Get all plugins matching a specific plugin-type - * - * @param {String} type - * @type {Array} - */ - this.getByType = function(type) { - if (this.collTypes[type] && this.collTypes[type].length) - return this.collTypes[type]; - return []; - }; - - /** - * API; Get all plugins matching a specific Event hook - * - * @param {String} hook - * @type {Array} - */ - this.getByHook = function(hook) { - if (this.collHooks[hook] && this.collHooks[hook].length) - return this.collHooks[hook]; - return []; - }; - - /** - * Notify a plugin of any occuring Event, if it has subscribed to it - * - * @param {String} name - * @param {String} hook - * @type {mixed} - */ - this.notify = function(name, hook) { - var item = this.coll[name]; - if (item && item.hook == hook && !item.busy) - return item.execute(this.editor, arguments); - return null; - }; - - /** - * Notify all plugins of an occuring Event - * - * @param {String} hook - * @param {Event} e - * @type {Array} - */ - this.notifyAll = function(hook, e) { - var res = []; - if (!this.collHooks) - return res; - - var coll = this.collHooks[hook]; - for (var i in coll) { - if (!coll[i].busy && coll[i].execute) - res.push(coll[i].execute(this.editor, e)); - } - //this.active = res.length ? res : res[0]; - return res; - }; - - /** - * Notify all plugins of an occuring keyboard Event with a certain key combo - * - * @param {Object} keyMap - * @type {Array} - */ - this.notifyKeyBindings = function(keyMap) { - var hash = createKeyHash(keyMap); - if (!this.collKeys[hash] || !this.collKeys[hash].length) - return false; - - var coll = this.collKeys[hash]; - for (var i = 0, j = coll.length; i < j; i++) - coll[i].execute(this.editor, arguments); - //this.active = coll.length ? coll : coll[0]; - - return true; - }; - - /** - * Turns an object of mapped keystrokes to a numeric representation. - * Since ASCII numbers of character codes don't go above 255, we start - * with 256 for modifier keys and shift bits around to the left until we - * get a unique hash for each key combination. - * - * @param {Object} keyMap - * @type {Number} - * @private - */ - function createKeyHash(keyMap) { - return (keyMap.meta ? 2048 : 0) | (keyMap.control ? 1024 : 0) - | (keyMap.alt ? 512 : 0) | (keyMap.shift ? 256 : 0) - | (keyMap.key || "").charCodeAt(0); - } - - this.$destroy = function() { - for (var i in this.coll) { - this.coll[i].$destroy(); - this.coll[i] = null; - delete this.coll[i]; - } - this.coll = this.collHooks = this.collTypes = this.collKeys = null; - delete this.coll; - delete this.collHooks; - delete this.collTypes; - delete this.collKeys; - }; - - /* - * Initialize the Editor.plugins class. - * - * @param {Array} coll Collection of plugins that should be searched for and loaded - * @param {Editor} editor - * @type {jpf.editor.plugins} - */ - this.editor = editor; - if (coll && coll.length) { - for (var i = 0; i < coll.length; i++) - this.add(coll[i]); - } -}; - -jpf.editor.TOOLBARITEM = "toolbaritem"; -jpf.editor.TOOLBARBUTTON = "toolbarbutton"; -jpf.editor.TOOLBARPANEL = "toolbarpanel"; -jpf.editor.TEXTMACRO = "textmacro"; -jpf.editor.CMDMACRO = "commandmacro"; - -/** - * @class Plugin - * @constructor - * @extends editor - * @namespace jpf - * @author Mike de Boer <mike@javeline.com> - * - * Example plugin: - * <code language=javascript> - * jpf.editor.plugin('sample', function() { - * this.name = "SamplePluginName"; - * this.type = "PluginType"; - * this.subType = "PluginSubType"; - * this.hook = "EventHook"; - * this.params = null; - * - * this.execute = function(editor) { - * // code to be executed when the event hook is fired - * } - * // That's it! you can add more code below to your liking... - * }); - * </code> - */ -jpf.editor.plugin = function(sName, fExec) { - jpf.editor.plugin[sName] = function() { - this.uniqueId = jpf.all.push(this) - 1; - - /** - * Appends a new JML element - in its string representation - to an - * existing JML node. A new JML node will be created as specified by the - * contents of sNode and appended to oParent. - * - * @param {String} sNode - * @param {JmlNode} oParent - * @type {JmlNode} - */ - this.appendJmlNode = function(sNode, oParent) { - if (!sNode) return null; - - var jml = jpf.getXml("<tempnode>" + sNode + "</tempnode>"); - return jpf.JmlParser.parseMoreJml(jml, oParent, this.editor, true); - }; - - this.dispatchEvent = function() { - var _self = this; - window.setTimeout(function() { - if (_self.type == jpf.editor.CONTEXTPANEL - && _self.queryState(_self.editor) == jpf.editor.ON) - return; - _self.state = jpf.editor.OFF; - if (_self.editor) - _self.editor.notify(_self.name, _self.state); - //@todo: add animation? - jpf.popup.hide(); - jpf.popup.last = null; - }); - - return false; - }; - - this.$destroy = function() { - jpf.popup.forceHide(); // @todo should we keep this, or does jpf.Popup destroy itself? what if we removeNode() the editor? - this.buttonNode = this.editor = null; - delete this.buttonNode; - delete this.editor; - if (this.destroy) - this.destroy(); - } - - fExec.apply(this, arguments); - }; -}; - - - -/*FILEHEAD(/var/lib/jpf/src/elements/editor/selection.js)SIZE(-1077090856)TIME(1238933682)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -/** - * @class jpf.editor.selection - * @constructor - * @extends jpf.editor - * @author Mike de Boer <mike@javeline.com> - */ -jpf.editor.selection = function(editor) { - /* - * Initialize the Editor.selection class. - * - * @type Editor.selection - */ - this.editor = editor; - this.current = null; - - var csLock, - _self = this; - - /** - * Get the selection of the editable area - * - * @type {Selection} - */ - this.get = function() { - var oDoc = this.editor.oDoc; - return oDoc.selection - ? oDoc.selection - : this.editor.oWin.getSelection() - }; - - /** - * Set or move the current selection to the cached one. - * At the moment, this function is very IE specific and is used to make sure - * that there's a correct selection object available at all times. - * @see jpf.editor.selection.cache - * - * @type {Range} - */ - this.set = function() { - if (!jpf.isIE || !this.current) return; - - try { - this.editor.$visualFocus(); - this.current.select(); - } - catch (ex) {} - - this.editor.$visualFocus(); - return this.current; - }; - - /** - * Save the selection object/ current range into a global variable to cache - * it for later use. - * At the moment, this function is very IE specific and is used to make sure - * that there's a correct selection object available at all times. - * - * @type {void} - */ - this.cache = function() { - if (!jpf.isIE) return this; - var oSel = _self.editor.oDoc.selection; - _self.current = oSel.createRange(); - _self.current.type = oSel.type; - - if (_self.current.type == "Text" && _self.current.text == "" && !csLock) { - csLock = setTimeout(_self.cache, 0); - } - else { - clearTimeout(csLock); - csLock = null; - } - - return this; - }; - - /** - * Retrieve the active Range object of the current document selection. - * Internet Explorer returns a controlRange when a control (e.g. image, - * object tag) is selected or a textRange when a set of characters is - * selected. - * - * @type {Range} - */ - this.getRange = function() { - var oSel = this.get(), oDoc = this.editor.oDoc, range; - - try { - if (oSel) - range = oSel.rangeCount > 0 - ? oSel.getRangeAt(0) - : (oSel.createRange - ? oSel.createRange() - : oDoc.createRange()); - } - // IE throws unspecified error here if we're placed in a frame/iframe - catch (ex) {} - - // No range found then create an empty one - // This can occur when the editor is placed in a hidden container - // element on Gecko. Or on IE when there was an exception - if (!range) - range = jpf.isIE - ? oDoc.body.createTextRange() - : oDoc.createRange(); - - return range; - }; - - /** - * Set the active range of the current selection inside the editable - * document to a specified range. - * - * @param {Range} range - * @type {void} - */ - this.setRange = function(range) { - if (!jpf.isIE) { - var oSel = this.get(); - - if (oSel) { - oSel.removeAllRanges(); - oSel.addRange(range); - } - } - else { - try { - range.select(); - } - // Needed for some odd IE bug - catch (ex) {} - } - - return this; - }; - - /** - * Returns a bookmark location for the current selection. This bookmark - * object can then be used to restore the selection after some content - * modification to the document. - * - * @param {bool} type Optional State if the bookmark should be simple or not. Default is complex. - * @return {Object} Bookmark object, use moveToBookmark with this object to restore the selection. - */ - this.getBookmark = function(type) { - var range = this.getRange(), - viewport = this.editor.getViewPort(), - oDoc = this.editor.oDoc; - - // Simple bookmark fast but not as persistent - if (type == 'simple') - return {range : range, scrollX : viewport.x, scrollY : viewport.y}; - - var oEl, sp, bp, iLength; - var oRoot = oDoc.body; - - // Handle IE - if (jpf.isIE) { - // Control selection - if (range.item) { - oEl = range.item(0); - - var aNodes = oDoc.getElementsByTagName(oEl.nodeName); - for (var i = 0; i < aNodes.length; i++) { - if (oEl == aNodes[i]) { - sp = i; - break; - } - } - return { - tag : oEl.nodeName, - index : sp, - scrollX : viewport.x, - scrollY : viewport.y - }; - } - - // Text selection - var tRange = oDoc.body.createTextRange(); - tRange.moveToElementText(oRoot); - tRange.collapse(true); - bp = Math.abs(tRange.move('character', -0xFFFFFF)); - - tRange = range.duplicate(); - tRange.collapse(true); - sp = Math.abs(tRange.move('character', -0xFFFFFF)); - - tRange = range.duplicate(); - tRange.collapse(false); - iLength = Math.abs(tRange.move('character', -0xFFFFFF)) - sp; - - return { - start : sp - bp, - length : iLength, - scrollX : viewport.x, - scrollY : viewport.y - }; - } - - // Handle W3C - oEl = this.getSelectedNode(); - var oSel = this.get(); - - if (!oSel) - return null; - - // Image selection - if (oEl && oEl.nodeName == 'IMG') { - return { - scrollX : viewport.x, - scrollY : viewport.y - }; - } - - // Text selection - function getPos(sn, en) { - var w = oDoc.createTreeWalker(oRoot, NodeFilter.SHOW_TEXT, null, false), n, p = 0, d = {}; - - while ((n = w.nextNode()) != null) { - if (n == sn) - d.start = p; - if (n == en) { - d.end = p; - return d; - } - p += (n.nodeValue || '').trim().length; - } - return null; - } - - var wb = 0, wa = 0; - - // Caret or selection - if (oSel.anchorNode == oSel.focusNode && oSel.anchorOffset == oSel.focusOffset) { - oEl = getPos(oSel.anchorNode, oSel.focusNode); - if (!oEl) - return {scrollX : viewport.x, scrollY : viewport.y}; - // Count whitespace before - (oSel.anchorNode.nodeValue || '').trim().replace(/^\s+/, function(a) { - wb = a.length; - }); - - return { - start : Math.max(oEl.start + oSel.anchorOffset - wb, 0), - end : Math.max(oEl.end + oSel.focusOffset - wb, 0), - scrollX: viewport.x, - scrollY: viewport.y, - begin : oSel.anchorOffset - wb == 0 - }; - } - else { - oEl = getPos(range.startContainer, range.endContainer); - if (!oEl) - return {scrollX : viewport.x, scrollY : viewport.y}; - - return { - start : Math.max(oEl.start + range.startOffset - wb, 0), - end : Math.max(oEl.end + range.endOffset - wa, 0), - scrollX: viewport.x, - scrollY: viewport.y, - begin : range.startOffset - wb == 0 - }; - } - } - - /** - * Restores the selection to the specified bookmark. - * - * @param {Object} bookmark Bookmark to restore selection from. - * @return {Boolean} true/false if it was successful or not. - */ - this.moveToBookmark = function(bmark) { - var range = this.getRange(), oSel = this.get(), sd, nvl, nv; - - var oDoc = this.editor.oDoc; - var oRoot = oDoc.body; - if (!bmark) - return false; - - this.editor.oWin.scrollTo(bmark.scrollX, bmark.scrollY); - - // Handle explorer - if (jpf.isIE) { - // Handle simple - if (range = bmark.range) { - try { - range.select(); - } - catch (ex) {} - return true; - } - - this.editor.$visualFocus(); - - // Handle control bookmark - if (bmark.tag) { - range = oRoot.createControlRange(); - var aNodes = oDoc.getElementsByTagName(bmark.tag); - for (var i = 0; i < aNodes.length; i++) { - if (i == bmark.index) - range.addElement(aNodes[i]); - } - } - else { - // Try/catch needed since this operation breaks when the editor - // is placed in hidden divs/tabs - try { - // Incorrect bookmark - if (bmark.start < 0) - return true; - range = oSel.createRange(); - range.moveToElementText(oRoot); - range.collapse(true); - range.moveStart('character', bmark.start); - range.moveEnd('character', bmark.length); - } - catch (ex2) { - return true; - } - } - try { - range.select(); - } - catch (ex) {} // Needed for some odd IE bug - return true; - } - - // Handle W3C - if (!oSel) - return false; - - // Handle simple - if (bmark.range) { - oSel.removeAllRanges(); - oSel.addRange(bmark.range); - } - else if (typeof bmark.start != "undefined" && typeof bmark.end != "undefined") { - function getPos(sp, ep) { - var w = oDoc.createTreeWalker(oRoot, NodeFilter.SHOW_TEXT, null, false) - var n, p = 0, d = {}, o, wa, wb; - - while ((n = w.nextNode()) != null) { - wa = wb = 0; - nv = n.nodeValue || ''; - nvl = nv.trim().length; - p += nvl; - if (p >= sp && !d.startNode) { - o = sp - (p - nvl); - // Fix for odd quirk in FF - if (bmark.begin && o >= nvl) - continue; - d.startNode = n; - d.startOffset = o + wb; - } - if (p >= ep) { - d.endNode = n; - d.endOffset = ep - (p - nvl) + wb; - return d; - } - } - return null; - }; - - try { - sd = getPos(bmark.start, bmark.end); - if (sd) { - range = oDoc.createRange(); - range.setStart(sd.startNode, sd.startOffset); - range.setEnd(sd.endNode, sd.endOffset); - oSel.removeAllRanges(); - oSel.addRange(range); - } - - if (!jpf.isOpera) - this.editor.$visualFocus(); - } - catch (ex) {} - } - } - - /** - * Retrieve the contents of the currently active selection/ range as a - * string of HTML. - * - * @type {String} - */ - this.getContent = function(retType) { - if (typeof retType != "string") - retType = "html" - var range = this.getRange(), oSel = this.get(), prefix, suffix, n; - var oNode = this.editor.oDoc.body; - - if (retType == "text") - return this.isCollapsed() ? '' : (range.text || (oSel.toString ? oSel.toString() : '')); - - if (this.isCollapsed()) - return ""; - - if (typeof range.htmlText != "undefined") - return range.htmlText; - - - var pNode, n = range.cloneContents(); - if (!n.childNodes.length) - return ""; - - pNode = n.childNodes[0].ownerDocument.createElement("div"); - pNode.appendChild(n); - return pNode.innerHTML; - - /* - prefix = suffix = ''; - //if (this.editor.output == 'text') - //return this.isCollapsed() ? '' : (range.htmlText || (range.item && range.item(0).outerHTML) || '');//oSel.toString ? oSel.toString() : '')); // ? - - if (range.cloneContents) { - n = range.cloneContents(); - if (n) - oNode.appendChild(n); - } - else if (typeof range.item != "undefined" || typeof range.htmlText != "undefined") - oNode.innerHTML = range.item ? range.item(0).outerHTML : range.htmlText; - else - oNode.innerHTML = range.toString(); - - // Keep whitespace before and after - if (/^\s/.test(oNode.innerHTML)) - prefix = ' '; - if (/\s+$/.test(oNode.innerHTML)) - suffix = ' '; - - // Note: TinyMCE uses a serializer here, I don't. - // prefix + this.serializer.serialize(oNode, options) + suffix; - return this.isCollapsed() ? '' : prefix + oNode.outerHTML + suffix;*/ - } - - /** - * Alter the content of the current selection/ active range by setting its - * contents with some other specified HTML - * - * @param {String} html - * @type {void} - * @return A reference to the HTML node which has been inserted or its direct parent - */ - this.setContent = function(html, bNoPrepare) { - var range = this.getRange(); - var oDoc = this.editor.oDoc; - - if (!bNoPrepare) - html = this.editor.prepareHtml(html, true); - - if (range.insertNode) { - // Make caret marker since insertNode places the caret in the - // beginning of text after insert - html += '<span id="__caret">_</span>'; - - // Delete and insert new node - range.deleteContents(); - range.insertNode(this.getRange().createContextualFragment(html)); - - // Move to caret marker - var oCaret = oDoc.getElementById('__caret'); - var htmlNode = oCaret.previousSibling; - - // Make sure we wrap it completely, Opera fails with a simple - // select call - range = oDoc.createRange(); - range.setStartBefore(oCaret); - range.setEndAfter(oCaret); - this.setRange(range); - - // Delete the marker, and hopefully the caret gets placed in the - // right location - oDoc.execCommand('Delete', false, null); - - // In case it's still there - if (oCaret && oCaret.parentNode) - oCaret.parentNode.removeChild(oCaret); - - return htmlNode; - } - else { - if (range.item) { - // Delete content and get caret text selection - this.remove(); - range = this.getRange(); - } - - html = html.replace(/^<(\w+)/, '<$1 id="__caret"'); - range.pasteHTML(html); - var htmlNode = oDoc.getElementById('__caret'); - if (htmlNode) { - htmlNode.removeAttribute("id"); - return htmlNode; - } - } - } - - var styleObjNodes = { - img : 1, - hr : 1, - li : 1, - table : 1, - tr : 1, - td : 1, - embed : 1, - object: 1, - ol : 1, - ul : 1 - }; - - /** - * Get the type of selection of the editable area - * - * @type String - */ - this.getType = function() { - var oSel = this.get(); - if (jpf.isIE) { - return oSel.type; - } - else { - // By default set the type to "Text". - var type = 'Text' ; - // Check if the actual selection is a Control (IMG, TABLE, HR, etc...). - if (oSel && oSel.rangeCount == 1) { - var range = oSel.getRangeAt(0); - if (range.startContainer == range.endContainer - && (range.endOffset - range.startOffset) == 1 - && range.startContainer.nodeType == 1 - && styleObjNodes[range.startContainer - .childNodes[range.startOffset].nodeName.toLowerCase()]) { - type = 'Control'; - } - } - return type; - } - }; - - /** - * Retrieve the currently selected element from the editable area - * - * @return {DOMObject} Currently selected element or common ancestor element - */ - this.getSelectedNode = function() { - var range = this.getRange(); - - if (!jpf.isIE) { - // Range maybe lost after the editor is made visible again - if (!range) - return this.editor.oDoc; - - var oSel = this.get(), oNode = range.commonAncestorContainer; - - // Handle selection as image or other control like element such - // as anchors - if (!range.collapsed) { - // If the anchor node is an element instead of a text node then - // return this element - if (jpf.isSafari && oSel.anchorNode && oSel.anchorNode.nodeType == 1) - return oSel.anchorNode.childNodes[oSel.anchorOffset]; - - if (range.startContainer == range.endContainer) { - if (range.startOffset - range.endOffset < 2) { - if (range.startContainer.hasChildNodes()) - oNode = range.startContainer.childNodes[range.startOffset]; - } - } - } - - //oNode = oNode.parentNode; - //while (oNode && oNode.parentNode && oNode.nodeType != 1) - // oNode = oNode.parentNode; - return oNode; - } - - return range.item ? range.item(0) : range.parentElement(); - }; - - /** - * Retrieve the parent node of the currently selected element from the - * editable area - * - * @type DOMObject - */ - this.getParentNode = function() { - switch (this.getType()) { - case "Control" : - if (jpf.isIE) - return this.getSelectedNode().parentElement; - else - return this.getSelectedNode().parentNode; - case "None" : - return; - default : - var oSel = this.get(); - if (jpf.isIE) { - return oSel.createRange().parentElement(); - } - else { - if (oSel) { - var oNode = oSel.anchorNode; - while (oNode && oNode.nodeType != 1) - oNode = oNode.parentNode; - return oNode; - } - } - break; - } - }; - - /** - * Select a specific node inside the editable area - * - * @param {DOMObject} node - * @type void - */ - this.selectNode = function(node) { - //this.editor.setFocus(); - var oSel, range; - if (jpf.isIE) { - oSel = this.get(); - - if (!node) - node = oSel.createRange().parentElement(); - - oSel.empty(); - - try { - // Try to select the node as a control. - range = this.editor.oDoc.body.createControlRange(); - range.addElement(node); - } - catch (e) { - // If failed, select it as a text range. - range = this.editor.oDoc.body.createTextRange(); - range.moveToElementText(node); - } - range.select(); - } - else { - range = this.getRange(); - if (node) - range.selectNode(node); - oSel = this.get(); - oSel.removeAllRanges(); - oSel.addRange(range); - } - - return this; - }; - - /** - * Collapse the selection to start or end of range. - * - * @param {Boolean} toEnd Optional boolean state if to collapse to end or not. Defaults to start. - * @type {void} - */ - this.collapse = function(toEnd) { - var range = this.getRange(), n; - - // 'Control' range on IE - if (range.item) { - n = range.item(0); - range = this.editor.oDoc.body.createTextRange(); - range.moveToElementText(n); - } - - range.collapse(!!toEnd); - this.setRange(range); - - return this; - }; - - /** - * Checks if the active range is in a collapsed state or not. - * - * @type {Boolean} - */ - this.isCollapsed = function() { - var range = this.getRange(), oSel = this.get(); - - if (!range || range.item) - return false; - - return !oSel || range.boundingWidth == 0 || range.collapsed; - }; - - /** - * Check if the currently selected element has any parent node(s) with the - * specified tagname - * - * @param {String} nodeTagName - * @type {Boolean} - */ - this.hasAncestorNode = function(nodeTagName) { - var oContainer, range = this.getRange(); - if (this.getType() == "Control" || !jpf.isIE) { - oContainer = this.getSelectedNode(); - if (!oContainer && !jpf.isIE) { - try { - oContainer = range.startContainer; - } - catch(e){} - } - } - else { - oContainer = range.parentElement(); - } - while (oContainer) { - if (jpf.isIE) - if (oContainer.tagName == nodeTagName) - return true; - else if (oContainer.nodeType == 1 - && oContainer.tagName == nodeTagName) - return true; - oContainer = oContainer.parentNode; - } - return false ; - }; - - /** - * Move the selection to a parent element of the currently selected node - * with the specified tagname - * - * @param {String} nodeTagName - * @type {void} - */ - this.moveToAncestorNode = function(nodeTagName) { - var oNode, i, range = this.getRange(); - nodeTagName = nodeTagName.toUpperCase(); - if (jpf.isIE) { - if (this.getType() == "Control") { - for (i = 0; i < range.length; i++) { - if (range(i).parentNode) { - oNode = range(i).parentNode; - break; - } - } - } - else { - oNode = range.parentElement(); - } - while (oNode && oNode.nodeName != nodeTagName) - oNode = oNode.parentNode; - return oNode; - } - else { - var oContainer = this.getSelectedNode(); - if (!oContainer) - oContainer = this.editor.oWin.getSelection().getRangeAt(0).startContainer - while (oContainer) { - if (oContainer.tagName == nodeTagName) - return oContainer; - oContainer = oContainer.parentNode; - } - return null ; - } - }; - - /** - * Remove the currently selected contents from the editable area - * - * @type {Selection} - */ - this.remove = function() { - var oSel = this.get(), i; - if (jpf.isIE) { - if (oSel.type.toLowerCase() != "none") - oSel.clear(); - } - else if (oSel) { - for (i = 0; i < oSel.rangeCount; i++) - oSel.getRangeAt(i).deleteContents(); - } - return this; - }; - - this.$destroy = function() { - this.editor = this.current = _self = null; - delete this.editor; - delete this.current; - delete _self; - }; -}; - - - -/*FILEHEAD(/var/lib/jpf/src/elements/editor/plugins/media.js)SIZE(-1077090856)TIME(1238933682)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -jpf.editor.plugin('media', function(){ - this.name = 'media'; - this.icon = 'media'; - this.type = jpf.editor.TOOLBARITEM; - this.subType = jpf.editor.TOOLBARBUTTON; - this.hook = 'ontoolbar'; - this.keyBinding = 'ctrl+m'; - this.state = jpf.editor.OFF; - - this.execute = function(editor) { - // @todo: implement this plugin - editor.dispatchEvent("pluginexecute", {name: this.name, plugin: this}); - }; - - this.queryState = function(editor) { - return this.state; - }; -}); - - - -/*FILEHEAD(/var/lib/jpf/src/elements/editor/plugins/printing.js)SIZE(-1077090856)TIME(1238933682)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -jpf.editor.plugin('print', function(){ - this.name = 'print'; - this.icon = 'print'; - this.type = jpf.editor.TOOLBARITEM; - this.subType = jpf.editor.TOOLBARBUTTON; - this.hook = 'ontoolbar'; - this.keyBinding = 'ctrl+p'; - this.state = jpf.editor.OFF; - - this.execute = function(editor) { - if (jpf.print) - jpf.print(editor.getValue()); - - editor.dispatchEvent("pluginexecute", {name: this.name, plugin: this}); - }; - - this.queryState = function() { - return this.state; - }; -}); - -jpf.editor.plugin('preview', function(){ - this.name = 'preview'; - this.icon = 'preview'; - this.type = jpf.editor.TOOLBARITEM; - this.subType = jpf.editor.TOOLBARBUTTON; - this.hook = 'ontoolbar'; - this.keyBinding = 'ctrl+shift+p'; - this.state = jpf.editor.OFF; - - this.execute = function(editor) { - if (jpf.printer) - jpf.printer.preview(editor.getValue()); - - editor.dispatchEvent("pluginexecute", {name: this.name, plugin: this}); - }; - - this.queryState = function() { - return this.state; - }; -}); - - - -/*FILEHEAD(/var/lib/jpf/src/elements/editor/plugins/blockquote.js)SIZE(-1077090856)TIME(1238933682)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -jpf.editor.plugin('blockquote', function(){ - this.name = 'blockquote'; - this.icon = 'blockquote'; - this.type = jpf.editor.TOOLBARITEM; - this.subType = jpf.editor.TOOLBARBUTTON; - this.hook = 'ontoolbar'; - this.keyBinding = 'ctrl+shift+b'; - this.buttonBuilt = false; - this.state = jpf.editor.OFF; - - this.execute = function(editor) { - editor.executeCommand('FormatBlock', 'BLOCKQUOTE'); - - editor.dispatchEvent("pluginexecute", {name: this.name, plugin: this}); - }; - - this.queryState = function(editor) { - return editor.getCommandState('FormatBlock'); - }; -}); - - - -/*FILEHEAD(/var/lib/jpf/src/elements/editor/plugins/scayt.js)SIZE(-1077090856)TIME(1238933682)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -jpf.editor.plugin('scayt', function(){ - this.name = 'scayt'; - this.icon = 'scayt'; - this.type = jpf.editor.TOOLBARITEM; - this.subType = jpf.editor.TOOLBARBUTTON; - this.hook = 'ontoolbar'; - this.keyBinding = 'ctrl+h'; - this.state = jpf.editor.OFF; - - this.execute = function(editor) { - // @todo: implement this plugin - - // cmd=get_opt - // customerid=1:rvyy72-5NS5o3-yXVS13-hNbyY1-GNda0-KjkQH1-jWrIR3-03eg64-J9VJ93-LXmzy4-FeHKe2-VO5TF3 - // sessionid= - // --------------------- - // cmd=scayt_spelltext - // customerid=1:rvyy72-5NS5o3-yXVS13-hNbyY1-GNda0-KjkQH1-jWrIR3-03eg64-J9VJ93-LXmzy4-FeHKe2-VO5TF3 - // sessionid=1 - // text={urlencoded, html-tag-free text} - // slang=en - // intlang=en - // sug_len=14 - jpf.oHttp.get(function() { - - }, {}); - - editor.dispatchEvent("pluginexecute", {name: this.name, plugin: this}); - }; - - this.queryState = function(editor) { - return this.state; - }; -}); - - - -/*FILEHEAD(/var/lib/jpf/src/elements/editor/plugins/color.js)SIZE(-1077090856)TIME(1238933682)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -jpf.editor.colorPlugin = function(sName) { - this.name = sName; - this.icon = sName; - this.type = jpf.editor.TOOLBARITEM; - this.subType = jpf.editor.TOOLBARPANEL; - this.hook = 'ontoolbar'; - this.buttonNode = null; - this.state = jpf.editor.OFF; - this.colspan = 18; - - var panelBody; - - var colorAtoms = ['00', '33', '66', '99', 'CC', 'FF']; - function generatePalette() { - jpf.editor.colorPlugin.palette = []; - var r, g, b, iCol; - for (r = 0; r < colorAtoms.length; r++) { - for (g = 0; g < colorAtoms.length; g++) { - iCol = (r % 3) * 6 + g; - for (b = 0; b < colorAtoms.length; b++) { - if (!jpf.editor.colorPlugin.palette[iCol]) - jpf.editor.colorPlugin.palette[iCol] = []; - jpf.editor.colorPlugin.palette[iCol][(r < 3 ? 0 : 6) + b] = { - red : colorAtoms[r], - green: colorAtoms[g], - blue : colorAtoms[b] - }; - } - } - } - } - - /** - * Color code from MS sometimes differ from RGB; it's BGR. This method - * converts both ways - * - * @param {color} c code - RGB-->BGR or BGR-->RGB - * @type String - * @return RGB<-->BGR - */ - function RGBToBGRToRGB(c) { - if (typeof c == 'string' && c.length > 0) { - //c = c.parseColor(); - var tmp = []; - var ch1 = c.charAt(0); - var ch2 = c.charAt(4); - tmp[0] = ch2; - tmp[4] = ch1; - ch1 = c.charAt(1); - ch2 = c.charAt(5); - tmp[1] = ch2; - tmp[5] = ch1; - return tmp[0] + tmp[1] + c.charAt(2) + c.charAt(3) + tmp[4] + tmp[5]; - } - return c; - } - - function int2Color(intVal) { - var colorVal = (intVal & 0xFFFFFF).toString(16); - return ("000000").substring(0, 6 - colorVal.length) + colorVal; - } - - this.init = function(editor, btn) { - this.buttonNode.className = this.buttonNode.className + " dropdown_small"; - var oArrow = this.buttonNode.getElementsByTagName("div")[0]; - this.colorPreview = this.buttonNode.insertBefore(document.createElement('div'), - oArrow); - this.colorPreview.className = "colorpreview"; - var colorArrow = this.buttonNode.insertBefore(document.createElement('span'), - oArrow); - colorArrow.className = "selectarrow"; - }; - - this.execute = function(editor) { - if (!panelBody) { - this.editor = editor; - jpf.popup.setContent(this.uniqueId, this.createPanelBody()); - } - - editor.dispatchEvent("pluginexecute", {name: this.name, plugin: this}); - - this.editor.showPopup(this, this.uniqueId, this.buttonNode, jpf.isIE6 ? 296 : 292, 167); - //return button id, icon and action: - return { - id: this.name, - action: null - }; - }; - - this.setStyleMethod = function(useSpan) { - if (typeof useSpan == "undefined") - useSpan = true; - // Tell Gecko to use or not the <SPAN> tag for the bold, italic and underline. - try { - this.editor.oDoc.execCommand('styleWithCSS', false, useSpan); - } - catch (ex) { - this.editor.oDoc.execCommand('useCSS', false, !useSpan); - } - }; - - this.queryState = function(editor) { - var cmdName = this.name == "forecolor" - ? 'ForeColor' - : jpf.isIE ? 'BackColor' : 'HiliteColor'; - this.state = editor.getCommandState(cmdName); - var currValue = ""; - try { - currValue = editor.oDoc.queryCommandValue(cmdName); - } - catch (ex) {} - if (jpf.isIE) - currValue = '#' + RGBToBGRToRGB(int2Color(currValue)); - if (currValue != this.colorPreview.style.backgroundColor) - this.colorPreview.style.backgroundColor = currValue; - }; - - this.submit = function(e) { - e = new jpf.AbstractEvent(e || window.event); - while (e.target.tagName.toLowerCase() != "a" && e.target.className != "editor_popup") - e.target = e.target.parentNode; - var sColor = e.target.getAttribute('rel'); - if (sColor) { - jpf.popup.forceHide(); -// if (this.name == "backcolor" && jpf.isGecko) -// this.setStyleMethod(true); - this.editor.executeCommand(this.name == "forecolor" - ? 'ForeColor' - : jpf.isIE ? 'BackColor' : 'HiliteColor', - '#' + sColor); -// if (this.name == "backcolor" && jpf.isGecko) -// this.setStyleMethod(false); - } - }; - - this.createPanelBody = function() { - if (!jpf.editor.colorPlugin.palette) - generatePalette(); - - panelBody = document.body.appendChild(document.createElement('div')); - panelBody.className = "editor_popup"; - panelBody.style.display = "none"; - var aHtml = []; - - var row, col, colorCode, palette = jpf.editor.colorPlugin.palette; - for (row = 0; row < palette[0].length; row++) { - aHtml.push('<div class="editor_panelrow">'); - for (col= 0; col < palette.length; col++) { - colorCode = palette[col][row].red + - palette[col][row].green + - palette[col][row].blue; - aHtml.push('<a class="editor_smallcell editor_panelcell" style="background-color:#', - colorCode, ';" rel="', colorCode, - '" href="javascript:;" onmousedown="jpf.lookup(', this.uniqueId, - ').submit(event);">\ - </a>'); - } - aHtml.push('</div>'); - } - panelBody.innerHTML = aHtml.join(''); - - return panelBody; - } - - this.destroy = function() { - panelBody = this.colorPreview = null; - delete panelBody; - delete this.colorPreview; - }; -}; -jpf.editor.colorPlugin.palette = null; - -jpf.editor.plugin('forecolor', jpf.editor.colorPlugin); -jpf.editor.plugin('backcolor', jpf.editor.colorPlugin); - - - -/*FILEHEAD(/var/lib/jpf/src/elements/editor/plugins/datetime.js)SIZE(-1077090856)TIME(1238933682)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -jpf.editor.dateTimePlugin = function(sName) { - this.name = sName; - this.icon = sName; - this.type = jpf.editor.TOOLBARITEM; - this.subType = jpf.editor.TOOLBARBUTTON; - this.hook = 'ontoolbar'; - this.keyBinding = sName == "insertdate" ? 'ctrl+shift+d' : 'ctrl+shift+t'; - this.state = jpf.editor.OFF; - this.i18n = { //default English (en_GB) - date_format :"%Y-%m-%d", - time_format :"%H:%M:%S", - months_long :"January,February,March,April,May,June,July,August,September,October,November,December", - months_short :"Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec", - days_long :"Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday", - days_short :"Sun,Mon,Tue,Wed,Thu,Fri,Sat,Sun" - }; - - this.execute = function(editor) { - if (typeof this.i18n.months_long == "string") { - this.i18n.months_long = this.i18n.months_long.split(','); - this.i18n.months_short = this.i18n.months_short.split(','); - this.i18n.days_long = this.i18n.days_long.split(','); - this.i18n.days_short = this.i18n.days_short.split(','); - } - var d = new Date(); - var fmt = (this.name == "insertdate") ? this.i18n.date_format : this.i18n.time_format; - fmt = fmt.replace("%D", "%m/%d/%y") - .replace("%r", "%I:%M:%S %p") - .replace("%Y", "" + d.getFullYear()) - .replace("%y", "" + d.getYear()) - .replace("%m", ("" + d.getMonth() + 1).pad(2, "0")) - .replace("%d", ("" + d.getDate()).pad(2, "0")) - .replace("%H", ("" + d.getHours()).pad(2, "0")) - .replace("%M", ("" + d.getMinutes()).pad(2, "0")) - .replace("%S", ("" + d.getSeconds()).pad(2, "0")) - .replace("%I", "" + (d.getHours() + 11) % 12 + 1) - .replace("%p", "" + (d.getHours() < 12 ? "AM" : "PM")) - .replace("%B", "" + this.i18n.months_long[d.getMonth()]) - .replace("%b", "" + this.i18n.months_short[d.getMonth()]) - .replace("%A", "" + this.i18n.days_long[d.getDay()]) - .replace("%a", "" + this.i18n.days_short[d.getDay()]) - .replace("%%", "%"); - - editor.insertHTML(fmt, true); - - editor.dispatchEvent("pluginexecute", {name: this.name, plugin: this}); - }; - - this.queryState = function() { - return this.state; - }; -}; - -jpf.editor.plugin('insertdate', jpf.editor.dateTimePlugin); -jpf.editor.plugin('inserttime', jpf.editor.dateTimePlugin); - - - -/*FILEHEAD(/var/lib/jpf/src/elements/editor/plugins/subsup.js)SIZE(-1077090856)TIME(1238933682)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -jpf.editor.subSupCommand = function(sName) { - this.name = sName; - this.icon = sName; - this.type = jpf.editor.TOOLBARITEM; - this.subType = jpf.editor.TOOLBARBUTTON; - this.hook = 'ontoolbar'; - this.keyBinding = sName == "sub" ? 'ctrl+alt+s' : 'ctrl+shift+s'; - this.state = jpf.editor.OFF; - - this.execute = function(editor) { - var other = this.name == "sub" ? 'Superscript' : 'Subscript'; - if (editor.getCommandState(other) == jpf.editor.ON) - editor.executeCommand(other); - editor.executeCommand(this.name == "sub" ? 'Subscript' : 'Superscript'); - - editor.dispatchEvent("pluginexecute", {name: this.name, plugin: this}); - }; - - this.queryState = function(editor) { - return editor.getCommandState(this.name == "sub" - ? 'Subscript' - : 'Superscript'); - }; -} -jpf.editor.plugin('sub', jpf.editor.subSupCommand); -jpf.editor.plugin('sup', jpf.editor.subSupCommand); - - - -/*FILEHEAD(/var/lib/jpf/src/elements/editor/plugins/clipboard.js)SIZE(-1077090856)TIME(1238933682)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -jpf.editor.plugin('pastetext', function() { - this.name = 'pastetext'; - this.icon = 'pastetext'; - this.type = jpf.editor.TOOLBARITEM; - this.subType = jpf.editor.TOOLBARPANEL; - this.hook = 'ontoolbar'; - this.keyBinding = 'ctrl+shift+v'; - this.state = jpf.editor.OFF; - - var panelBody; - - this.init = function(editor, btn) { - this.buttonNode.className = this.buttonNode.className + " dropdown_small"; - var oArrow = this.buttonNode.insertBefore(document.createElement('span'), - this.buttonNode.getElementsByTagName("div")[0]); - oArrow.className = "selectarrow"; - }; - - this.execute = function(editor) { - if (!panelBody) { - this.editor = editor; - jpf.popup.setContent(this.uniqueId, this.createPanelBody()); - } - - editor.dispatchEvent("pluginexecute", {name: this.name, plugin: this}); - - this.editor.showPopup(this, this.uniqueId, this.buttonNode, 300, 270); - if (panelBody.style.visibility == "hidden") - panelBody.style.visibility = "visible"; - var _self = this; - setTimeout(function() { - _self.oArea.focus(); - }, 100); // 100ms, because of the $focusfix code... - //return button id, icon and action: - return { - id: this.name, - action: null - }; - }; - - this.queryState = function(editor) { - return this.state; - }; - - this.submit = function(e) { - jpf.popup.forceHide(); - - var sContent = this.oArea.value; - if (!sContent || sContent.length == 0) return; - - var rl = ['\u2122', '<sup>TM</sup>', '\u2026', '...', '\u201c|\u201d', - '"', '\u2019,\'', '\u2013|\u2014|\u2015|\u2212', '-']; - for (var i = 0; i < rl.length; i += 2) - sContent = sContent.replace(new RegExp(rl[i], 'gi'), rl[i+1]); - - sContent = sContent.replace(/\r\n/g, '<br />') - .replace(/\r/g, '<br />') - .replace(/\n/g, '<br />'); - this.editor.insertHTML(sContent); - - if (e.stop) - e.stop(); - else - e.cancelBubble = true; - return false; - }; - - this.createPanelBody = function() { - panelBody = document.body.appendChild(document.createElement('div')); - panelBody.className = "editor_popup"; - panelBody.style.display = "none"; - var idArea = 'editor_' + this.uniqueId + '_input'; - var idBtns = 'editor_' + this.uniqueId + '_btns'; - panelBody.innerHTML = - '<label for="' + idArea + '">' + - this.editor.translate('paste_keyboardmsg', true).sprintf(jpf.isMac ? 'CMD+V' : 'CTRL+V') - + '</label>\ - <textarea id="' + idArea + '" name="' + idArea + '" wrap="soft" dir="ltr" \ - cols="60" rows="10" class="editor_textarea"></textarea>\ - <div class="editor_panelrow" style="position:absolute;bottom:0;width:100%" id="' + idBtns + '"></div>'; - - this.oArea = document.getElementById(idArea); - jpf.sanitizeTextbox(this.oArea); - if (jpf.isIE) { - this.oArea.onselectstart = this.oArea.onpaste = function(e) { - e = e || window.event; - e.cancelBubble = true; - }; - } - this.appendJmlNode( - '<j:toolbar xmlns:j="' + jpf.ns.jml + '"><j:bar>\ - <j:button caption="' + this.editor.translate('insert') + '" \ - onclick="jpf.lookup(' + this.uniqueId + ').submit(event)" />\ - </j:bar></j:toolbar>', - document.getElementById(idBtns)); - - return panelBody; - }; - - this.destroy = function() { - panelBody = this.oArea = null; - delete panelBody; - delete this.oArea; - }; -}); -jpf.editor.plugin('pasteword', function() { - this.name = 'pasteword'; - this.icon = 'pasteword'; - this.type = jpf.editor.CMDMACRO; - this.hook = 'onpaste'; - this.keyBinding = 'ctrl+shift+v'; - this.state = jpf.editor.OFF; - - this.parse = function(sContent) { - // Cleanup Word content - var bull = String.fromCharCode(8226); - var middot = String.fromCharCode(183); - // convert headers to strong typed character (BOLD) - sContent = sContent.replace(new RegExp('<p class=MsoHeading.*?>(.*?)<\/p>', 'gi'), '<p><b>$1</b></p>') - .replace(new RegExp('tab-stops: list [0-9]+.0pt">', 'gi'), '">' + "--list--") - .replace(new RegExp(bull + "(.*?)<BR>", "gi"), "<p>" + middot + "$1</p>") - .replace(new RegExp('<SPAN style="mso-list: Ignore">', 'gi'), "<span>" + bull) // Covert to bull list - .replace(/<o:p><\/o:p>/gi, "") - .replace(new RegExp('<br style="page-break-before: always;.*>', 'gi'), '-- page break --') // Replace pagebreaks - .replace(new RegExp('<(!--)([^>]*)(--)>', 'g'), "") // Word comments - .replace(/<\/?span[^>]*>/gi, "") //remove Word-generated superfluous spans - .replace(new RegExp('<(\\w[^>]*) style="([^"]*)"([^>]*)', 'gi'), "<$1$3") //remove inline style attributes - .replace(/<\/?font[^>]*>/gi, "") - .replace(/<(\w[^>]*) class=([^ |>]*)([^>]*)/gi, "<$1$3") // Strips class attributes. - //.replace(new RegExp('<(\\w[^>]*) class="?mso([^ |>]*)([^>]*)', 'gi'), "<$1$3"); //MSO class attributes - //.replace(new RegExp('href="?' + this._reEscape("" + document.location) + '', 'gi'), 'href="' + this.editor.documentBaseURI.getURI()); - .replace(/<(\w[^>]*) lang=([^ |>]*)([^>]*)/gi, "<$1$3") - .replace(/<\\?\?xml[^>]*>/gi, "") - .replace(/<\/?\w+:[^>]*>/gi, "") - .replace(/-- page break --\s*<p> <\/p>/gi, "") // Remove pagebreaks - .replace(/-- page break --/gi, "") // Remove pagebreaks - .replace(/<\/p>/gi, "<br /><br />") //convert <p> newlines to <br> ones - .replace(/<\/?p[^>]*>/gi, "") - .replace(/<\/?div[^>]*>/gi, "") - .replace(/<TABLE[^>]*cellPadding=[^>]*>/gi, '<table border="0">') //correct tables - .replace(/<td[^>]*vAlign=[^>]*>/gi, '<td>'); - //.replace(/\/? */gi, ""); - //.replace(/<p> <\/p>/gi, ''); - // Replace all headers with strong and fix some other issues - //sContent = sContent.replace(/<h[1-6]> <\/h[1-6]>/gi, '<p> </p>') - // .replace(/<h[1-6]>/gi, '<p><b>') - // .replace(/<\/h[1-6]>/gi, '</b></p>') - // .replace(/<b> <\/b>/gi, '<b> </b>') - // .replace(/^( )*/gi, ''); - - // Convert all middlot lists to UL lists - var div = document.createElement("div"); - div.innerHTML = sContent; - // Convert all middot paragraphs to li elements - while (this._convertMiddots(div, "--list--")); // bull - while (this._convertMiddots(div, middot, "unIndentedList")); // Middot - while (this._convertMiddots(div, bull)); // bull - sContent = div.innerHTML; - - return sContent.replace(/--list--/gi, ""); // Remove temporary --list-- - }; - - this._convertMiddots = function(div, search, class_name) { - var mdot = String.fromCharCode(183), bull = String.fromCharCode(8226); - var nodes, prevul, i, p, ul, li, np, cp; - - nodes = div.getElementsByTagName("p"); - for (i = 0; i < nodes.length; i++) { - p = nodes[i]; - - // Is middot - if (p.innerHTML.indexOf(search) != 0) continue; - - ul = document.createElement("ul"); - if (class_name) - ul.className = class_name; - - // Add the first one - li = document.createElement("li"); - li.innerHTML = p.innerHTML.replace(new RegExp('' + mdot + '|' + bull + '|--list--| ', "gi"), ''); - ul.appendChild(li); - - // Add the rest - np = p.nextSibling; - while (np) { - // If the node is whitespace, then - // ignore it and continue on. - if (np.nodeType == 3 && new RegExp('^\\s$', 'm').test(np.nodeValue)) { - np = np.nextSibling; - continue; - } - - if (search == mdot) { - if (np.nodeType == 1 && new RegExp('^o(\\s+| )').test(np.innerHTML)) { - // Second level of nesting - if (!prevul) { - prevul = ul; - ul = document.createElement("ul"); - prevul.appendChild(ul); - } - np.innerHTML = np.innerHTML.replace(/^o/, ''); - } - else { - // Pop the stack if we're going back up to the first level - if (prevul) { - ul = prevul; - prevul = null; - } - // Not element or middot paragraph - if (np.nodeType != 1 || np.innerHTML.indexOf(search) != 0) - break; - } - } - else { - // Not element or middot paragraph - if (np.nodeType != 1 || np.innerHTML.indexOf(search) != 0) - break; - } - - cp = np.nextSibling; - li = document.createElement("li"); - li.innerHTML = np.innerHTML.replace(new RegExp('' + mdot + '|' + bull + '|--list--| ', "gi"), ''); - np.parentNode.removeChild(np); - ul.appendChild(li); - np = cp; - } - p.parentNode.replaceChild(ul, p); - return true; - } - return false; - }; -}); - - - -/*FILEHEAD(/var/lib/jpf/src/elements/editor/plugins/tables.js)SIZE(-1077090856)TIME(1238933682)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -jpf.editor.plugin('table', function() { - this.name = 'table'; - this.icon = 'table'; - this.type = jpf.editor.TOOLBARITEM; - this.subType = jpf.editor.TOOLBARPANEL; - this.hook = 'ontoolbar'; - this.keyBinding = 'ctrl+alt+shift+t'; - this.state = jpf.editor.OFF; - - var panelBody, oTableCont, oTableSel, oTable, oStatus, oTablePos, oDoc, - iCurrentX = 0, - iCurrentY = 0, - _self = this; - - this.init = function(editor, btn) { - this.buttonNode.className = this.buttonNode.className + " dropdown_small"; - var oArrow = this.buttonNode.insertBefore(document.createElement('span'), - this.buttonNode.getElementsByTagName("div")[0]); - oArrow.className = "selectarrow"; - }; - - this.execute = function(editor) { - if (!panelBody) { - this.editor = editor; - oDoc = editor.useIframe ? document : editor.oDoc; - jpf.popup.setContent(this.uniqueId, this.createPanelBody()); - } - else - resetTableMorph(); - - //this.storeSelection(); - - editor.dispatchEvent("pluginexecute", {name: this.name, plugin: this}); - - this.editor.showPopup(this, this.uniqueId, this.buttonNode); - window.setTimeout(function() { - panelBody.style.width = (oTableCont.offsetWidth + 8) + "px"; - panelBody.style.height = (oTableCont.offsetWidth + 20) + "px"; - oTablePos = jpf.getAbsolutePosition(oTable); - }); - }; - - this.queryState = function(editor) { - return this.state; - }; - - this.submit = function(oSize) { - jpf.popup.forceHide(); - - if (oSize[0] < 0 || oSize[1] < 0) return; - - var i, j, k, l, aOut = ['<table border="0" width="50%">']; - for (i = 0, j = oSize[0]; i < j; i++) { - aOut.push('<tr>'); - for (k = 0, l = oSize[1]; k < l; k++) - aOut.push('<td>', (jpf.isIE ? '' : ' <br _jpf_placeholder="1" />'),'</td>'); - aOut.push('</tr>') - } - aOut.push('</table>') - - //this.restoreSelection(); - //if (jpf.isIE) - //this.editor.selection.set(); - this.editor.insertHTML(aOut.join(''), true); - this.editor.selection.collapse(false); - this.editor.$visualFocus(); - }; - - var bMorphing = false, oMorphCurrent, iMorphXCount, iMorphYCount; - function mouseDown(e) { - bMorphing = true; - oMorphCurrent = e.client; - iMorphXCount = iMorphYCount = 0; - //jpf.plane.show(panelBody, true); - document.onmousemove = function(e) { - if (!bMorphing) return; - e = new jpf.AbstractEvent(e || window.event); - // only morph the table when the mouse reaches beyond the table - if (e.client.x > oTablePos[0] + oTable.offsetWidth - || e.client.y > oTablePos[1] + oTable.offsetHeight) - morphTable(e); - e.stop(); - return false; - } - document.onmouseup = function(e) { - e = new jpf.AbstractEvent(e || window.event); - mouseUp.call(_self, e); - e.stop(); - return false; - } - //e.stop(); - return false; - } - - function mouseUp(e) { - if (bMorphing) { - bMorphing = false; - oMorphCurrent = document.onmousemove = document.onmouseup = null; - iMorphXCount = iMorphYCount = 0; - //jpf.plane.hide(); - } - mouseOver.call(this, e); - if (iCurrentX > 0 && iCurrentY > 0) - this.submit([iCurrentY, iCurrentX]); - e.stop(); - return false; - } - - function morphTable(e) { - oMorphCurrent = e.client; - iMorphXCount = (Math.floor((oMorphCurrent.x - oTablePos[0]) / 23) * 23) + 23; - if (iMorphXCount > oTable.offsetWidth) { - panelBody.style.width = (iMorphXCount + 10) + "px"; - oTableCont.style.width = (iMorphXCount + 4) + "px"; - oTable.style.width = (iMorphXCount) + "px"; - oTableSel.style.width = (iMorphXCount) + "px"; - } - iMorphYCount = (Math.floor((oMorphCurrent.y - oTablePos[1]) / 23) * 23) + 23; - if (iMorphYCount > oTable.offsetHeight) { - panelBody.style.height = (iMorphYCount + 20) + "px"; - oTableCont.style.height = (iMorphYCount + 4) + "px"; - oTable.style.height = (iMorphYCount) + "px"; - oTableSel.style.height = (iMorphYCount) + "px"; - } - } - - function resetTableMorph() { - oTableCont.style.width = oTableCont.style.height = "164px"; - oTableSel.style.width = oTableSel.style.height = "0px"; - oTable.style.width = oTable.style.height = "160px"; - } - - var sCurrentCaption = ""; - - function mouseOver(e) { - if (typeof oTablePos == "undefined") return; - iCurrentX = Math.ceil((e.page.x - oTablePos[0]) / 23); - iCurrentY = Math.ceil((e.page.y - oTablePos[1]) / 23); - if (iCurrentX > 0 && iCurrentY > 0) { - oTableSel.style.width = Math.min((iCurrentX * 23), oTable.offsetWidth) + "px"; - oTableSel.style.height = Math.min((iCurrentY * 23), oTable.offsetHeight) + "px"; - var sCaption = iCurrentY + " x " + iCurrentX + " " - + _self.editor.translate('table_noun', true); - if (sCurrentCaption != sCaption) - oStatus.innerHTML = sCurrentCaption = sCaption; - } - else - iCurrentX = iCurrentY = 0; - } - - function mouseOut(e) { - if (bMorphing) return; - oTableSel.style.width = oTableSel.style.height = "0px"; - iCurrentX = iCurrentY = 0; - oStatus.innerHTML = sCurrentCaption = _self.editor.translate('cancel'); - } - - function statusClick(e) { - mouseOut.call(this, e); - jpf.popup.forceHide(); - } - - this.createPanelBody = function() { - panelBody = document.body.appendChild(document.createElement('div')); - panelBody.className = "editor_popup editor_tablepopup"; - panelBody.style.display = "none"; - - var idTableCont = 'editor_' + this.uniqueId + '_tablecont'; - var idTableSel = 'editor_' + this.uniqueId + '_tablesel'; - var idTable = 'editor_' + this.uniqueId + '_table'; - var idStatus = 'editor_' + this.uniqueId + '_table_status'; - panelBody.innerHTML = - '<div id="' + idTableCont + '" class="editor_paneltable_cont">\ - <div id="' + idTableSel + '" class="editor_paneltable_sel"></div>\ - <div id="' + idTable + '" class="editor_paneltable"></div>\ - </div>\ - <div id="' + idStatus + '" class="editor_paneltablecancel">' - + this.editor.translate('cancel') + '</div>'; - - oTableCont = document.getElementById(idTableCont); - oTableSel = document.getElementById(idTableSel); - oTable = document.getElementById(idTable); - oTable.onmousedown = mouseDown.bindWithEvent(this); - oTable.onmouseup = mouseUp.bindWithEvent(this); - oTable.onmousemove = mouseOver.bindWithEvent(this); - oTable.onmouseout = mouseOut.bindWithEvent(this); - oStatus = document.getElementById(idStatus); - oStatus.onmousedown = statusClick.bindWithEvent(this); - panelBody.onselectstart = function() { return false; }; - resetTableMorph(); - - return panelBody; - }; - - this.destroy = function() { - //oTableCont, oTableSel, oTable, oStatus, oTablePos, oDoc - panelBody = oTableCont = oTableSel = oTable = oStatus = oTablePos - = oDoc = null; - delete panelBody; - delete oTableCont; - delete oTableSel; - delete oTable; - delete oStatus; - delete oTablePos; - delete oDoc; - }; -}); - -jpf.editor.plugin('tablewizard', function() { - this.name = 'tablewizard'; - this.icon = 'tablewizard'; - this.type = jpf.editor.CONTEXTPANEL; - this.hook = 'context'; - this.state = jpf.editor.OFF; - this.oTable = null; - this.oRow = null; - this.oCell = null; - - var activeNode, oDoc, _self = this; - - this.execute = function(editor, e) { - if (this.queryState(editor) != jpf.editor.ON) - return; - // get the active table, row and cell nodes: - this.oTable = this.oRow = this.oCell = null; - while (activeNode.tagName != "TABLE") { - if (activeNode.tagName == "TD") - this.oCell = activeNode; - else if (activeNode.tagName == "TR") - this.oRow = activeNode; - activeNode = activeNode.parentNode; - } - this.oTable = activeNode; - - if (!this.editor) - this.editor = editor; - if (!jpf.editor.oMenu) - this.createContextMenu(); - if (!oDoc) - oDoc = editor.useIframe ? document : editor.oDoc; - jpf.editor.oMenu.tablePlugin = this; - - var pos = jpf.getAbsolutePosition(editor.iframe); - if (!e.client) - e = new jpf.AbstractEvent(e); - jpf.editor.oMenu.display(e.client.x + pos[0], e.client.y + pos[1], true); - - e.stop(); - - editor.dispatchEvent("pluginexecute", {name: this.name, plugin: this}); - - return false; - }; - - this.queryState = function(editor) { - var oNode = editor.selection.getSelectedNode(); - if (oNode.tagName == "TABLE" || oNode.tagName == "TBODY" - || oNode.tagName == "TR" || oNode.tagName == "TD") { - activeNode = oNode; - return jpf.editor.ON; - } - - return jpf.editor.OFF; - }; - - function addRows(td_elm, tr_elm, rowspan) { - // Add rows - td_elm.rowSpan = 1; - var trNext = nextElm(tr_elm, ["TR"]); - for (var i = 1; i < rowspan && trNext; i++) { - var newTD = oDoc.createElement("td"); - if (!jpf.isIE) - newTD.innerHTML = '<br mce_bogus="1"/>'; - if (jpf.isIE) - trNext.insertBefore(newTD, trNext.cells(td_elm.cellIndex)); - else - trNext.insertBefore(newTD, trNext.cells[td_elm.cellIndex]); - trNext = nextElm(trNext, ["TR"]); - } - } - - function getColRowSpan(td) { - var colspan = td.getAttribute("colspan") || ""; - var rowspan = td.getAttribute("rowspan") || ""; - - return { - colspan : colspan == "" ? 1 : parseInt(colspan), - rowspan : rowspan == "" ? 1 : parseInt(rowspan) - }; - } - - function getTableGrid(table) { - var grid = [], rows = table.rows, x, y, td, sd, xstart, x2, y2; - - for (y = 0; y < rows.length; y++) { - for (x = 0; x < rows[y].cells.length; x++) { - td = rows[y].cells[x]; - sd = getColRowSpan(td); - - // All ready filled - for (xstart = x; grid[y] && grid[y][xstart]; xstart++){} - - // Fill box - for (y2 = y; y2 < y + sd.rowspan; y2++) { - if (!grid[y2]) - grid[y2] = []; - - for (x2 = xstart; x2 < xstart + sd.colspan; x2++) - grid[y2][x2] = td; - } - } - } - - return grid; - } - - function getCellPos(grid, td) { - for (var i = 0; i < grid.length; i++) { - for (var j = 0; j < grid[i].length; j++) { - if (grid[i][j] == td) - return {cellindex : j, rowindex : i}; - } - } - - return null; - } - - function getCell(grid, row, col) { - if (grid[row] && grid[row][col]) - return grid[row][col]; - return null; - } - - function nextElm(node, names) { - while ((node = node.nextSibling) != null) { - for (var i = 0; i < names.length; i++) { - if (node.nodeName.toLowerCase() == names[i].toLowerCase()) - return node; - } - } - return null; - } - - this.createContextMenu = function(){ - var idMenu = "editor_" + this.uniqueId + "_menu"; - this.appendJmlNode('\ - <j:menu xmlns:j="' + jpf.ns.jml + '" id="' + idMenu + '">\ - <j:item value="rowbefore">Insert row before</j:item>\ - <j:item value="rowbefore">Insert row after</j:item>\ - <j:item value="deleterow">Delete row</j:item>\ - <j:divider />\ - <j:item value="colbefore">Insert column before</j:item>\ - <j:item value="colafter">Insert column after</j:item>\ - <j:item value="deletecol">Delete column</j:item>\ - <j:divider />\ - <j:item value="splitcells">Split merged table cells</j:item>\ - <j:item value="mergecells">Merge table cells</j:item>\ - </j:menu>', document.body); - //nodes disabled: - // <j:divider />\ - // <j:item value="rowprops">Table row properties</j:item>\ - // <j:item value="colprops">Table column properties</j:item>\ - var oMenu = jpf.editor.oMenu = self[idMenu]; - oMenu.addEventListener("onitemclick", function(e){ - if (this.tablePlugin != _self) - return; - - var oRow, i, j, idx = 0; - - if (_self.oCell) { - for (i = 0, j = _self.oRow.cells.length; i < j; i++) - if (_self.oRow.cells[i] == _self.oCell) - idx = i; - } - - _self.editor.selection.set(); - - switch (e.value) { - case "rowbefore": - oRow = oDoc.createElement('tr'); - _self.oRow.parentNode.insertBefore(oRow, _self.oRow); - for (i = 0, j = _self.oRow.cells.length; i < j; i++) - oRow.insertCell(0); - break; - case "rowafter": - oRow = oDoc.createElement('tr'); - _self.oRow.parentNode.insertBefore(oRow, _self.oRow.nextSibling); - for (i = 0, j = _self.oRow.cells.length; i < j; i++) - oRow.insertCell(0); - break; - case "deleterow": - if (!_self.oRow || !_self.oRow.parentNode) return; - _self.oRow.parentNode.removeChild(_self.oRow); - break; - case "colbefore": - if (!_self.oCell) return; - for (i = 0, j = _self.oTable.rows.length; i < j; i++) - _self.oTable.rows[i].insertCell(idx); - break; - case "colafter": - if (!_self.oCell) return; - idx += 1; - for (i = 0, j = _self.oTable.rows.length; i < j; i++) - _self.oTable.rows[i].insertCell(idx); - break; - case "deletecol": - if (!_self.oCell || _self.oTable.rows[0].cells.length == 1) - return; - //@todo: fix this to understand cell spanning - for (i = 0, j = _self.oTable.rows.length; i < j; i++) { - if (_self.oTable.rows[i].cells[idx]) - _self.oTable.rows[i].deleteCell(idx); - } - break; - case "splitcells": - if (!_self.oRow || !_self.oCell) - return true; - - var spandata = getColRowSpan(_self.oCell); - - var colspan = spandata["colspan"]; - var rowspan = spandata["rowspan"]; - - // Needs splitting - if (colspan > 1 || rowspan > 1) { - // Generate cols - _self.oCol.colSpan = 1; - for (i = 1; i < colspan; i++) { - var newTD = oDoc.createElement("td"); - if (!jpf.isIE) - newTD.innerHTML = '<br _jpf_placeholder="1"/>'; - - _self.oRow.insertBefore(newTD, nextElm(_self.oCell, ['TD','TH'])); - - if (rowspan > 1) - addRows(newTD, _self.oRow, rowspan); - } - - addRows(_self.oCell, _self.oRow, rowspan); - } - break; - case "mergecells": - var rows = [], cells = [], - oSel = _self.editor.selection.get(), - grid = getTableGrid(_self.oTable), - oCellPos, aRows, aRowCells, aBrs, oTd, k; - - if (jpf.isIE || oSel.rangeCount == 1) { - var numRows = 1; - var numCols = 1; - oCellPos = getCellPos(grid, _self.oCell); - - // Get rows and cells - aRows = _self.oTable.rows; - for (i = oCellPos.rowindex; i < grid.length; i++) { - aRowCells = []; - - for (j = oCellPos.cellindex; j < grid[i].length; j++) { - oTd = getCell(grid, i, j); - - if (oTd && !rows.contains(oTd) && !aRowCells.contains(oTd)) { - var cp = getCellPos(grid, oTd); - // Within range - if (cp.cellindex < oCellPos.cellindex + numCols - && cp.rowindex < oCellPos.rowindex + numRows) - aRowCells[aRowCells.length] = oTd; - } - } - if (aRowCells.length > 0) - rows[rows.length] = aRowCells; - - oTd = getCell(grid, oCellPos.rowindex, oCellPos.cellindex); - aBrs = oTd.getElementsByTagName('br'); - if (aBrs.length > 1) { - for (j = aBrs.length; j >= 1; j--) { - if (aBrs[j].getAttribute('_jpf_placeholder')) - aBrs[j].parentNode.removeChild(aBrs[j]); - } - } - } - } - else { - var x1 = -1, y1 = -1, x2, y2; - - // Only one cell selected, whats the point? - if (oSel.rangeCount < 2) - return true; - - // Get all selected cells - for (i = 0; i < oSel.rangeCount; i++) { - var rng = oSel.getRangeAt(i); - _self.oCell = rng.startContainer.childNodes[rng.startOffset]; - if (!_self.oCell) - break; - if (_self.oCell.nodeName == "TD" || _self.oCell.nodeName == "TH") - cells.push(_self.oCell); - } - - // Get rows and cells - aRows = _self.oTable.rows; - for (i = 0; i < aRows.length; i++) { - aRowCells = []; - for (j = 0; j < aRows[i].cells.length; j++) { - oTd = aRows[i].cells[j]; - for (k = 0; k < cells.length; k++) { - if (oTd != cells[k]) continue; - aRowCells.push(oTd); - } - } - if (aRowCells.length > 0) - rows.push(aRowCells); - } - - // Find selected cells in grid and box - for (i = 0; i < grid.length; i++) { - for (j = 0; j < grid[i].length; j++) { - grid[i][j]._selected = false; - for (k = 0; k < cells.length; k++) { - if (grid[i][j] != cells[k]) continue; - // Get start pos - if (x1 == -1) { - x1 = j; - y1 = i; - } - // Get end pos - x2 = j; - y2 = i; - grid[i][j]._selected = true; - } - } - } - - // Is there gaps, if so deny - for (i = y1; i <= y2; i++) { - for (j = x1; j <= x2; j++) { - if (!grid[i][j]._selected) { - alert("Invalid selection for merge."); - return true; - } - } - } - } - - // Validate selection and get total rowspan and colspan - var rowSpan = 1, colSpan = 1; - - // Validate horizontal and get total colspan - var sd, lastRowSpan = -1; - for (i = 0; i < rows.length; i++) { - var rowColSpan = 0; - for (j = 0, k = rows[i].length; j < k; j++) { - sd = getColRowSpan(rows[i][j]); - rowColSpan += sd.colspan; - if (lastRowSpan != -1 && sd.rowspan != lastRowSpan) { - alert("Invalid selection for merge."); - return true; - } - lastRowSpan = sd.rowspan; - } - if (rowColSpan > colSpan) - colSpan = rowColSpan; - lastRowSpan = -1; - } - - // Validate vertical and get total rowspan - var lastColSpan = -1; - for (j = 0; j < rows[0].length; j++) { - var colRowSpan = 0; - for (i = 0; i < rows.length; i++) { - sd = getColRowSpan(rows[i][j]); - colRowSpan += sd.rowspan; - if (lastColSpan != -1 && sd.colspan != lastColSpan) { - alert("Invalid selection for merge."); - return true; - } - lastColSpan = sd.colspan; - } - if (colRowSpan > rowSpan) - rowSpan = colRowSpan; - lastColSpan = -1; - } - - // Setup td - _self.oCell = rows[0][0]; - _self.oCell.rowSpan = rowSpan; - _self.oCell.colSpan = colSpan; - - // Merge cells - for (i = 0; i < rows.length; i++) { - for (j = 0; j < rows[i].length; j++) { - var html = rows[i][j].innerHTML; - var chk = html.replace(/[ \t\r\n]/g, ""); - if (chk != "<br/>" && chk != '<br _jpf_placeholder="1"/>' - && (j + i > 0)) - _self.oCell.innerHTML += html; - - // Not current cell - if (rows[i][j] == _self.oCell && rows[i][j]._deleted) - continue; - oCellPos = getCellPos(grid, rows[i][j]); - var tr = rows[i][j].parentNode; - - tr.removeChild(rows[i][j]); - rows[i][j]._deleted = true; - - if (tr.hasChildNodes()) continue; - // Empty TR, remove it - tr.parentNode.removeChild(tr); - - var cellElm, lastCell = null; - for (k = 0; cellElm = getCell(grid, oCellPos.rowindex, k); k++) { - if (cellElm != lastCell && cellElm.rowSpan > 1) - cellElm.rowSpan--; - lastCell = cellElm; - } - if (_self.oCell.rowSpan > 1) - _self.oCell.rowSpan--; - } - } - - // Remove all but one bogus br - aBrs = _self.oCell.getElementsByTagName('br'); - if (aBrs.length > 1) { - for (i = aBrs.length; i >= 1; i--) { - if (aBrs[i] && aBrs[i].getAttribute('_jpf_placeholder')) - aBrs[i].parentNode.removeChild(aBrs[i]); - } - } - break; - } - - _self.editor.change(_self.editor.getValue()); - }); - }; -}); - - - -/*FILEHEAD(/var/lib/jpf/src/elements/editor/plugins/code.js)SIZE(-1077090856)TIME(1238933682)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -jpf.editor.plugin('code', function() { - this.name = 'code'; - this.icon = 'code'; - this.type = jpf.editor.TOOLBARITEM; - this.subType = jpf.editor.TOOLBARBUTTON; - this.hook = 'ontoolbar'; - this.keyBinding = 'ctrl+shift+h'; - this.state = jpf.editor.OFF; - this.noDisable = true; - this.regex = null; - - var oPreview, protectedData, lastLoaded, _self = this; - - this.execute = function(editor) { - //this.buttonNode.onclick(editor.mimicEvent()); - if (!oPreview) - this.drawPreview(editor); - - if (oPreview.style.display == "none") { - // remember the selection for IE - editor.selection.cache(); - - this.update(editor); - - editor.plugins.active = this; - // disable the editor... - editor.setProperty('state', jpf.editor.DISABLED); - - // show the textarea and position it correctly... - this.setSize(editor); - oPreview.style.display = ""; - - oPreview.focus(); - } - else { - editor.plugins.active = null; - - oPreview.style.display = "none"; - editor.setProperty('state', jpf.editor.OFF); - - propagateChange(); - - setTimeout(function() { - editor.selection.set(); - editor.$visualFocus(); - }); - } - editor.notify('code', this.queryState(editor)); - - editor.dispatchEvent("pluginexecute", {name: this.name, plugin: this}); - }; - - this.update = function(editor, sHtml) { - if (changeTimer) { - lastLoaded = sHtml; - return; - } - // update the contents of the (hidden) textarea - oPreview.value = format.call(this, sHtml - ? editor.exportHtml(sHtml) - : (lastLoaded = editor.getValue())); - }; - - this.getValue = function() { - return oPreview.value; - }; - - function propagateChange() { - if (lastLoaded == oPreview.value) return false; - var html = _self.editor.exportHtml(oPreview.value - .replace(/<\/p>/gi, "</p><p></p>") - .replace(/\n/g, '')); - - try{ - jpf.getXml('<source>' + html.replace(/&.{3,5};/g, "") + '</source>'); - } - catch(e){ - if (confirm("Er zit een fout in de html. Klik op OK om deze \ - te corrigeren, of op Cancel om door te gaan")){ - //@todo mike: finish this - return false; - } - } - - if (_self.editor.$value.replace(/[\r\n]/g, "") == html.replace(/[\r\n]/g, "")) { - _self.editor.$propHandlers["value"].call(_self.editor, html); - } - else - _self.editor.change(html); - - return true; - } - - var changeTimer = null; - - function resumeChangeTimer() { - if (!_self.editor.realtime || changeTimer !== null) return; - changeTimer = setTimeout(function() { - clearTimeout(changeTimer); - _self.editor.change(oPreview.value); - changeTimer = null; - }, 200); - } - - function onKeydown(e) { - e = e || window.event; - var code = e.which || e.keyCode; - if (!e.ctrlKey && !e.altKey && (code < 112 || code > 122) - && (code < 33 && code > 31 || code > 42 || code == 8 || code == 13)) { - resumeChangeTimer(); - } - } - - this.drawPreview = function(editor) { - this.editor = editor; - - oPreview = editor.oExt.appendChild(document.createElement('textarea')); - oPreview.rows = 15; - oPreview.cols = 10; - // make selections in IE possible. - if (jpf.isIE) - oPreview.onselectstart = function(e) { - e = e || window.event; - e.cancelBubble = true; - }; - oPreview.onkeydown = onKeydown; - this.setSize(editor); - oPreview.style.display = "none"; - jpf.sanitizeTextbox(oPreview); - } - - this.setSize = function(editor) { - if (!oPreview || !editor) return; - oPreview.style.width = editor.oExt.offsetWidth - 2 + "px"; - oPreview.style.height = editor.oExt.offsetHeight - editor.oToolbar.offsetHeight - 4 + "px"; - }; - - function protect(outer, opener, data, closer) { - return opener + "___JPFpd___" + protectedData.push(data) + closer; - } - - function format(sHtml) { - if (!this.regex) - setupRegex.call(this); - protectedData = []; - - var sFmt = sHtml.replace(this.regex.protectedTags, protect); - // Line breaks. - sFmt = sFmt.replace(this.regex.blocksOpener, '\n$&') - .replace(this.regex.blocksCloser, '$&\n') - .replace(this.regex.newLineTags, '$&\n') - .replace(this.regex.mainTags, '\n$&\n'); - - // Indentation. - var i, j, - sIdt = "", - asLines = sFmt.split(this.regex.lineSplitter); - sFmt = ""; - for (i = 0, j = asLines.length; i < j; i++) { - var sLn = asLines[i]; - if (sLn.length == 0) - continue ; - if (this.regex.decreaseIndent.test(sLn)) - sIdt = sIdt.replace(this.regex.formatIndentatorRemove, ''); - sFmt += sIdt + sLn + "\n"; - if (this.regex.increaseIndent.test(sLn)) - sIdt += ' '; - } - - // Now we put back the protected data. - for (i = 0, j = protectedData.length; i < j; i++) { - var oRegex = new RegExp('___JPFpd___' + i); - sFmt = sFmt.replace(oRegex, protectedData[i].replace(/\$/g, '$$$$')); - } - - return sFmt.trim(); - } - - function setupRegex() { - // Regex for line breaks. - this.regex = { - blocksOpener : /\<(P|DIV|H1|H2|H3|H4|H5|H6|ADDRESS|PRE|OL|UL|LI|TITLE|META|LINK|BASE|SCRIPT|LINK|TD|TH|AREA|OPTION)[^\>]*\>/gi, - blocksCloser : /\<\/(P|DIV|H1|H2|H3|H4|H5|H6|ADDRESS|PRE|OL|UL|LI|TITLE|META|LINK|BASE|SCRIPT|LINK|TD|TH|AREA|OPTION)[^\>]*\>/gi, - newLineTags : /\<(BR|HR)[^\>]*\>/gi, - mainTags : /\<\/?(HTML|HEAD|BODY|FORM|TABLE|TBODY|THEAD|TR)[^\>]*\>/gi, - lineSplitter : /\s*\n+\s*/g, - // Regex for indentation. - increaseIndent: /^\<(HTML|HEAD|BODY|FORM|TABLE|TBODY|THEAD|TR|UL|OL)[ \/\>]/i, - decreaseIndent: /^\<\/(HTML|HEAD|BODY|FORM|TABLE|TBODY|THEAD|TR|UL|OL)[ \>]/i, - protectedTags : /(<PRE[^>]*>)([\s\S]*?)(<\/PRE>)/gi, - formatIndentatorRemove: /^ / - }; - } - - this.queryState = function(editor) { - if (editor.plugins.active == this) - return jpf.editor.SELECTED; - return jpf.editor.OFF; - }; - - this.destroy = function() { - oPreview = this.regex = null; - delete oPreview; - delete this.regex; - }; -}); - - - -/*FILEHEAD(/var/lib/jpf/src/elements/editor/plugins/anchor.js)SIZE(-1077090856)TIME(1238933682)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -jpf.editor.plugin('anchor', function() { - this.name = 'anchor'; - this.icon = 'anchor'; - this.type = jpf.editor.TOOLBARITEM; - this.subType = jpf.editor.TOOLBARPANEL; - this.hook = 'ontoolbar'; - this.keyBinding = 'ctrl+shift+a'; - this.state = jpf.editor.OFF; - - var panelBody; - - this.init = function(editor, btn) { - this.buttonNode.className = this.buttonNode.className + " dropdown_small"; - var oArrow = this.buttonNode.insertBefore(document.createElement('span'), - this.buttonNode.getElementsByTagName("div")[0]); - oArrow.className = "selectarrow"; - }; - - this.execute = function(editor) { - if (!panelBody) { - this.editor = editor; - jpf.popup.setContent(this.uniqueId, this.createPanelBody()); - } - - editor.dispatchEvent("pluginexecute", {name: this.name, plugin: this}); - - this.editor.showPopup(this, this.uniqueId, this.buttonNode, 218, 47); - if (panelBody.style.visibility == "hidden") - panelBody.style.visibility = "visible"; - var _self = this; - setTimeout(function() { - _self.oName.focus(); - }); - //return button id, icon and action: - return { - id: this.name, - action: null - }; - }; - - this.queryState = function(editor) { - // @todo: for webkit compat, we need to insert images instead of inline an elements - var oNode = editor.selection.getSelectedNode(); - if (oNode.tagName == "A" && oNode.getAttribute('name')) - return jpf.editor.ON; - - return this.state; - }; - - this.submit = function(e) { - jpf.popup.forceHide(); - - if (!this.oName.value) return; - - //this.storeSelection(); - this.editor.insertHTML('<a name="' + this.oName.value + '" class="itemAnchor" />'); - //this.restoreSelection(); - this.editor.selection.collapse(false); - }; - - this.createPanelBody = function() { - panelBody = document.body.appendChild(document.createElement('div')); - panelBody.className = "editor_popup"; - panelBody.style.display = "none"; - var idName = 'editor_' + this.uniqueId + '_anchor_url'; - var idButton = 'editor_' + this.uniqueId + '_anchor_button'; - panelBody.innerHTML = - '<div class="editor_panelrow editor_panelrowinput">\ - <label for="' + idName + '">Anchor name</label>\ - <input type="text" id="' + idName + '" name="' + idName + '" class="editor_input" value="" />\ - </div>\ - <div id="' + idButton + '" class="editor_panelrow editor_panelrowbtns"></div>'; - - this.appendJmlNode( - '<j:toolbar xmlns:j="' + jpf.ns.jml + '"><j:bar>\ - <j:button caption="Insert" \ - onclick="jpf.lookup(' + this.uniqueId + ').submit(event)" />\ - </j:bar></j:toolbar>', - document.getElementById(idButton)); - this.oName = document.getElementById(idName); - jpf.sanitizeTextbox(this.oName); - - return panelBody; - }; - - this.destroy = function() { - panelBody = this.oName = null; - delete panelBody; - delete this.oName; - }; -}); - - - -/*FILEHEAD(/var/lib/jpf/src/elements/editor/plugins/image.js)SIZE(-1077090856)TIME(1238933682)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -jpf.editor.plugin('image', function(){ - this.name = 'image'; - this.icon = 'image'; - this.type = jpf.editor.TOOLBARITEM; - this.subType = jpf.editor.TOOLBARPANEL; - this.hook = 'ontoolbar'; - this.keyBinding = 'ctrl+alt+i'; - this.state = jpf.editor.OFF; - - var panelBody; - - this.init = function(editor) { - this.buttonNode.className = this.buttonNode.className + " dropdown_small"; - var oArrow = this.buttonNode.insertBefore(document.createElement('span'), - this.buttonNode.getElementsByTagName("div")[0]); - oArrow.className = "selectarrow"; - }; - - this.execute = function(editor) { - if (!panelBody) { - this.editor = editor; - jpf.popup.setContent(this.uniqueId, this.createPanelBody()); - } - - editor.dispatchEvent("pluginexecute", {name: this.name, plugin: this}); - - // @todo: auto-fill input with currently selected image url - this.editor.showPopup(this, this.uniqueId, this.buttonNode, 218, 47); - var _self = this; - setTimeout(function() { - _self.oUrl.focus(); - }); - //return button id, icon and action: - return { - id: this.name, - action: null - }; - }; - - this.queryState = function(editor) { - return this.state; - }; - - this.submit = function(e) { - var sUrl = this.oUrl.value; - if (sUrl) { - jpf.popup.forceHide(); - var oUrl = new jpf.url(sUrl); - if (!oUrl.protocol || !oUrl.host || !oUrl.file) - alert("Please enter a valid URL"); - else - this.editor.insertHTML('<img src="' + sUrl + '" border="0" />', true); - } - }; - - this.createPanelBody = function() { - panelBody = document.body.appendChild(document.createElement('div')); - panelBody.className = "editor_popup"; - panelBody.style.display = "none"; - var idUrl = 'editor_' + this.uniqueId + '_input'; - var idBtns = 'editor_' + this.uniqueId + '_btns'; - panelBody.innerHTML = - '<div class="editor_panelrow editor_panelrowinput">\ - <label for="' + idUrl + '">Image URL</label>\ - <input type="text" id="' + idUrl + '" class="editor_input" name="' + idUrl + '" value="" />\ - </div>\ - <div id="' + idBtns + '" class="editor_panelrow editor_panelrowbtns"></div>'; - this.oUrl = document.getElementById(idUrl); - this.appendJmlNode( - '<j:toolbar xmlns:j="' + jpf.ns.jml + '"><j:bar>\ - <j:button caption="Insert"\ - onclick="jpf.lookup(' + this.uniqueId + ').submit(event)" />\ - </j:bar></j:toolbar>', - document.getElementById(idBtns)); - - if (jpf.hasFocusBug) { - jpf.sanitizeTextbox(this.oUrl); - this.oUrl.onselectstart = function(e) { - e = e || window.event; - e.cancelBubble = true; - }; - } - - return panelBody; - }; - - this.destroy = function() { - panelBody = this.oUrl = null; - delete panelBody; - delete this.oUrl; - }; -}); - -jpf.editor.plugin('imagespecial', function() { - this.name = 'imagespecial'; - this.icon = 'image'; - this.type = jpf.editor.TOOLBARITEM; - this.subType = jpf.editor.TOOLBARBUTTON; - this.hook = 'ontoolbar'; - this.keyBinding = 'ctrl+alt+j'; - this.state = jpf.editor.OFF; - - var winHandle; - - this.execute = function(editor) { - if (!winHandle) { - // get window handle from editor JML attribute - var s = (editor.$jml.getAttribute('imagewindow') || "").trim(); - if (s) - winHandle = self[s]; - } - - if (winHandle && winHandle.show) - winHandle.show(); - - editor.dispatchEvent("pluginexecute", {name: this.name, plugin: this}); - }; - - this.queryState = function(editor) { - return this.state; - }; -}); - - - -/*FILEHEAD(/var/lib/jpf/src/elements/editor/plugins/emotions.js)SIZE(-1077090856)TIME(1238933682)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -jpf.editor.plugin('emotions', function() { - this.name = 'emotions'; - this.icon = 'emotions'; - this.type = jpf.editor.TOOLBARITEM; - this.subType = jpf.editor.TOOLBARPANEL; - this.hook = 'ontoolbar'; - this.buttonNode = null; - this.state = jpf.editor.OFF; - this.colspan = 4; - this.emotions = []; - - var panelBody; - - this.init = function(editor, btn) { - this.buttonNode.className = this.buttonNode.className + " dropdown_small"; - var oArrow = this.buttonNode.insertBefore(document.createElement('span'), - this.buttonNode.getElementsByTagName("div")[0]); - oArrow.className = "selectarrow"; - }; - - this.execute = function(editor) { - if (!panelBody) { - this.editor = editor; - this.emotionsPath = editor.$getOption("emotions", "path"); - - // parse smiley images, or 'emotions' - var i, node, oNode = editor.$getOption('emotions'); - for (i = 0; i < oNode.childNodes.length; i++) { - node = oNode.childNodes[i]; - if (node.nodeType == 3 || node.nodeType == 4) - this.emotions = node.nodeValue.splitSafe(","); - } - - jpf.popup.setContent(this.uniqueId, this.createPanelBody()); - } - - editor.dispatchEvent("pluginexecute", {name: this.name, plugin: this}); - - this.editor.showPopup(this, this.uniqueId, this.buttonNode, 123, 110); - //return button id, icon and action: - return { - id: this.name, - action: null - }; - }; - - this.queryState = function() { - return this.state; - }; - - this.submit = function(e) { - e = new jpf.AbstractEvent(e || window.event); - this.editor.$visualFocus(); - var icon = e.target.getAttribute('rel'); - // @todo still iffy... - if (!icon || icon == null) - icon = e.target.parentNode.getAttribute('rel'); - if (!icon) return; - jpf.popup.forceHide(); - this.editor.insertHTML('<img src="' + this.emotionsPath - + '/smiley-' + icon + '.gif' + '" alt="" border="0" />', true); - //this.restoreSelection(); - }; - - this.createPanelBody = function() { - panelBody = document.body.appendChild(document.createElement('div')); - panelBody.className = "editor_popup"; - panelBody.style.display = "none"; - var aHtml = []; - var emotions = this.emotions; - var path = this.emotionsPath; - var rowLen = this.colspan - 1; - for (var i = 0; i < emotions.length; i++) { - if (i % this.colspan == 0) - aHtml.push('<div class="editor_panelrow">'); - aHtml.push('<a class="editor_panelcell editor_largestcell" rel="', - emotions[i], '" href="javascript:;" onmousedown="jpf.lookup(', - this.uniqueId, ').submit(event);">\ - <img border="0" src="', path, '/smiley-', emotions[i], '.gif" />\ - </a>'); - if (i % this.colspan == rowLen) - aHtml.push('</div>'); - } - panelBody.innerHTML = aHtml.join(''); - - return panelBody; - }; - - this.destroy = function() { - panelBody = null; - delete panelBody; - }; -}); - - - -/*FILEHEAD(/var/lib/jpf/src/elements/editor/plugins/list.js)SIZE(-1077090856)TIME(1238933682)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -jpf.editor.listPlugin = function(sName) { - this.name = sName; - this.icon = sName; - this.type = jpf.editor.TOOLBARITEM; - this.subType = jpf.editor.TOOLBARBUTTON; - this.hook = 'ontoolbar'; - this.keyBinding = sName == "bullist" ? "ctrl+shift+u" : "ctrl+shift+o"; - this.state = jpf.editor.OFF; - - var emptyRegex = jpf.isIE - ? /^( )?<DIV[^>]*_jpf_placeholder(="1"> )?<\/DIV>$/gi - : /^( )?<BR\/?>$/gi; - - this.execute = function(editor) { - editor.executeCommand(this.name == "bullist" - ? 'InsertUnorderedList' - : 'InsertOrderedList'); - - this.correctLists(editor); - editor.$visualFocus(); - - editor.dispatchEvent("pluginexecute", {name: this.name, plugin: this}); - }; - - function moveListItems(from, to) { - var i, oNode, oLastNode, - listNode = (this.name == "bullist") ? "OL" : "UL"; - for (i = from.childNodes.length; i >= 0; i--) { - oNode = from.childNodes[i]; - if (!oNode) continue; - if (oNode.tagName == listNode) break; - if (!oLastNode) - to.appendChild(oNode); - else - to.insertBefore(oNode, oLastNode); - oLastNode = oNode; - } - from.parentNode.removeChild(from); - } - - function getEmptyLi(oParent) { - if (!oParent || oParent.nodeType != 1) return; - var sHtml, aNodes = oParent.getElementsByTagName('li'); - for (var i = 0, j = aNodes.length; i < j; i++) { - sHtml = aNodes[i].innerHTML.trim(); - if (sHtml == "" || sHtml == " " || sHtml.match(emptyRegex)) - return aNodes[i]; - } - return null; - } - - this.correctLists = function(editor) { - editor.selection.set(); - - var oNode = editor.selection.getSelectedNode(); - //window.console.log('correcting lists0: ', oNode); - //window.console.dir(editor.selection.getRange()); - if (oNode.tagName != "LI") { - oNode = getEmptyLi(oNode); - if (!oNode || oNode.tagName != "LI") - return false; - } - var oParent = oNode.parentNode, - oSiblingP = oNode.parentNode.previousSibling, - oHasBr = null; - if (!oSiblingP) return false - if (oSiblingP && oSiblingP.tagName == "BR") { - oHasBr = oSiblingP; - oSiblingP = oSiblingP.previousSibling; - } - var oSibling = (oSiblingP && oSiblingP.tagName == oParent.tagName) - ? oSiblingP - : null; - if (!oSibling) return; - if (oHasBr) - oParent.removeChild(oHasBr); - - moveListItems(oParent, oSibling); - - //while (oSibling.nextSibling && oSibling.tagName == oSibling.nextSibling.tagName) - // moveListItems(oSibling.nextSibling, oSibling); - - editor.selection.selectNode(oNode); - if (!jpf.isIE) - editor.selection.getRange().setStart(oNode, 0); - editor.selection.collapse(!jpf.isIE); - editor.$visualFocus(); - return true; - }; - - this.correctIndentation = function(editor, dir) { - //this.correctLists(editor); - editor.executeCommand(dir); - this.correctLists(editor); - }; - - this.queryState = function(editor) { - var state = editor.getCommandState(this.name == "bullist" - ? 'InsertUnorderedList' - : 'InsertOrderedList'); - if (state == jpf.editor.DISABLED) - return jpf.editor.OFF; - return state; - }; -}; - -jpf.editor.plugin('bullist', jpf.editor.listPlugin); -jpf.editor.plugin('numlist', jpf.editor.listPlugin); - - - -/*FILEHEAD(/var/lib/jpf/src/elements/editor/plugins/search.js)SIZE(-1077090856)TIME(1238933682)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -jpf.editor.searchPlugin = function(sName) { - this.name = sName; - this.icon = sName; - this.type = jpf.editor.TOOLBARITEM; - this.subType = jpf.editor.TOOLBARPANEL; - this.hook = 'ontoolbar'; - this.keyBinding = this.name == "search" ? 'ctrl+f' : 'ctrl+shift+f'; - this.state = jpf.editor.OFF; - - var panelBody; - - this.init = function(editor, btn) { - this.buttonNode.className = this.buttonNode.className + " dropdown_small"; - var oArrow = this.buttonNode.insertBefore(document.createElement('span'), - this.buttonNode.getElementsByTagName("div")[0]); - oArrow.className = "selectarrow"; - }; - - this.execute = function(editor) { - if (!panelBody) { - this.editor = editor; - jpf.popup.setContent(this.uniqueId, this.createPanelBody()); - } - - editor.dispatchEvent("pluginexecute", {name: this.name, plugin: this}); - - this.editor.showPopup(this, this.uniqueId, this.buttonNode, 218, - this.name == "search" ? 71 : 95); - // prefill search box with selected text - this.oSearch.value = this.editor.selection.getContent(); - var _self = this; - setTimeout(function() { - _self.oSearch.focus(); - }); - //return button id, icon and action: - - return { - id: this.name, - action: null - }; - }; - - this.queryState = function(editor) { - return this.state; - }; - - this.submit = function(e) { - //e = new jpf.AbstractEvent(e || window.event); - var val = this.oSearch.value, bMatchCase = this.oCase.checked, flag = 0; - if (!val) - return; - - if (jpf.isIE) - this.editor.selection.set(); - //this.editor.oDoc.execCommand('SelectAll'); - //this.editor.executeCommand('SelectAll'); - this.editor.selection.collapse(false); - this.editor.$visualFocus(); - - if (bMatchCase) //IE specific flagging - flag = flag | 4; - - var found = false; - - if (jpf.isIE) { - var sel = this.editor.selection; - var range = sel.getRange(); - if (!(found = range.findText(val, 1, flag))) { - // simulate 'wrapAround' search... - this.editor.oDoc.execCommand('SelectAll'); - sel.collapse(true); - range = sel.getRange(); - //no chaining of calls here, seems to b0rk selection in IE - found = range.findText(val, 1, flag); - } - if (found) { - range.scrollIntoView(); - range.select(); - } - //this.storeSelection(); - sel.cache(); - } - else { - if (this.editor.oWin.find(val, bMatchCase, false, true, false, false, false)) - found = true; - } - if (this.oReplBtn) - this.oReplBtn[!found ? "disable" : "enable"](); - - if (!found) { - if (this.oReplBtn) - this.oReplBtn.disable(); - alert("No occurences found for '" + val + "'"); - } - else if (this.oReplBtn) - this.oReplBtn.enable(); - - if (e.stop) - e.stop(); - else - e.cancelBubble = true; - - if (!jpf.isIE) { - // IE cannot show the selection anywhere else then where the cursor - // is, so no show for them users... - var _self = this; - setTimeout(function() { - _self.oSearch.focus(); - }); - } - - return false; - }; - - this.onDoReplClick = function(e) { - this.replace(); - }; - - this.onReplAllClick = function(e) { - var val = this.oSearch.value, bMatchCase = this.oCase.checked, flag = 0, - ed = this.editor; - if (!val) - return; - - // Move caret to beginning of text - this.editor.executeCommand('SelectAll'); - this.editor.selection.collapse(true); - this.editor.$visualFocus(); - - var range = this.editor.selection.getRange(), found = 0; - - if (bMatchCase) //IE specific flagging - flag = flag | 4; - - if (jpf.isIE) { - while (range.findText(val, 1, flag)) { - range.scrollIntoView(); - range.select(); - this.replace(); - found++; - } - this.editor.selection.cache(); - //this.storeSelection(); - } - else { - while (this.editor.oWin.find(val, bMatchCase, false, false, false, false, false)) { - this.replace(); - found++; - } - } - - if (found > 0) - alert(found + " occurences found and replaced with '" + this.oReplace.value + "'"); - else - alert("No occurences found for '" + val + "'"); - }; - - this.replace = function() { - var sRepl = this.oReplace.value; - // Needs to be duplicated due to selection bug in IE - if (jpf.isIE) { - this.editor.selection.set(); - this.editor.selection.getRange().duplicate().pasteHTML(sRepl); - } - else - this.editor.oDoc.execCommand('InsertHTML', false, sRepl); - }; - - this.createPanelBody = function() { - panelBody = document.body.appendChild(document.createElement('div')); - panelBody.className = "editor_popup"; - panelBody.style.display = "none"; - var idSearch = 'editor_' + this.uniqueId + '_input'; - var idReplace = 'editor_' + this.uniqueId + '_replace'; - var idReplBtn = 'editor_' + this.uniqueId + '_replbtn'; - var idReplAllBtn = 'editor_' + this.uniqueId + '_replallbtn'; - var idCase = 'editor_' + this.uniqueId + '_case'; - var idBtns = 'editor_' + this.uniqueId + '_btns'; - panelBody.innerHTML = - '<div class="editor_panelrow editor_panelrowinput">\ - <label for="' + idSearch + '">Find what</label>\ - <textarea type="text" id="' + idSearch + '" class="editor_input" name="' + idSearch + '" value="">\ - </textarea>\ - </div>' + - (this.name == "replace" ? - '<div class="editor_panelrow editor_panelrowinput">\ - <label for="' + idReplace + '">Replace with</label>\ - <input type="text" id="' + idReplace + '" class="editor_input" name="' + idReplace + '" value="" />\ - </div>' : '') + - '<div class="editor_panelrow editor_panelrowinput">\ - <label for="' + idCase + '">Match case</label>\ - <input type="checkbox" id="' + idCase + '" name="' + idCase + '" class="editor_checkbox" value="" />\ - </div>\ - <div id="' + idBtns + '" class="editor_panelrow editor_panelrowbtns"></div>'; - this.oSearch = document.getElementById(idSearch); - this.oCase = document.getElementById(idCase); - - var aJml = [ - '<j:toolbar xmlns:j="', jpf.ns.jml, '"><j:bar>\ - <j:button caption="Find next" \ - onclick="jpf.lookup(', this.uniqueId, ').submit(event)" />']; - if (this.name == "replace") { - this.oReplace = document.getElementById(idReplace); - aJml.push( - '<j:button caption="Replace" \ - onclick="jpf.lookup(', this.uniqueId, ').onDoReplClick(event)" \ - id="', idReplBtn, '" />\ - <j:button caption="Replace all" \ - onclick="jpf.lookup(', this.uniqueId, ').onReplAllClick(event)" \ - id="', idReplAllBtn, '" />'); - } - aJml.push('</j:bar></j:toolbar>'); - - this.appendJmlNode(aJml.join(""), document.getElementById(idBtns)); - - if (this.name == "replace") { - this.oReplBtn = self[idReplBtn]; - this.oReplAllBtn = self[idReplAllBtn]; - this.oReplBtn.disable(); - } - - if (jpf.hasFocusBug) { - var fSel = function(e) { - e = e || window.event; - e.cancelBubble = true; - }; - jpf.sanitizeTextbox(this.oSearch); - this.oSearch.onselectstart = fSel; - if (this.oReplace) { - jpf.sanitizeTextbox(this.oReplace); - this.oReplace.onselectstart = fSel; - } - // checkboxes also need the focus fix: - jpf.sanitizeTextbox(this.oCase); - } - - return panelBody; - }; - - this.destroy = function() { - panelBody = this.oSearch = this.oCase = null; - delete panelBody; - delete this.oSearch; - delete this.oCase; - if (this.oReplace) { - this.oReplace = this.oReplBtn = this.oReplAllBtn = null; - delete this.oReplace; - delete this.oReplBtn; - delete this.oReplAllBtn; - } - }; -}; - -jpf.editor.plugin('search', jpf.editor.searchPlugin); -jpf.editor.plugin('replace', jpf.editor.searchPlugin); - - - -/*FILEHEAD(/var/lib/jpf/src/elements/editor/plugins/links.js)SIZE(-1077090856)TIME(1238933682)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -jpf.editor.plugin('link', function(){ - this.name = 'link'; - this.icon = 'link'; - this.type = jpf.editor.TOOLBARITEM; - this.subType = jpf.editor.TOOLBARPANEL; - this.hook = 'ontoolbar'; - this.keyBinding = 'ctrl+shift+l'; - this.state = jpf.editor.OFF; - - var panelBody; - - this.init = function(editor, btn) { - this.buttonNode.className = this.buttonNode.className + " dropdown_small"; - var oArrow = this.buttonNode.insertBefore(document.createElement('span'), - this.buttonNode.getElementsByTagName("div")[0]); - oArrow.className = "selectarrow"; - }; - - this.execute = function(editor) { - if (!panelBody) { - this.editor = editor; - jpf.popup.setContent(this.uniqueId, this.createPanelBody()); - } - - editor.dispatchEvent("pluginexecute", {name: this.name, plugin: this}); - - this.editor.showPopup(this, this.uniqueId, this.buttonNode, 218, 95); - if (panelBody.style.visibility == "hidden") - panelBody.style.visibility = "visible"; - var _self = this; - setTimeout(function() { - _self.oUrl.focus(); - }); - //return button id, icon and action: - return { - id: this.name, - action: null - }; - }; - - this.queryState = function(editor) { - if (editor.selection.isCollapsed() || editor.selection.getSelectedNode().tagName == "A") - return jpf.editor.DISABLED; - return this.state; - }; - - this.submit = function(e) { - jpf.popup.forceHide(); - - if (!this.oUrl.value) return; - - this.editor.executeCommand('CreateLink', 'javascript:jpftmp(0);'); - var oLink, aLinks = this.editor.oDoc.getElementsByTagName('a'); - for (var i = 0; i < aLinks.length && !oLink; i++) - if (aLinks[i].href == 'javascript:jpftmp(0);') - oLink = aLinks[i]; - if (oLink) { - oLink.href = this.oUrl.value; - oLink.target = this.oTarget.value; - oLink.title = this.oTitle.value; - } - this.editor.selection.collapse(false); - - // propagate the change AFTER changing back the link to its proper format - this.editor.change(this.editor.getValue()); - - if (e.stop) - e.stop(); - return false; - }; - - this.createPanelBody = function() { - panelBody = document.body.appendChild(document.createElement('div')); - panelBody.className = "editor_popup"; - panelBody.style.display = "none"; - var idUrl = 'editor_' + this.uniqueId + '_link_url'; - var idTarget = 'editor_' + this.uniqueId + '_link_target'; - var idTitle = 'editor_' + this.uniqueId + '_link_title'; - var idBtns = 'editor_' + this.uniqueId + '_link_btns'; - panelBody.innerHTML = - '<div class="editor_panelrow editor_panelrowinput">\ - <label for="' + idUrl + '">Link URL</label>\ - <input type="text" id="' + idUrl + '" name="' + idUrl + '" class="editor_input" value="" />\ - </div>\ - <div class="editor_panelrow editor_panelrowinput">\ - <label for="' + idTarget + '">Target</label>\ - <select id="' + idTarget + '" name="' + idTarget + '">\ - <option value="_self">Open in this window/ frame</option>\ - <option value="_blank">Open in new window (_blank)</option>\ - <option value="_parent">Open in parent window/ frame (_parent)</option>\ - <option value="_top">Open in top frame (replaces all frames) (_top)</option>\ - </select>\ - </div>\ - <div class="editor_panelrow editor_panelrowinput">\ - <label for="' + idTitle + '">Title</label>\ - <input type="text" id="' + idTitle + '" name="' + idTitle + '" class="editor_input" value="" />\ - </div>\ - <div id="' + idBtns + '" class="editor_panelrow editor_panelrowbtns"></div>'; - - //document.getElementById(idButton).onmousedown = this.submit.bindWithEvent(this); - this.oUrl = document.getElementById(idUrl); - this.oTarget = document.getElementById(idTarget); - this.oTitle = document.getElementById(idTitle); - - if (jpf.hasFocusBug) { - jpf.sanitizeTextbox(this.oUrl); - jpf.sanitizeTextbox(this.oTarget); - jpf.sanitizeTextbox(this.oTitle); - this.oUrl.onselectstart = this.oTarget.onselectstart = - this.oTitle.onselectstart = function(e) { - e = e || window.event; - e.cancelBubble = true; - }; - } - - this.appendJmlNode( - '<j:toolbar xmlns:j="' + jpf.ns.jml + '"><j:bar>\ - <j:button caption="' + this.editor.translate('insert') + '" \ - onclick="jpf.lookup(' + this.uniqueId + ').submit(event)" />\ - </j:bar></j:toolbar>', - document.getElementById(idBtns)) - - return panelBody; - }; - - this.destroy = function() { - panelBody = this.oUrl = this.oTarget = this.oTitle = null; - delete panelBody; - delete this.oUrl; - delete this.oTarget; - delete this.oTitle; - }; -}); - -jpf.editor.plugin('unlink', function(){ - this.name = 'unlink'; - this.icon = 'unlink'; - this.type = jpf.editor.TOOLBARITEM; - this.subType = jpf.editor.TOOLBARBUTTON; - this.hook = 'ontoolbar'; - this.keyBinding = 'ctrl+shift+l'; - this.state = jpf.editor.OFF; - - this.execute = function(editor) { - if (this.queryState(editor) == jpf.editor.DISABLED) - return; - - if (jpf.isIE) { - editor.executeCommand('Unlink'); - } - else { - var sel = editor.selection; - sel.set(); - var oNode = sel.getSelectedNode(); - if (oNode.tagName == "A") { - var txt = oNode.innerHTML; - sel.selectNode(oNode); - sel.remove(); - sel.collapse(); - editor.insertHTML(txt); - } - } - }; - - this.queryState = function(editor) { - if (editor.selection.getSelectedNode().tagName == "A") - return jpf.editor.OFF; - - return jpf.editor.DISABLED; - }; -}); - - - -/*FILEHEAD(/var/lib/jpf/src/elements/editor/plugins/directions.js)SIZE(-1077090856)TIME(1238933682)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -jpf.editor.directionPlugin = function(sName) { - this.name = sName; - this.icon = sName; - this.type = jpf.editor.TOOLBARITEM; - this.subType = jpf.editor.TOOLBARBUTTON; - this.hook = 'ontoolbar'; - this.state = jpf.editor.OFF; - - this.execute = function(editor) { - // @todo: implement this baby - editor.dispatchEvent("pluginexecute", {name: this.name, plugin: this}); - }; - - this.queryState = function(editor) { - return this.state; - }; -}; - -jpf.editor.plugin('ltr', jpf.editor.directionPlugin); -jpf.editor.plugin('rtl', jpf.editor.directionPlugin); - - - -/*FILEHEAD(/var/lib/jpf/src/elements/editor/plugins/visualaid.js)SIZE(-1077090856)TIME(1238933682)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -jpf.editor.plugin('visualaid', function(){ - this.name = 'visualaid'; - this.icon = 'visualaid'; - this.type = jpf.editor.TOOLBARITEM; - this.subType = jpf.editor.TOOLBARBUTTON; - this.hook = 'ontoolbar'; - this.keyBinding = 'ctrl+shift+v'; - this.state = jpf.editor.OFF; - - this.execute = function(editor) { - var state = this.queryState(editor); - editor.oDoc.body.className = (state == jpf.editor.ON) ? "" : "visualAid"; - editor.notify(this.name); - - editor.dispatchEvent("pluginexecute", {name: this.name, plugin: this}); - }; - - this.queryState = function(editor) { - this.state = jpf.editor[editor.oDoc.body.className == "visualAid" ? "ON" : "OFF"]; - return this.state; - }; -}); - - - -/*FILEHEAD(/var/lib/jpf/src/elements/editor/plugins/fontstyle.js)SIZE(-1077090856)TIME(1238933682)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -jpf.editor.plugin('fontstyle', function() { - this.name = 'fontstyle'; - this.icon = 'fontstyle'; - this.type = jpf.editor.TOOLBARITEM; - this.subType = jpf.editor.TOOLBARPANEL; - this.hook = 'ontoolbar'; - this.buttonNode = null; - this.state = jpf.editor.OFF; - - var panelBody, oStyles = null; - - function getStyles(editor) { - if (!oStyles) { - // parse font styles from skin definition - var node, aCss, bCss, oNode = editor.$getOption('fontstyles'); - if (!oNode || !oNode.childNodes) - throw new Error(jpf.formatErrorString(0, editor, - "Initializing plugin: fontstyle", - "No fontstyle block found in skin definition")); - for (var i = 0, j = oNode.childNodes.length; i < j && !oStyles; i++) { - node = oNode.childNodes[i]; - if (node.nodeType == 3 || node.nodeType == 4) { - oStyles = {}; - aCss = []; - bCss = []; - - node.nodeValue.replace(/([\w ]+)\s*=\s*(([^\{]+?)\s*\{[\s\S]*?\})\s*/g, - function(m, caption, css, className){ - if (!css || css.charAt(css.length - 1) != "}") - throw new Error(jpf.formatErrorString(0, editor, - "Initializing plugin: fontstyle", - "Invalid fontstyle block, please check if formatting rules have been applied")); - if (css.charAt(0) != ".") - css = "." + css; - css = css.trim().replace(/[\s]+/g, ""); - className = className.trim().replace(/\./, ""); - oStyles[className] = { - caption: caption.trim(), - cname : className, - css : css, - node : null - }; - aCss.push(css); - bCss.push(".editor_fontstyle " + css); - } - ); - } - } - - if (aCss.length) { - // insert resulting CSS into container document AND inside the - // document of the editor's iframe - jpf.importCssString(window.document, bCss.join("")); - jpf.importCssString(editor.oDoc, aCss.join("")); - if (jpf.isIE) { - // removing text nodes from the HEAD section, which are added - // by IE in some cases. - var nodes = editor.oDoc.getElementsByTagName('head')[0].childNodes; - var cnt = nodes.length - 1; - while (cnt) { - if (nodes[cnt].nodeType == 3) //text - nodes[cnt].parentNode.removeChild(nodes[cnt]); - cnt--; - } - } - } - } - return oStyles; - } - - this.init = function(editor) { - this.buttonNode.className = this.buttonNode.className + " fontstylepicker"; - this.stylePreview = this.buttonNode.getElementsByTagName('span')[0]; - this.stylePreview.className += " fontstylepreview"; - var styleArrow = this.buttonNode.appendChild(document.createElement('span')); - styleArrow.className = "selectarrow"; - }; - - this.execute = function(editor) { - if (!panelBody) { - this.editor = editor; - - jpf.popup.setContent(this.uniqueId, this.createPanelBody(editor)); - } - - editor.dispatchEvent("pluginexecute", {name: this.name, plugin: this}); - - this.editor.showPopup(this, this.uniqueId, this.buttonNode, 203); - //return button id, icon and action: - return { - id: this.name, - action: null - }; - }; - - function getCurrentStyle(editor) { - getStyles(editor); - - var oNode = editor.selection.getSelectedNode(); - while (oNode.nodeType != 1) // we need a block element - oNode = oNode.parentNode; - - var oCurrent; - while (!oCurrent && oNode && oNode.tagName != "BODY") { - var cs = oNode.className; - for (var i in oStyles) { - if (cs.indexOf(i) > -1) { - oCurrent = oStyles[i]; - oCurrent.node = oNode; - } - } - oNode = oNode.parentNode; - } - - return oCurrent; - } - - this.submit = function(e, sStyle) { - if (!sStyle) { - e = new jpf.AbstractEvent(e || window.event); - while (e.target.tagName.toLowerCase() != "a" && e.target.className != "editor_popup") - e.target = e.target.parentNode; - sStyle = e.target.getAttribute('rel'); - } - - if (sStyle) { - jpf.popup.forceHide(); - var sel = this.editor.selection; - - sel.set(); - this.editor.$visualFocus(); - - var o = getCurrentStyle(this.editor); - - if (o && sStyle == "normal") { - var n = o.node.childNodes, p = o.node.parentNode; - while (n.length) { - p.insertBefore(n[0], o.node); - } - p.removeChild(o.node); - - this.queryState(this.editor); - } - else if (o && (sel.isCollapsed() - || sel.getContent('text') == o.node.innerHTML) - && jpf.xmldb.isChildOf(o.node, sel.getSelectedNode(), true)) { - if (o.cname == sStyle) return; - jpf.setStyleClass(o.node, sStyle, [o.cname]); - } - else { - if (sel.isCollapsed()) { - if (jpf.isIE) { - var oNode = sel.getRange().parentElement(); - var p = this.editor.oDoc.createElement("span"); - p.className = sStyle; - p.innerHTML = oNode.innerHTML; - if (oNode.tagName == "BODY") { - oNode.innerHTML = ""; - oNode.appendChild(p); - } - else { - oNode.parentNode.insertBefore(p, oNode); - oNode.parentNode.removeChild(oNode); - } - sel.selectNode(p); - } - else { - var range = sel.getRange(); - var oCaret = range.commonAncestorContainer; - range.setStartBefore(oCaret); - range.setEndAfter(oCaret); - sel.setRange(range); - var htmlNode = sel.setContent('<span class="' + sStyle + '">' - + sel.getContent() + '</span>'); - sel.selectNode(htmlNode); - } - } - else { - //s.match(/^([\s\S]*?)(<(?:normal|pre|p|address|h1|h2|h3|h4|h5|h6)[\s\S]*?<\/(?:normal|pre|p|address|h1|h2|h3|h4|h5|h6)>)([\s\S]*?)$/gi) - var s = sel.getContent().trim(); - var shouldPrefixSpan = s.substr(0,5) == "<SPAN"; - s = s.replace(/<SPAN class=.*?>|<\/SPAN>/gi, ""); - if (s.charAt(0) == "<") { - s = s - .replace(/<(normal|pre|p|address|h1|h2|h3|h4|h5|h6)(?:\s.*?|)>(.+?)<\/(normal|pre|p|address|h1|h2|h3|h4|h5|h6)>/gi, - '<$1><span class="' + sStyle + '">$2</span></$3>') - .replace(/^([\s\S]*?)(<(?:normal|pre|p|address|h1|h2|h3|h4|h5|h6)[\s\S]*<\/(?:normal|pre|p|address|h1|h2|h3|h4|h5|h6)>)([\s\S]*?)$/gi, - function(m, m1, m2, m3){ - return (m1 ? '<span class="' + sStyle + '">' + m1 + '</span>' : '') + m2 + (m3 ? '<span class="' + sStyle + '">' + m3 + '</span>' : ''); - }) - .replace(/^\s*<(?:normal|pre|p|address|h1|h2|h3|h4|h5|h6)(?:\s.*?|)>|<\/(?:normal|pre|p|address|h1|h2|h3|h4|h5|h6)>\s*$/gi, ""); - if (jpf.isIE) - s = s.replace(/<\/P>/, ""); - } - else { - s = '<span class="' + sStyle + '">' + s + '</span>'; - } - - if (shouldPrefixSpan) - s = "</SPAN>" + s.replace(/<\/SPAN>$/i, ""); - - var htmlNode = sel.setContent(s, true); - sel.selectNode(htmlNode); - } - } - // Notify the SmartBindings we've changed... - this.editor.change(this.editor.getValue()); - } - }; - - this.queryState = function(editor) { - var o = getCurrentStyle(editor); - if (o) { - if (this.stylePreview.innerHTML != o.caption) - this.stylePreview.innerHTML = o.caption; - this.state = jpf.editor.ON; - } - else { - this.stylePreview.innerHTML = "Style"; - this.state = jpf.editor.OFF; - } - - return this.state; - }; - - this.createPanelBody = function(editor) { - panelBody = document.body.appendChild(document.createElement('div')); - panelBody.className = "editor_popup"; - panelBody.style.display = "none"; - - getStyles(editor); - var aHtml = ['<a class="editor_panelcell editor_fontstyle" rel="normal" \ - href="javascript:;" onmouseup="jpf.lookup(', this.uniqueId, - ').submit(event);"><span>Normal</span></a>']; - for (var i in oStyles) { - aHtml.push('<a class="editor_panelcell editor_fontstyle" rel="', - i, '" href="javascript:;" onmouseup="jpf.lookup(', - this.uniqueId, ').submit(event);"><span class="', i, '">', - oStyles[i].caption, '</span></a>') - } - panelBody.innerHTML = aHtml.join(''); - - return panelBody; - }; - - this.destroy = function() { - panelBody = this.stylePreview = null; - delete panelBody; - delete this.stylePreview; - }; -}); - -//############################################################################## - -jpf.editor.plugin('paragraph', function() { - this.name = 'paragraph'; - this.icon = 'paragraph'; - this.type = jpf.editor.TOOLBARITEM; - this.subType = jpf.editor.TOOLBARPANEL; - this.hook = 'ontoolbar'; - this.buttonNode = null; - this.state = jpf.editor.OFF; - this.node = null; - - var panelBody, - - // this hashmap maps font size number to it's equivalent in points (pt) - blocksMap = { - 'normal' : 'Normal', - 'p' : 'Paragraph', - 'pre' : 'Preformatted', - 'address' : 'Address', - 'h1' : 'Header 1', - 'h2' : 'Header 2', - 'h3' : 'Header 3', - 'h4' : 'Header 4', - 'h5' : 'Header 5', - 'h6' : 'Header 6' - }, - blocksRE, blocksRE2, blocksRE3, blocksRE4, blockFormats; - - function getFormats(editor) { - if (!blockFormats) { - // parse font styles from skin definition - var i, j, node, oNode = editor.$getOption('blockformats'); - if (!oNode || !oNode.childNodes) - throw new Error(jpf.formatErrorString(0, editor, - "Initializing plugin: Paragraph (blockformats)", - "No block formats found in skin definition")); - for (i = 0, j = oNode.childNodes.length; i < j; i++) { - node = oNode.childNodes[i]; - if (node.nodeType == 3 || node.nodeType == 4) - blockFormats = node.nodeValue.splitSafe(","); - } - - var sJoin = "(" + blockFormats.join("|") + ")"; - blocksRE = new RegExp("^" + sJoin + "$", "gi"); - blocksRE2 = new RegExp("<\\/?" + sJoin + ">", "gi"); - blocksRE3 = new RegExp("<\\/?(" + blockFormats.join("|") + "|p)>", "gi"); - blocksRE4 = new RegExp("^(" + blockFormats.join("|") + "|p)$", "gi"); - } - return blockFormats; - } - - this.init = function(editor) { - this.buttonNode.className = this.buttonNode.className + " paragraphpicker"; - this.blockPreview = this.buttonNode.getElementsByTagName('span')[0]; - this.blockPreview.className += " paragraphpreview"; - var blockArrow = this.buttonNode.appendChild(document.createElement('span')); - blockArrow.className = "selectarrow"; - }; - - this.execute = function(editor) { - if (!panelBody) { - this.editor = editor; - - jpf.popup.setContent(this.uniqueId, this.createPanelBody(editor)); - } - this.editor.showPopup(this, this.uniqueId, this.buttonNode, 203); - //return button id, icon and action: - return { - id: this.name, - action: null - }; - }; - - this.queryState = function(editor) { - var oNode = editor.selection.getSelectedNode(), - aFormats = getFormats(editor), - /*bCurrent = (oNode && oNode.nodeType == 1 - && aFormats.contains(oNode.tagName.toLowerCase())), - bParent = (oNode && oNode.parentNode && oNode.parentNode.nodeType == 1 - && aFormats.contains(oNode.parentNode.tagName.toLowerCase())),*/ - tagName = oNode.nodeType == 1 ? oNode.tagName.toLowerCase() : ""; - - while (!tagName.match(blocksRE) && tagName != "body") { - oNode = oNode.parentNode; - tagName = oNode.tagName.toLowerCase(); - } - if (tagName.match(blocksRE)) {//bCurrent || bParent) { - var sBlock = blocksMap[tagName]; - if (this.blockPreview.innerHTML != sBlock) - this.blockPreview.innerHTML = sBlock; - this.state = jpf.editor.ON; - this.node = oNode; - } - else { - this.blockPreview.innerHTML = "Normal"; - this.state = jpf.editor.OFF; - this.node = null; - } - return this.state; - }; - - this.submit = function(e, sBlock) { - if (!sBlock) { - e = new jpf.AbstractEvent(e || window.event); - while (e.target.tagName.toLowerCase() != "a" && e.target.className != "editor_popup") - e.target = e.target.parentNode; - sBlock = e.target.getAttribute('rel'); - } - - if (sBlock) { - jpf.popup.forceHide(); - var oNode, sel = this.editor.selection; - - sel.set(); - this.editor.$visualFocus(); - var s = sel.getContent(); - if (sBlock == "normal" && this.queryState(this.editor) == jpf.editor.ON) { - // revert style to NORMAL, i.e. no style at all. - /*sel.selectNode(this.node); - sel.setContent(this.node.innerHTML);*/ - - var n = this.node.childNodes, p = this.node.parentNode; - - if (jpf.isIE) { - var textlength = sel.getContent('text').length; - var l = p.insertBefore(p.ownerDocument.createElement("p"), this.node); - - while (n.length) { - l.insertBefore(n[0], l.firstChild); - } - - p.removeChild(this.node); - sel.selectNode(l); - if (l.previousSibling && l.previousSibling.tagName == "P") { - if (l.previousSibling.innerHTML == "") { - l.parentNode.removeChild(l.previousSibling); - } - } - } - else { - while (n.length) { - p.insertBefore(n[0], this.node); - } - - p.removeChild(this.node); - } - - this.state = jpf.editor.OFF; - this.node = null; - this.blockPreview.innerHTML = "Normal"; - } - else if (sel.isCollapsed() || s.trim() == "") { - if (jpf.isIE) { - var startNode, oNode; - oNode = startNode = sel.getRange().parentElement(); - while(!oNode.tagName.match(blocksRE4) && oNode.tagName != "BODY") { - oNode = oNode.parentNode; - } - - if (oNode && oNode.tagName == "BODY") { - if (startNode != oNode) - oNode = startNode; - else { - //r = sel.getRange();r.moveEnd("character", 500); r.htmlText - } - } - - var p = this.editor.oDoc.createElement(sBlock); - p.innerHTML = oNode.innerHTML; - if (oNode.tagName == "BODY") { - oNode.innerHTML = ""; - oNode.appendChild(p); - } - else { - oNode.parentNode.insertBefore(p, oNode); - oNode.parentNode.removeChild(oNode); - } - sel.selectNode(p); - } - else { - this.editor.executeCommand('FormatBlock', sBlock); - } - - this.blockPreview.innerHTML = blocksMap[sBlock]; - } - else { - oNode = sel.getSelectedNode(); - while (oNode.nodeType != 1) - oNode = oNode.parentNode; - - // @todo FF is DEFINITELY b0rking when we try to nest HTML 4.01 block elements... - // REALLY not like Word does it... - if (oNode.tagName.match(blocksRE4) && s.length == oNode[jpf.hasInnerText ? 'innerText' : 'textContent'].length) { - var p = this.editor.oDoc.createElement(sBlock); - p.innerHTML = oNode.innerHTML; - oNode.parentNode.insertBefore(p, oNode); - oNode.parentNode.removeChild(oNode); - sel.selectNode(p); - } - else { - while(!oNode.tagName.match(blocksRE4) && oNode.tagName != "BODY") { - oNode = oNode.parentNode; - } - if (oNode && oNode.tagName != "BODY") { - var s2; - if (oNode.tagName == "P" && jpf.isIE) { - s2 = '<' + sBlock + '>' + s.trim().replace(blocksRE3, '') + '</' + sBlock + '>'; - addedNode = sel.setContent(s2); - } - else { - s2 = '<P __jpf_placeholder="true">' + s + '</P>'; - sel.setContent(s2); - - var sBlock2 = oNode.tagName; - var html = [], first, last; - var strHtml = oNode.innerHTML.replace(s2, function(m, pos){ - return (pos != 0 - ? (first = true) && '</' + sBlock2 + '>' - : '') + - '<' + sBlock + ' __jpf_placeholder="true">' + s.replace(blocksRE3, '') + - '</' + sBlock + '>' + - (pos < oNode.innerHTML.length - s.length - ? (last = true) && '<' + sBlock2 + '>' - : ''); - }); - if (first) - html.push('<' + sBlock2 + '>'); - html.push(strHtml); - if (last) - html.push('</' + sBlock2 + '>'); - - oNode.innerHTML = html.join(""); - var addedNode, n = oNode.getElementsByTagName(sBlock); - for (var i = 0; i < n.length; i++) { - if (n[i].getAttribute("__jpf_placeholder")) { - n[i].removeAttribute("__jpf_placeholder"); - addedNode = n[i]; - break; - } - } - - n = oNode.childNodes, p = oNode.parentNode; - while (n.length) - p.insertBefore(n[0], oNode); - p.removeChild(oNode); - } - - if (jpf.isIE) { - addedNode.parentNode.insertBefore( - addedNode.ownerDocument.createElement("P"), - addedNode); - } - - sel.selectNode(addedNode); - } - else { - var addedNode = sel.setContent('<' + sBlock + '>' - + s.replace(/<p>(.*?)<\/p>(.)/gi, "$1<br />$2") - .replace(blocksRE3, '') + '</' + sBlock + '>'); - - if (jpf.isIE) { - addedNode.parentNode.insertBefore( - addedNode.ownerDocument.createElement("P"), - addedNode); - } - - sel.selectNode(addedNode); - } - } - - this.blockPreview.innerHTML = blocksMap[sBlock]; - } - - // Notify the SmartBindings we've changed... - this.editor.change(this.editor.getValue()); - } - }; - - this.createPanelBody = function(editor) { - panelBody = document.body.appendChild(document.createElement('div')); - panelBody.className = "editor_popup"; - panelBody.style.display = "none"; - - var aHtml = [], - aFormats = getFormats(editor); - for (var i = 0, j = aFormats.length; i < j; i++) { - aHtml.push('<a class="editor_panelcell editor_paragraph" rel="', - aFormats[i], '" href="javascript:;" onmouseup="jpf.lookup(', - this.uniqueId, ').submit(event);"><', aFormats[i], '>', - blocksMap[aFormats[i]], '</', aFormats[i], '></a>'); - } - panelBody.innerHTML = aHtml.join(''); - - return panelBody; - }; - - this.destroy = function() { - panelBody = this.blockPreview = this.node = null; - delete panelBody; - delete this.blockPreview; - delete this.node; - }; -}); - - - - -/*FILEHEAD(/var/lib/jpf/src/elements/editor/plugins/fontbase.js)SIZE(-1077090856)TIME(1238933682)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -jpf.editor.plugin('fonts', function() { - this.name = 'fonts'; - this.icon = 'fonts'; - this.type = jpf.editor.TOOLBARITEM; - this.subType = jpf.editor.TOOLBARPANEL; - this.hook = 'ontoolbar'; - this.buttonNode = null; - this.state = jpf.editor.OFF; - this.colspan = 1; - this.fontNames = {}; - - var panelBody; - - this.init = function(editor) { - this.buttonNode.className = this.buttonNode.className + " fontpicker"; - this.fontPreview = this.buttonNode.getElementsByTagName('span')[0]; - this.fontPreview.className += " fontpreview"; - var fontArrow = this.buttonNode.insertBefore(document.createElement('span'), - this.buttonNode.getElementsByTagName("div")[0]); - fontArrow.className = "selectarrow"; - - this.editor = editor; - - // parse fonts - var l, j, font, fonts, node; - var oNode = editor.$getOption('fonts').childNodes[0]; - while(oNode) { - fonts = oNode.nodeValue.splitSafe('(?:;|=)'); - if (fonts[0]) { - for (j = 0, l = fonts.length; j < l; j++) - this.fontNames[fonts[j]] = fonts[++j]; - break; - } - oNode = oNode.nextSibling - } - }; - - this.execute = function() { - if (!panelBody) { - jpf.popup.setContent(this.uniqueId, this.createPanelBody()); - } - - this.editor.dispatchEvent("pluginexecute", {name: this.name, plugin: this}); - - this.editor.showPopup(this, this.uniqueId, this.buttonNode, 120); - //return button id, icon and action: - - return { - id: this.name, - action: null - }; - }; - - this.queryState = function(editor) { - this.state = editor.getCommandState('FontName'); - - var currValue = editor.oDoc.queryCommandValue('FontName'); - if (!currValue || (this.fontNames[currValue] && this.fontPreview.innerHTML != currValue)) - this.fontPreview.innerHTML = currValue ? currValue : "Font"; - }; - - this.submit = function(e) { - e = new jpf.AbstractEvent(e || window.event); - while (e.target.tagName.toLowerCase() != "a" && e.target.className != "editor_popup") - e.target = e.target.parentNode; - var sFont = e.target.getAttribute('rel'); - if (sFont) { - jpf.popup.forceHide(); - if (jpf.isIE) { - this.editor.selection.set(); - if (this.editor.selection.isCollapsed()) { - this.editor.$visualFocus(); - var r = this.editor.selection.getRange(); - r.moveStart('character', -1); - r.select(); - } - } - this.editor.executeCommand('FontName', sFont); - if (jpf.isIE) - this.editor.selection.collapse(false); - } - }; - - this.createPanelBody = function() { - panelBody = document.body.appendChild(document.createElement('div')); - panelBody.className = "editor_popup"; - panelBody.style.display = "none"; - var aHtml = []; - - for (var i in this.fontNames) { - aHtml.push('<a class="editor_panelcell editor_font" style="font-family:', - this.fontNames[i], ';" rel="', i, - '" href="javascript:;" onmouseup="jpf.lookup(', this.uniqueId, - ').submit(event);">', i, '</a>'); - } - panelBody.innerHTML = aHtml.join(''); - - return panelBody; - }; - - this.destroy = function() { - panelBody = this.fontPreview = null; - delete panelBody; - delete this.fontPreview; - }; -}); - -jpf.editor.plugin('fontsize', function() { - this.name = 'fontsize'; - this.icon = 'fontsize'; - this.type = jpf.editor.TOOLBARITEM; - this.subType = jpf.editor.TOOLBARPANEL; - this.hook = 'ontoolbar'; - this.buttonNode = null; - this.state = jpf.editor.OFF; - - var panelBody; - - // this hashmap maps font size number to it's equivalent in points (pt) - var sizeMap = { - '1' : '8', - '2' : '10', - '3' : '12', - '4' : '14', - '5' : '18', - '6' : '24', - '7' : '36' - }; - - this.init = function(editor) { - this.buttonNode.className = this.buttonNode.className + " fontsizepicker"; - this.sizePreview = this.buttonNode.getElementsByTagName('span')[0]; - this.sizePreview.className += " fontsizepreview"; - var sizeArrow = this.buttonNode.insertBefore(document.createElement('span'), - this.buttonNode.getElementsByTagName("div")[0]); - sizeArrow.className = "selectarrow"; - }; - - this.execute = function(editor) { - if (!panelBody) { - this.editor = editor; - - // parse font sizes - var i, node, oNode = editor.$getOption('fontsizes'); - for (i = 0; i < oNode.childNodes.length; i++) { - node = oNode.childNodes[i]; - if (node.nodeType == 3 || node.nodeType == 4) - this.fontSizes = node.nodeValue.splitSafe(","); - } - - jpf.popup.setContent(this.uniqueId, this.createPanelBody()); - } - this.editor.showPopup(this, this.uniqueId, this.buttonNode, 203); - //return button id, icon and action: - return { - id: this.name, - action: null - }; - }; - - this.queryState = function(editor) { - this.state = editor.getCommandState('FontSize'); - - var currValue = editor.oDoc.queryCommandValue('FontSize') - if (!currValue || this.sizePreview.innerHTML != currValue) { - this.sizePreview.innerHTML = currValue ? currValue : "Size"; - } - }; - - this.submit = function(e) { - e = new jpf.AbstractEvent(e || window.event); - while (e.target.tagName.toLowerCase() != "a" && e.target.className != "editor_popup") - e.target = e.target.parentNode; - var sSize = e.target.getAttribute('rel'); - if (sSize) { - jpf.popup.forceHide(); - if (jpf.isIE) { - this.editor.selection.set(); - if (this.editor.selection.isCollapsed()) { - this.editor.$visualFocus(); - var r = this.editor.selection.getRange(); - r.moveStart('character', -1); - r.select(); - } - } - this.editor.executeCommand('FontSize', sSize); - if (jpf.isIE) - this.editor.selection.collapse(false); - } - e.stop(); - return false; - }; - - this.createPanelBody = function() { - panelBody = document.body.appendChild(document.createElement('div')); - panelBody.className = "editor_popup"; - panelBody.style.display = "none"; - var aHtml = []; - - var aSizes = this.fontSizes; - for (var i = 0; i < aSizes.length; i++) { - aHtml.push('<a class="editor_panelcell editor_fontsize" style="font-size:', - sizeMap[aSizes[i]], 'pt;height:', sizeMap[aSizes[i]], 'pt;line-height:', - sizeMap[aSizes[i]], 'pt;" rel="', aSizes[i], - '" href="javascript:;" onmouseup="jpf.lookup(', this.uniqueId, - ').submit(event);">', aSizes[i], ' (', sizeMap[aSizes[i]], 'pt)</a>'); - } - panelBody.innerHTML = aHtml.join(''); - - return panelBody; - }; - - this.destroy = function() { - panelBody = this.sizePreview = null; - delete panelBody; - delete this.sizePreview; - }; -}); - - - -/*FILEHEAD(/var/lib/jpf/src/elements/editor/plugins/charmap.js)SIZE(-1077090856)TIME(1238933682)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -jpf.editor.plugin('charmap', function() { - this.name = 'charmap'; - this.icon = 'charmap'; - this.type = jpf.editor.TOOLBARITEM; - this.subType = jpf.editor.TOOLBARPANEL; - this.hook = 'ontoolbar'; - this.buttonNode = null; - this.state = jpf.editor.OFF; - this.colspan = 20; - - var panelBody; - - this.init = function(editor, btn) { - this.buttonNode.className = this.buttonNode.className + " dropdown_small"; - var oArrow = this.buttonNode.insertBefore(document.createElement('span'), - this.buttonNode.getElementsByTagName("div")[0]); - oArrow.className = "selectarrow"; - }; - - this.execute = function(editor) { - if (!panelBody) { - this.editor = editor; - jpf.popup.setContent(this.uniqueId, this.createPanelBody()); - } - - editor.dispatchEvent("pluginexecute", {name: this.name, plugin: this}); - - this.editor.showPopup(this, this.uniqueId, this.buttonNode, jpf.isIE6 ? 469 : 466, 199); - //return button id, icon and action: - return { - id: this.name, - action: null - }; - }; - - this.queryState = function() { - return this.state; - }; - - var chars = ["!",""","#","$","%","&","\\'","(",")","*", - "+","-",".","/","0","1","2","3","4","5","6","7","8","9",":", - ";","<","=",">","?","@","A","B","C","D","E","F","G","H", - "I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W", - "X","Y","Z","[","]","^","_","`","a","b","c","d","e","f","g", - "h","i","j","k","l","m","n","o","p","q","r","s","t","u","v", - "w","x","y","z","{","|","}","~","€","‘","’", - "’","“","”","–","—","¡", - "¢","£","¤","¥","¦","§", - "¨","©","ª","«","¬","®","¯", - "°","±","²","³","´","µ","¶", - "·","¸","¹","º","»","¼", - "½","¾","¿","À","Á","Â", - "Ã","Ä","Å","Æ","Ç","È", - "É","Ê","Ë","Ì","Í","Î", - "Ï","Ð","Ñ","Ò","Ó","Ô", - "Õ","Ö","×","Ø","Ù","Ú", - "Û","Ü","Ý","Þ","ß","à", - "á","â","ã","ä","å","æ", - "ç","è","é","ê","ë","ì", - "í","î","ï","ð","ñ","ò", - "ó","ô","õ","ö","÷","ø", - "ù","ú","û","ü","ü","ý", - "þ","ÿ","Œ","œ","‚","‛", - "„","…","™","►","•","→", - "⇒","⇔","♦","≈"]; - - this.submit = function(e) { - e = new jpf.AbstractEvent(e || window.event); - while (e.target.tagName.toLowerCase() != "a" && e.target.className != "editor_popup") - e.target = e.target.parentNode; - var sCode = e.target.getAttribute('rel'); - if (sCode) { - jpf.popup.forceHide(); - //this.storeSelection(); - this.editor.insertHTML(sCode, true); - //this.restoreSelection(); - } - }; - - this.createPanelBody = function() { - panelBody = document.body.appendChild(document.createElement('div')); - panelBody.className = "editor_popup"; - panelBody.style.display = "none"; - var aHtml = []; - var rowLen = this.colspan - 1; - for (var i = 0; i < chars.length; i++) { - if (i % this.colspan == 0) - aHtml.push('<div class="editor_panelrow">'); - aHtml.push('<a class="editor_panelcell editor_largecell" style="background-color:#', - chars[i], ';" rel="', chars[i], '" href="javascript:;" onmousedown="jpf.lookup(', - this.uniqueId, ').submit(event);">\ - <span>', chars[i],'</span>\ - </a>'); - if (i % this.colspan == rowLen) - aHtml.push('</div>'); - } - panelBody.innerHTML = aHtml.join(''); - return panelBody; - }; - - this.destroy = function() { - panelBody = null; - delete panelBody; - }; -}); - - - -/*FILEHEAD(/var/lib/jpf/src/elements/editor/plugins/help.js)SIZE(-1077090856)TIME(1238933682)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -jpf.editor.plugin('help', function(){ - this.name = 'help'; - this.icon = 'help'; - this.type = jpf.editor.TOOLBARITEM; - this.subType = jpf.editor.TOOLBARBUTTON; - this.hook = 'ontoolbar'; - this.keyBinding = 'ctrl+h'; - this.state = jpf.editor.OFF; - - this.execute = function(editor) { - // @todo: implement this plugin - editor.dispatchEvent("pluginexecute", {name: this.name, plugin: this}); - }; - - this.queryState = function(editor) { - return this.state; - }; -}); - - - -/*FILEHEAD(/var/lib/jpf/src/elements/editor/plugins/hr.js)SIZE(-1077090856)TIME(1238933682)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -jpf.editor.plugin('hr', function(){ - this.name = 'hr'; - this.icon = 'hr'; - this.type = jpf.editor.TOOLBARITEM; - this.subType = jpf.editor.TOOLBARBUTTON; - this.hook = 'ontoolbar'; - this.keyBinding = 'ctrl+h'; - this.state = jpf.editor.OFF; - - this.execute = function(editor) { - if (jpf.isGecko || jpf.isIE) - editor.insertHTML('<hr />', true); - else - editor.executeCommand('InsertHorizontalRule'); - - editor.dispatchEvent("pluginexecute", {name: this.name, plugin: this}); - }; - - this.queryState = function(editor) { - return this.state; - }; -}); - - - -/*FILEHEAD(/var/lib/jpf/src/elements/modalwindow/widget.js)SIZE(-1077090856)TIME(1238933681)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -/** - * @private - * @constructor - */ -jpf.modalwindow.widget = function(){ - var nX, nY, verdiff, hordiff, cData; - var _self = this; - - this.dragStart = function(e){ - if (!e) e = event; - - nX = _self.oExt.offsetLeft - e.clientX; - nY = _self.oExt.offsetTop - e.clientY; - - var htmlNode = _self.oExt; - var p = _self.positionHolder; - p.className = "position_holder"; - - htmlNode.parentNode.insertBefore(p, htmlNode); - //p.style.width = (htmlNode.offsetWidth - 2) + "px"; - p.style.height = (htmlNode.offsetHeight - (jpf.isIE6 ? 0 : 13)) + "px"; - - var diff = jpf.getDiff(htmlNode); - var lastSize = [htmlNode.style.width, htmlNode.style.height]; - htmlNode.style.width = (htmlNode.offsetWidth - diff[0]) + "px"; - //htmlNode.style.height = (htmlNode.offsetHeight - diff[1]) + "px"; - - htmlNode.style.left = (e.clientX - nX) + "px"; - htmlNode.style.top = (e.clientY - nY) + "px"; - htmlNode.style.position = "absolute"; - htmlNode.style.zIndex = htmlNode.parentNode.style.zIndex = 100000; - htmlNode.parentNode.style.position = "relative"; - htmlNode.parentNode.style.left = "0"; //hack - // @todo: should we rewrite this to use jpf.tween? - jpf.Animate.fade(htmlNode, 0.8); - - jpf.dragmode.mode = true; //simulate using dragmode - - cData = [htmlNode, p]; - document.onmousemove = _self.dragMove; - document.onmouseup = function(){ - document.onmousemove = document.onmouseup = null; - - htmlNode.style.position = "";//relative"; - htmlNode.style.left = 0; - htmlNode.style.top = 0; - htmlNode.style.width = lastSize[0]; - //htmlNode.style.height = lastSize[1]; - htmlNode.style.zIndex = htmlNode.parentNode.style.zIndex = 1; - //htmlNode.parentNode.style.position = "static"; - - p.parentNode.insertBefore(htmlNode, p); - p.parentNode.removeChild(p); - jpf.Animate.fade(htmlNode, 1); - - //@todo please move this to datagrid internals - var grids = _self.getElementsByTagName("datagrid"); - for(var i = 0; i < grids.length; i++) { - grids[i].updateWindowSize(true); - } - - jpf.dragmode.mode = null; - }; - - e.cancelBubble = true; - return false; - }; - - //Search for insert position - function insertInColumn(el, ey){ - var pos = jpf.getAbsolutePosition(el); - var cy = ey - pos[1]; - var nodes = el.childNodes; - - for (var th = 0, i = 0, l = nodes.length; i < l; i++) { - var node = nodes[i]; - if (node.nodeType != 1 - || jpf.getStyle(node, "position") == "absolute") - continue; - - th = node.offsetTop + node.offsetHeight; - if (th > cy) { - el.insertBefore(cData[1], - th - (node.offsetHeight / 2) > cy - ? node - : node.nextSibling); - } - } - - if (i == nodes.length) - el.appendChild(cData[1]); - } - - this.dragMove = function(e){ - if (!e) e = event; - - _self.oExt.style.top = "10000px"; - var ex = e.clientX + document.documentElement.scrollLeft; - var ey = e.clientY + document.documentElement.scrollTop; - var el = document.elementFromPoint(ex, ey); - - if (el.isColumn){ - insertInColumn(el, ey); - } - else { - //search for element - while (el.parentNode && !el.isColumn) { - el = el.parentNode; - } - - if (el.isColumn) - insertInColumn(el, ey); - } - - _self.oExt.style.left = (e.clientX - nX) + "px"; - _self.oExt.style.top = (e.clientY - nY) + "px"; - - e.cancelBubble = true; - }; - - this.$loadJml = function(x) { - jpf.WinServer.setTop(this); - - var diff = jpf.getDiff(this.oExt); - hordiff = diff[0]; - verdiff = diff[1]; - - var oInt = this.$getLayoutNode("main", "container", this.oExt); - var oSettings = this.$getLayoutNode("main", "settings_content", this.oExt); - - //Should be moved to an init function - this.positionHolder = document.body.appendChild(document.createElement("div")); - - var oConfig = $xmlns(this.$jml, "config", jpf.ns.jml)[0]; - if (oConfig) - oConfig.parentNode.removeChild(oConfig); - var oBody = $xmlns(this.$jml, "body", jpf.ns.jml)[0];//jpf.xmldb.selectSingleNode("j:body", this.$jml); - oBody.parentNode.removeChild(oBody); - - jpf.JmlParser.parseChildren(this.$jml, null, this); - - if (oConfig) - this.$jml.appendChild(oConfig); - this.$jml.appendChild(oBody); - - if (oSettings && oConfig) { - this.oSettings = this.oSettings - ? jpf.JmlParser.replaceNode(oSettings, this.oSettings) - : jpf.JmlParser.parseChildren(oConfig, oSettings, this, true); - } - - this.oInt = this.oInt - ? jpf.JmlParser.replaceNode(oInt, this.oInt) - : jpf.JmlParser.parseChildren(oBody, oInt, this, true); - - if (oBody.getAttribute("class")) - this.$setStyleClass(this.oInt, oBody.getAttribute("class")) - - this.oDrag.onmousedown = this.dragStart; - - if (this.resizable) - this.resizable = false; - - if (this.draggable === undefined) - this.draggable = true; - - this.minwidth = this.$getOption("Main", "min-width"); - this.minheight = this.$getOption("Main", "min-height"); - }; -}; - - -/*FILEHEAD(/var/lib/jpf/src/elements/teleport/rpc.js)SIZE(-1077090856)TIME(1238944817)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-/**
- * Baseclass for rpc in teleport. Modules are available for
- * SOAP, XML-RPC, CGI, JSON-RPC and several proprietary protocols.
- * Example:
- * This example shows an rpc element using the xmlrpc protocol. It contains
- * two methods which can be called. The return of the first method is handled
- * by a javascript function called processSearch.
- * <code>
- * <j:teleport>
- * <j:rpc id="comm" protocol="xmlrpc">
- * <j:method
- * name = "searchProduct"
- * receive = "processSearch" />
- * <j:method
- * name = "loadProduct" />
- * </j:rpc>
- * </j:teleport>
- *
- * <j:script>
- * //This function is called when the search returns
- * function processSearch(data, state, extra){
- * alert(data)
- * }
- *
- * //Execute a search for the product car
- * comm.searchProduct('car', 10);
- * </j:script>
- * </code>
- *
- * @define rpc
- * @attribute {String} soap-xmlns the url that uniquely identifies the xml namespace for the message
- * @attribute {String} soap-prefix the prefix that is paired with the message xml namespace
- * @addnode teleport
- * @allowchild method
- *
- * @constructor
- *
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.4
- * @default_private
- */
-jpf.rpc = function(){
- if (!this.supportMulticall)
- this.multicall = false;
-
- this.stack = {};
- this.urls = {};
- this.tagName = "rpc";
- this.useHTTP = true;
-
- this.TelePortModule = true;
- this.routeServer = jpf.host + "/cgi-bin/rpcproxy.cgi";
- this.autoroute = false;
- this.namedArguments = false;
-
- var _self = this;
-
- this.addMethod = function(name, callback, names, async, caching, ignoreOffline){
- this[name] = function(){
- return this.call(name, arguments);
- }
-
- this[name].async = async;
- this[name].caching = caching;
- this[name].names = names;
- this[name].ignoreOffline = ignoreOffline;
-
- if (callback)
- this[name].callback = callback;
-
- return true;
- }
-
- this.setCallback = function(name, func){
- this[name].callback = func;
- }
-
- this.$convertArgs = function(name, args){
- if (!this.namedArguments)
- return args.slice();
-
- var nodes = this[name].names;
- if (!nodes || !nodes.length)
- return {};
-
- var name, value, result = {};
- for (var j = 0, i = 0; i < nodes.length; i++) {
- name = nodes[i].getAttribute("name");
-
- if (nodes[i].getAttribute("value"))
- value = jpf.parseExpression(nodes[i].getAttribute("value"));
- else {
- value = args[j++];
-
- if (jpf.isNot(value) && nodes[i].getAttribute("default"))
- value = jpf.parseExpression(nodes[i].getAttribute("default"));
- }
-
- //Encode string optionally
- value = jpf.isTrue(nodes[i].getAttribute("encoded"))
- ? encodeURIComponent(value)
- : value;
-
- result[name] = value;
- }
-
- return result;
- }
-
- this.call = function(name, args, options){
- args = this.$convertArgs(name, args);
-
- // Set up multicall
- if (this.multicall) {
- if (!this.stack[this.url])
- this.stack[this.url] = this.getMulticallObject
- ? this.getMulticallObject()
- : new Array();
-
- this.getSingleCall(name, args, this.stack[this.url])
- return true;
- }
-
- var callback = (typeof this[name].callback == "string"
- ? self[this[name].callback]
- : this[name].callback) || function(){};
-
- // Get Data
- var data = this.serialize(name, args); //function of module
-
- function pCallback(data, state, extra){
- extra.data = data;
-
- if(state != jpf.SUCCESS)
- callback(null, state, extra);
- else if (_self.isValid && !_self.isValid(extra))
- callback(null, jpf.ERROR, extra);
- else
- callback(_self.unserialize(extra.data), state, extra);
- }
-
- // Sent the request
- var url = jpf.getAbsolutePath(this.baseurl, this.url);
- var info = this.get(url, pCallback, jpf.extend({
- async : this[name].async,
- userdata : this[name].userdata,
- nocache : true,
- data : data,
- useXML : this.useXML,
- caching : this[name].caching,
- ignoreOffline : this[name].ignoreOffline
- }, options));
-
- return info;
- }
-
- /**
- * Purge multicalled requests
- */
- this.purge = function(callback, userdata, async, extradata){
- if (!this.stack[this.url] || !this.stack[this.url].length)
- throw new Error(jpf.formatErrorString(0, null, "Executing a multicall", "No RPC calls where executed before calling purge()."));
-
- // Get Data
- var data = this.serialize("multicall", [this.stack[this.url]]); //function of module
- var url = jpf.getAbsolutePath(this.baseurl, this.url);
- if (extradata) {
- for (var vars = [], i = 0; i < extradata.length; i++) {
- vars.push(encodeURIComponent(extradata[i][0]) + "="
- + encodeURIComponent(extradata[i][1] || ""))
- }
- url = url + (url.match(/\?/) ? "&" : "?") + vars.join("&");
- }
-
- var info = this.get(url, callback, {
- async : async,
- userdata : userdata,
- nocache : true,
- data : data,
- useXML : this.useXML
- });
-
- this.stack[this.url] = this.getMulticallObject
- ? this.getMulticallObject()
- : [];
-
- //return info[1];
- }
-
- this.revert = function(modConst){
- this.stack[modConst.url] = this.getMulticallObject
- ? this.getMulticallObject()
- : [];
- }
-
- this.getStackLength = function(){
- return this.stack[this.url] ? this.stack[this.url].length : 0;
- }
-
- /**
- * Loads jml definition
- * @todo opt to rename this to .$loadJml()
- *
- * @attribute {String} url the location of the server that is recipient of the rpc messages.
- * @attribute {String} protocol the name of the plugin that is used to provide the messages.
- * @attribute {Boolean} [multicall] whether the call is stacked until purge() is called.
- * @attribute {Number} [timeout] the number of milliseconds after which the call is considered timed out.
- * @attribute {Boolean} [autoroute] whether the call should be routed through a proxy when a permission error occurs due to the same domein policy.
- * @attribute {Boolean} [async] whether the call is executed in the backround. Default is true. When set to false the application hangs while this call is executed.
- * @attribute {Boolean} [caching] whether the call is cached. Default is false. When set to true any call with the same data will return immediately with the cached result.
- * @define method element specifying a method available within the rpc element.
- * @allowchild variable
- * @attribute {String} name the name of the method. This name will be available on the rpc object as a javascript method.
- * Example:
- * <code>
- * <j:teleport>
- * <j:rpc id="comm" protocol="xmlrpc">
- * <j:method name="save" />
- * </j:rpc>
- * </j:teleport>
- *
- * <j:script>
- * comm.save(data);
- * </j:script>
- * </code>
- * @attribute {String} [url] the location of the server that is recipient of the rpc message.
- * @attribute {String} [callback] the name of the method that handles the return of the call.
- * @attribute {Boolean} [ignore-offline] whether the method should not be stored for later execution when offline.
- * @define variable element specifying an argument of a method in an rpc element.
- * @attribute {String} name the argument name.
- * @attribute {String} [value] the value of the argument.
- * @attribute {String} [default] the default value of the argument. If no value is specified when this function is called, the default value is used.
- */
- this.load = function(x){
- this.$jml = x;
- this.timeout = parseInt(x.getAttribute("timeout")) || this.timeout;
- this.url = jpf.parseExpression(x.getAttribute("url"))
- this.baseurl = jpf.parseExpression(
- jpf.xmldb.getInheritedAttribute(
- this.$jml, "baseurl")) || "";
- this.multicall = x.getAttribute("multicall") == "true";
- this.autoroute = x.getAttribute("autoroute") == "true";
-
- if (this.url)
- this.server = this.url.replace(/^(.*\/\/[^\/]*)\/.*$/, "$1") + "/";
-
- if (this.$load)
- this.$load(x);
-
- var q = x.childNodes;
- for (var url, i = 0; i < q.length; i++) {
- if (q[i].nodeType != 1)
- continue;
-
- if (q[i][jpf.TAGNAME] != "method") {
- throw new Error(jpf.formatErrorString(0, this,
- "Parsing RPC Teleport node",
- "Found element which is not a method", q[i]));
- }
-
- url = jpf.parseExpression(q[i].getAttribute("url"));
- if (url)
- this.urls[q[i].getAttribute("name")] = url;
-
- //Add Method
- this.addMethod(q[i].getAttribute("name"),
- q[i].getAttribute("receive") || x.getAttribute("receive"),
- q[i].getElementsByTagName("*"), //var nodes = $xmlns(q[i], "variable", jpf.ns.jml);
- !jpf.isFalse(q[i].getAttribute("async")),
- jpf.isTrue(q[i].getAttribute("caching")),
- jpf.isTrue(q[i].getAttribute("ignore-offline")));
- }
- }
-
- /*
- * Post a form with ajax
- *
- * @param form form
- * @param function callback Called when http result is received
- * /
- this.submitForm = function(form, callback, callName) {
- this.addMethod('postform', callback);
- this.urls['postform'] = form.action;
- var args = [];
- for (var i = 0; i < form.elements.length; i++) {
- var name = form.elements[i].name.split("[");
- for(var j = 0; j < name.length; j++) {
- //Hmm problem with sequence of names... have to get that from the variable sequence...
- }
- args[] = form.elements[i].value;
- }
-
- this['postform'].apply(this, args);
- }
- */
-}
-
-//instrType, data, options, xmlContext, callback, multicall, userdata, arg, isGetRequest
-jpf.datainstr.rpc = function(xmlContext, options, callback){
- var parsed = options.parsed || this.parseInstructionPart(
- options.instrData.join(":"), xmlContext, options.args, options);
-
- if (options.preparse) {
- options.parsed = parsed;
- options.preparse = -1;
- return;
- }
-
- var args = parsed.arguments;
- var q = parsed.name.split(".");
- var obj = eval(q[0]);
- var method = q[1];
-
- if (!obj)
- throw new Error(jpf.formatErrorString(0, null, "Saving/Loading data",
- "Could not find RPC object by name '" + q[0] + "' in data \
- '" + options.instruction + "'"));
-
- //force multicall if needed;
- if (options.multicall)
- obj.forceMulticall = true;
-
- //Set information later neeed
- if (!obj[method])
- throw new Error(jpf.formatErrorString(0, null, "Saving/Loading data",
- "Could not find RPC function by name '" + method + "' in data \
- instruction '" + options.instruction + "'"));
-
- if (options.userdata)
- obj[method].userdata = options.userdata;
-
- if (!obj.multicall)
- obj[method].callback = callback; //&& obj[method].async
-
- //Call method
- var retvalue = obj.call(method, args, options);
-
- if (obj.multicall)
- return obj.purge(callback, "&@^%!@"); //Warning!! @todo Make multicall work with offline
- else if (options.multicall) {
- obj.forceMulticall = false;
- return obj;
- }
-
- if(typeof jpf.offline != "undefined" && !jpf.offline.onLine)
- return;
-
- //Call callback for sync calls
- if (!obj.multicall && !obj[method].async && callback)
- callback(retvalue);
-}
-
-
- - -/*FILEHEAD(/var/lib/jpf/src/elements/teleport/xmpp.js)SIZE(-1077090856)TIME(1238950356)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * Element implementing XMPP IM protocol.
- * Depends on implementation of XMPP server supporting bosh or http-poll
- *
- * @define xmpp
- * @addnode teleport
- *
- * @author Mike de Boer
- * @version %I%, %G%
- * @since 1.0
- * @constructor
- *
- * @inherits jpf.BaseComm
- * @inherits jpf.http
- * @namespace jpf
- */
-
-jpf.xmpp = function(){
- this.server = null;
- this.timeout = 10000;
- this.useHTTP = true;
- this.method = "POST";
-
- this.oModel = null;
- this.modelContent = null;
- this.TelePortModule = true;
- this.isPoll = false;
-
- if (!this.uniqueId) {
- jpf.makeClass(this);
-
- this.inherit(jpf.BaseComm, jpf.http);
- }
-
- /**
- * Append any string with an underscore '_' followed by a five character
- * long random number sequence.
- *
- * @param {String} s
- * @type {String}
- * @exception {Error} A general Error object
- * @private
- */
- function makeUnique(s) {
- if (typeof s != "string")
- throw new Error('Dependencies not met, please provide a string');
-
- return (s + "_").appendRandomNumber(5);
- }
-
- var _self = this;
- var serverVars = {};
- var bListening = false;
- var tListener = null;
- var sJAV_ID = makeUnique('javRSB');
-
- /**
- * Constructs a <body> tag that will be used according to XEP-0206, and
- * the more official RFCs.
- *
- * @param {Object} options
- * @param {String} content
- * @type {String}
- * @private
- */
- function createBodyTag(options, content) {
- var aOut = ["<body "];
-
- for (var i in options) {
- if (options[i] == null) continue;
- aOut.push(i, "='", options[i], "' ");
- }
-
- aOut.push(">", content || "", "</body>");
-
- return aOut.join('');
- }
-
- /**
- * Constructs a <stream> tag that will be used when polling is active instead
- * of the regular BOSH implementation.
- *
- * @param {String} prepend
- * @param {Object} options
- * @param {String} content
- * @type {String}
- * @private
- */
- function createStreamTag(prepend, options, content) {
- if (!options)
- options = {};
- var aOut = [getVar('SID') || "0", ","];
-
- if (options.doOpen) {
- aOut.push("<stream:stream");
- for (var i in options) {
- if (i == "doOpen" || i == "doClose" || options[i] == null)
- continue;
- aOut.push(" ", i, "='", options[i], "'");
- }
- aOut.push(">");
- }
-
- aOut.push(content || "");
-
- if (options.doClose)
- aOut.push("</stream:stream>");
-
- return aOut.join('');
- }
-
- /**
- * A cnonce parameter is used by the SASL implementation to do some
- * additional client-server key exchange. You can say that this is the
- * part of the handshake that is powered by the client (i.e. 'us').
- *
- * @param {Number} size Length of the cnonce
- * @type {String}
- * @private
- */
- function generateCnonce(size) {
- var sTab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; //length: 62
- var sCnonce = '';
- for (var i = 0; i < size; i++) {
- sCnonce += sTab.charAt(jpf.randomGenerator.generate(0, 61));
- }
- return sCnonce;
- }
-
- /**
- * Create a <response> tag completely according to the SASL rules as
- * described in RFC 2617.
- *
- * @param {Object} parts
- * @type {String}
- * @private
- */
- function createAuthBlock(parts) {
- var aOut = [];
-
- for (var i in parts) {
- if (parts[i] == null) continue;
- aOut.push(i, '="', parts[i], '",');
- }
- var sOut = aOut.join('').replace(/,$/, '');
-
- return "<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
- + jpf.crypto.Base64.encode(sOut) + "</response>";
- }
-
- /**
- * Create an <iq> message node which is part of the XMPP standard base
- * specification and may contain session data, bind/ stream information
- * and presence.
- *
- * @param {Object} parts
- * @param {String} content
- * @type {String}
- * @private
- */
- function createIqBlock(parts, content) {
- var aOut = ['<iq '];
-
- for (var i in parts) {
- if (parts[i] == null) continue;
- aOut.push(i, "='", parts[i], "' ");
- }
-
- aOut.push(">", content || "", "</iq>");
-
- return aOut.join('');
- }
-
- /**
- * Create a <presence> message which is part of the XMPP standard base
- * specification and is used to transfer presence information (state of a
- * user) across the roster.
- *
- * @param {Object} options
- * @type {String}
- * @private
- */
- function createPresenceBlock(options) {
- var aOut = ["<presence xmlns='", jpf.xmpp.NS.jabber, "'"];
- if (options.type)
- aOut.push(" type='", options.type, "'");
- aOut.push('>');
-
- // show An XMPP complient status indicator. See the class constants
- // jpf.xmpp.STATUS_* for options
- if (options.status)
- aOut.push('<show>', options.status, '</show>');
-
- // Usually this is set to some human readable string indicating what the
- // user is doing/ feels like currently.
- if (options.custom)
- aOut.push('<status>', options.custom, '</status>');
-
- aOut.push('</presence>');
- return aOut.join('');
- }
-
- /**
- * Create a <presence> message which is part of the XMPP standard base
- * specification and may contain text messages, usually for instant
- * messaging applications.
- *
- * @param {Object} options
- * @param {String} body
- * @type {String}
- * @private
- */
- function createMessageBlock(options, body) {
- var aOut = ["<message xmlns='", jpf.xmpp.NS.jabber, "' from='", getVar('JID'),
- "' to='", options.to, "' id='message_", register('mess_count',
- parseInt(getVar('mess_count')) + 1), "' xml:lang='", options['xml:lang'], "'"];
- if (options.type)
- aOut.push(" type='", options.type, "'");
- aOut.push('>');
-
- // A subject to be sent along
- if (options.subject)
- aOut.push('<subject>', options.subject, '</subject>');
-
- // This is used to identify threads in chat conversations
- // A thread is usually a somewhat random hash.
- if (options.thread)
- aOut.push('<thread>', options.thread, '</thread>');
-
- aOut.push('<body>', body, '</body></message>');
- return aOut.join('');
- }
-
- /**
- * Simple helper function to store session variables in the private space.
- *
- * @param {String} name
- * @param {mixed} value
- * @type {mixed}
- * @private
- */
- function register(name, value) {
- serverVars[name] = value;
-
- return value;
- }
-
- /**
- * Simple helper function to complete remove variables that have been
- * stored in the private space by register()
- *
- * @param {String} name
- * @type {void}
- * @private
- */
- function unregister() {
- for (var i = 0; i < arguments.length; i++) {
- if (typeof serverVars[arguments[i]] != "undefined") {
- serverVars[arguments[i]] = null;
- delete serverVars[arguments[i]];
- }
- }
- }
-
- /**
- * Simple helper function that retrieves a variable, stored in the private
- * space.
- *
- * @param {String} name
- * @type {mixed}
- * @private
- */
- function getVar(name) {
- return serverVars[name] || "";
- }
-
- /**
- * Special version of getVar('RID'), because RID needs to upped by one each
- * time a request is sent to the XMPP server.
- *
- * @type {Number}
- * @private
- */
- function getRID() {
- return register('RID', getVar('RID') + 1);
- }
-
- /**
- * Generic function that provides a basic method for making HTTP calls to
- * the XMPP server and processing the response in retries, error messages
- * or through a custom callback.
- *
- * @param {Function} callback
- * @param {String} body
- * @param {Boolean} isUserMessage Specifies whether this message is a
- * message sent over the established connection or a protocol message.
- * The user messages are recorded when offline and sent when the
- * application comes online again.
- * @exception {Error} A general Error object
- * @type {XMLHttpRequest}
- */
- this.doXmlRequest = function(callback, body) {
- return this.get(this.server,
- function(data, state, extra) {
- if (_self.isPoll) {
- if (!data || data.replace(/^[\s\n\r]+|[\s\n\r]+$/g, "") == "") {
- //state = jpf.ERROR;
- //extra.message = (extra.message ? extra.message + "\n" : "")
- // + "Received an empty XML document (0 bytes)";
- }
- else {
- if (data.indexOf('<stream:stream') > -1
- && data.indexOf('</stream:stream>') == -1)
- data = data + "</stream:stream>";
- data = jpf.getXmlDom(data);
- if (!jpf.supportNamespaces)
- data.setProperty("SelectionLanguage", "XPath");
- }
- }
-
- if (state != jpf.SUCCESS) {
- var oError;
-
- oError = new Error(jpf.formatErrorString(0,
- _self, "XMPP Communication error",
- "Url: " + extra.url + "\nInfo: " + extra.message));
-
- if (typeof callback == "function") {
- callback.call(_self, data, state, extra);
- return true;
- }
- else if (extra.tpModule.retryTimeout(extra, state, _self, oError) === true)
- return true;
-
- onError(jpf.xmpp.ERROR_CONN, extra.message, state); //@TBD:Mike please talk to me about how to integrate onError() properly
- throw oError;
- }
-
- if (typeof callback == "function")
- callback.call(_self, data, state, extra);
- }, {
- nocache : true,
- useXML : !this.isPoll,
- ignoreOffline : true,
- data : body || ""
- });
- };
-
- /**
- * ERROR_AUTH: Something went wrong during the authentication process; this function
- * provides a central mechanism for dealing with this situation
- *
- * ERROR_CONN: Our connection to the server has dropped, or the XMPP server can not be
- * reached at the moment. We will cancel the authentication process and
- * dispatch a 'connectionerror' event
- *
- * @param {Number} nType Type of the error (jpf.xmpp.ERROR_AUTH or jpf.xmpp.ERROR_CONN)
- * @param {String} sMsg Error message/ description. Optional.
- * @param {Number} nState State of the http connection. Optional, defaults to jpf.ERROR.
- * @type {Boolean}
- * @private
- */
- function onError(nType, sMsg, nState) {
- jpf.console.log('[XMPP-' + (nType & jpf.xmpp.ERROR_AUTH
- ? 'AUTH'
- : 'CONN') + '] onError called.', 'xmpp');
- clearTimeout(tListener);
- tListener = null;
- unregister('password');
-
- var extra = {
- username : getVar('username'),
- server : _self.server,
- message : sMsg || (nType & jpf.xmpp.ERROR_AUTH
- ? "Access denied. Please check your username or password."
- : "Could not connect to server, please contact your System Administrator.")
- }
-
- var cb = getVar('login_callback');
- if (cb) {
- unregister('login_callback');
- return cb(null, nState || jpf.ERROR, extra);
- }
-
- jpf.console.error(extra.message + ' (username: ' + extra.username
- + ', server: ' + extra.server + ')', 'xmpp');
-
- return _self.dispatchEvent(nType & jpf.xmpp.ERROR_AUTH
- ? "authfailure"
- : "connectionerror", extra);
- }
-
- /**
- * Connect to the XMPP server with a username and password combination
- * provided.
- *
- * @param {String} username
- * @param {String} password
- * @type {void}
- */
- this.connect = function(username, password, callback) {
- this.reset();
-
- register('username', username);
- register('password', password);
- register('login_callback', callback);
- getVar('roster').registerAccount(username, this.domain);
-
- this.doXmlRequest(processConnect, this.isPoll
- ? createStreamTag(null, {
- doOpen : true,
- to : _self.domain,
- xmlns : jpf.xmpp.NS.jabber,
- 'xmlns:stream' : jpf.xmpp.NS.stream,
- version : '1.0'
- })
- : createBodyTag({
- content : 'text/xml; charset=utf-8',
- hold : '1',
- rid : getVar('RID'),
- to : _self.domain,
- route : 'xmpp:jabber.org:9999',
- secure : 'true',
- wait : '120',
- ver : '1.6',
- 'xml:lang' : 'en',
- 'xmpp:version' : '1.0',
- xmlns : jpf.xmpp.NS.httpbind,
- 'xmlns:xmpp' : jpf.xmpp.NS.bosh
- })
- );
- };
-
- /**
- * Disconnect from the XMPP server. It suspends the connection with the
- * 'pause' attribute when using BOSH. Poll-based connection only need to
- * stop polling.
- *
- * @type {void}
- */
- this.disconnect = function() {
- if (getVar('connected')) {
- this.doXmlRequest(processDisconnect, this.isPoll
- ? createStreamTag(null, {
- doClose: true
- })
- : createBodyTag({
- pause : 120,
- rid : getRID(),
- sid : getVar('SID'),
- xmlns : jpf.xmpp.NS.httpbind
- })
- );
- }
- else
- this.reset();
- };
-
- /**
- * Set all session variables to NULL, so the element may create a new
- * XMPP connection.
- *
- * @type {void}
- */
- this.reset = function() {
- // unregister ALL variables with a trick:
- for (var i in serverVars)
- unregister(i);
- //if (this.oModel)
- //this.oModel.load('<xmpp/>')
-
- // apply some initial values to the serverVars global scoped Array
- register('RID', parseInt("".appendRandomNumber(10)));
- register('cnonce', generateCnonce(14));
- register('nc', '00000001');
- register('bind_count', 1);
- register('connected', false);
- register('roster', new jpf.xmpp.Roster(this.oModel, this.modelContent, this.resource));
- register('mess_count', 0);
- };
-
- /**
- * A new stream has been created, now we need to process the response body.
- *
- * Example:
- * <body xmpp:version='1.0'
- * authid='ServerStreamID'
- * xmlns='http://jabber.org/protocol/httpbind'
- * xmlns:xmpp='urn:xmpp:xbosh'
- * xmlns:stream='http://etherx.jabber.org/streams'>
- * <stream:features>
- * <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
- * <mechanism>DIGEST-MD5</mechanism>
- * <mechanism>PLAIN</mechanism>
- * </mechanisms>
- * </stream:features>
- * </body>
- *
- * @param {Object} oXml
- * @param {Number} state
- * @param {mixed} extra
- * @type {void}
- * @private
- */
- function processConnect(oXml, state, extra) {
- if (state != jpf.SUCCESS)
- return onError(jpf.xmpp.ERROR_CONN, extra.message, state);
-
- //jpf.xmldb.getXml('<>'); <-- one way to convert XML string to DOM
- if (!this.isPoll) {
- register('SID', oXml.getAttribute('sid'));
- register('AUTH_ID', oXml.getAttribute('authid'));
- }
- else {
- var aCookie = extra.http.getResponseHeader('Set-Cookie').splitSafe(';');
- register('SID', aCookie[0].splitSafe('=')[1])
- register('AUTH_ID', oXml.firstChild.getAttribute('id'));
- }
-
- var aMechanisms = oXml.getElementsByTagName('mechanism');
- var found = false;
- for (var i = 0; i < aMechanisms.length && !found; i++) {
- // PLAIN type challenge not supported by us: insecure!!
- if (aMechanisms[i].firstChild.nodeValue == "DIGEST-MD5") {
- register('AUTH_TYPE', 'DIGEST-MD5');
- found = true;
- }
- }
-
- if (!found)
- return onError(jpf.xmpp.ERROR_AUTH, "No supported authentication protocol found. We cannot continue!");
-
- // start the authentication process by sending a request
- var sAuth = "<auth xmlns='" + jpf.xmpp.NS.sasl + "' mechanism='" + getVar('AUTH_TYPE') + "'/>";
- this.doXmlRequest(processAuthRequest, this.isPoll
- ? createStreamTag(null, null, sAuth)
- : createBodyTag({
- rid : getRID(),
- sid : getVar('SID'),
- xmlns : jpf.xmpp.NS.httpbind
- }, sAuth)
- );
- }
-
- /**
- * The connection has been terminated (set to state 'paused'). Theoretically
- * it could be resumed, but doing a complete reconnect would be more secure
- * and stable for RSB and other implementations that rely on stable stream
- * traffic.
- *
- * Example:
- * @todo: put the spec response here...
- *
- * @param {Object} oXml
- * @type {void}
- * @private
- */
- function processDisconnect(oXml) {
- jpf.console.dir(oXml);
- this.reset();
- }
-
- /**
- * Check the response from the server to a challenge our connection manager
- * set up. When a <failure> node is detected, it means that the challenge
- * failed and thereby the authentication as well.
- *
- * @param {XMLDom} oXml
- * @type {Boolean}
- * @private
- */
- function processChallenge(oXml) {
- if (oXml.getElementsByTagName('failure').length)
- return false; // authentication failed!
-
- var oChallenge = oXml.getElementsByTagName("challenge")[0];
- if (oChallenge) {
- var b64_challenge = oChallenge.firstChild.nodeValue;
- var aParts = jpf.crypto.Base64.decode(b64_challenge).split(',');
-
- for (var i = 0; i < aParts.length; i++) {
- var aChunk = aParts[i].split('=');
- register(aChunk[0], aChunk[1].trim().replace(/[\"\']/g, ''));
- }
-
- jpf.console.info('processChallenge: ' + aParts.join(' '), 'xmpp');
- }
-
- return true;
- }
-
- /**
- * The first challenge result should be be processed here and the second
- * challenge is sent to the server
- *
- * Response example:
- * <body xmlns='http://jabber.org/protocol/httpbind'>
- * <challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
- * cmVhbG09InNvbWVyZWFsbSIsbm9uY2U9Ik9BNk1HOXRFUUdtMmhoIixxb3A9
- * ImF1dGgiLGNoYXJzZXQ9dXRmLTgsYWxnb3JpdGhtPW1kNS1zZXNzCg==
- * </challenge>
- * </body>
- *
- * @param {Object} oXml
- * @type {void}
- * @private
- */
- function processAuthRequest(oXml) {
- if (!processChallenge(oXml))
- return onError(jpf.xmpp.ERROR_AUTH);
-
- if (!getVar('realm'))
- register('realm', ''); //DEV: option to provide realm with a default
-
- if (getVar('realm'))
- register('digest_uri', 'xmpp/' + getVar('realm'));
-
- // for the calculations of A1, A2 and sResp below, take a look at
- // RFC 2617, Section 3.2.2.1
- var A1 = jpf.crypto.MD5.str_md5(getVar('username') + ':' + getVar('realm')
- + ':' + getVar('password')) // till here we hash-up with MD5
- + ':' + getVar('nonce') + ':' + getVar('cnonce');
-
- var A2 = 'AUTHENTICATE:' + getVar('digest_uri');
-
- var sResp = jpf.crypto.MD5.hex_md5(jpf.crypto.MD5.hex_md5(A1) + ':'
- + getVar('nonce') + ':' + getVar('nc') + ':' + getVar('cnonce')
- + ':' + getVar('qop') + ':' + jpf.crypto.MD5.hex_md5(A2));
-
- jpf.console.info("response: " + sResp, 'xmpp');
-
- var sAuth = createAuthBlock({
- username : getVar('username'),
- realm : getVar('realm'),
- nonce : getVar('nonce'),
- cnonce : getVar('cnonce'),
- nc : getVar('nc'),
- qop : getVar('qop'),
- digest_uri : getVar('digest_uri'),
- response : sResp,
- charset : getVar('charset')
- });
- this.doXmlRequest(processFinalChallenge, _self.isPoll
- ? createStreamTag(null, null, sAuth)
- : createBodyTag({
- rid : getRID(),
- sid : getVar('SID'),
- xmlns : jpf.xmpp.NS.httpbind
- }, sAuth)
- );
- }
-
- /**
- * The second a last part of the authentication process (handshake) should
- * be processed here. If the handshake was successful, we can close the
- * authentication/ handshake process.
- *
- * Response example:
- * <body xmlns='http://jabber.org/protocol/httpbind'>
- * <challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
- * cnNwYXV0aD1lYTQwZjYwMzM1YzQyN2I1NTI3Yjg0ZGJhYmNkZmZmZAo=
- * </challenge>
- * </body>
- *
- * @param {Object} oXml
- * @type {void}
- * @private
- */
- function processFinalChallenge(oXml) {
- // register the variables that are inside the challenge body
- // (probably only 'rspauth')
- if (!processChallenge(oXml))
- return onError(jpf.xmpp.ERROR_AUTH);
-
- // the spec requires us to clear the password from our system(s)
- unregister('password');
-
- var sAuth = createAuthBlock({});
- this.doXmlRequest(reOpenStream, _self.isPoll
- ? createStreamTag(null, null, sAuth)
- : createBodyTag({
- rid : getRID(),
- sid : getVar('SID'),
- xmlns : jpf.xmpp.NS.httpbind
- }, sAuth)
- );
- }
-
- /**
- * Check if the authentication process has been closed and confirmed by the
- * XMPP server. If successful, we can start listening for incoming messages.
- *
- * Response example:
- * <body xmlns='http://jabber.org/protocol/httpbind'>
- * <success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>
- * </body>
- *
- * @param {Object} oXml
- * @type {void}
- * @private
- */
- function reOpenStream(oXml) {
- if (!processChallenge(oXml))
- return onError(jpf.xmpp.ERROR_AUTH);
-
- //restart the stream request
- this.doXmlRequest(function(oXml) {
- if (_self.isPoll || oXml.getElementsByTagName('bind').length) {
- // Stream restarted OK, so now we can actually start listening to messages!
- _self.bind();
- }
- }, _self.isPoll
- ? createStreamTag(null, {
- doOpen : true,
- to : _self.domain,
- xmlns : jpf.xmpp.NS.jabber,
- 'xmlns:stream' : jpf.xmpp.NS.stream,
- version : '1.0'
- })
- : createBodyTag({
- rid : getRID(),
- sid : getVar('SID'),
- to : _self.domain,
- 'xml:lang' : 'en',
- 'xmpp:restart' : 'true',
- xmlns : jpf.xmpp.NS.httpbind,
- 'xmlns:xmpp' : jpf.xmpp.NS.bosh
- })
- );
- }
-
- /**
- * Tell the XMPP server that the authentication/ handshake has been completed
- * and that we want to start listening for messages for this user.
- *
- * @type {void}
- */
- this.bind = function() {
- var sIq = createIqBlock({
- id : 'bind_' + register('bind_count', parseInt(getVar('bind_count')) + 1),
- type : 'set',
- xmlns : this.isPoll ? null : jpf.xmpp.NS.jabber
- },
- "<bind xmlns='" + jpf.xmpp.NS.bind + "'>" +
- "<resource>" + this.resource + "</resource>" +
- "</bind>"
- );
- this.doXmlRequest(processBindingResult, _self.isPoll
- ? createStreamTag(null, null, sIq)
- : createBodyTag({
- rid : getRID(),
- sid : getVar('SID'),
- xmlns : jpf.xmpp.NS.httpbind
- }, sIq)
- );
- };
-
- /**
- * Checks if the request to bind the message stream with the the current
- * user was successful and if YES, then we store the full Jabber ID (JID)
- * and can start listening for incoming messages.
- *
- * Response example:
- * <body xmlns='http://jabber.org/protocol/httpbind'>
- * <iq id='bind_1'
- * type='result'
- * xmlns='jabber:client'>
- * <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>
- * <jid>stpeter@jabber.org/httpclient</jid>
- * </bind>
- * </iq>
- * </body>
- *
- * @param {Object} oXml
- * @type {void}
- * @private
- */
- function processBindingResult(oXml) {
- var oJID = oXml.getElementsByTagName('jid')[0];
- if (oJID) {
- register('JID', oJID.firstChild.nodeValue);
- var sIq = createIqBlock({
- from : getVar('JID'),
- id : sJAV_ID,
- to : _self.domain,
- type : 'set',
- xmlns : jpf.xmpp.NS.jabber
- },
- "<session xmlns='" + jpf.xmpp.NS.session + "'/>"
- );
- _self.doXmlRequest(function(oXml) {
- parseData(oXml);
- setInitialPresence();
- }, _self.isPoll
- ? createStreamTag(null, null, sIq)
- : createBodyTag({
- rid : getRID(),
- sid : getVar('SID'),
- xmlns : jpf.xmpp.NS.httpbind
- }, sIq)
- );
- }
- else {
- //@todo: check for binding failures!
- onError(jpf.xmpp.ERROR_AUTH);
- }
- }
-
- /**
- * On connect, the presence of the user needs to be broadcasted to all the
- * nodes in the roster to 'available' (or whatever the default status is).
- * The response of this presence callback is also the indicator for any
- * successful login sequence.
- *
- * @type {void}
- * @private
- */
- function setInitialPresence() {
- // NOW only we set the actual presence tag!
- var sPresence = createPresenceBlock({
- type: jpf.xmpp.TYPE_AVAILABLE
- });
- _self.doXmlRequest(function(oXml) {
- register('connected', true);
- _self.dispatchEvent('connected', {username: getVar('username')});
- parseData(oXml);
- getRoster();
- }, _self.isPoll
- ? createStreamTag(null, null, sPresence)
- : createBodyTag({
- rid : getRID(),
- sid : getVar('SID'),
- xmlns : jpf.xmpp.NS.httpbind
- }, sPresence)
- );
- }
-
- /**
- * Retrieve the roster information from the XMPP server. The roster contains
- * a list of nodes to which user has subscribed to. Each roster item will
- * contain presence information and optionally group metadata.
- * Generally, this data is only used for IM applications (see RFC 3921,
- * Section 7.2).
- * This function SHOULD only be called on login.
- *
- * @type {void}
- * @private
- */
- function getRoster() {
- var sIq = createIqBlock({
- from : getVar('JID'),
- type : 'get',
- id : makeUnique('roster')
- },
- "<query xmlns='" + jpf.xmpp.NS.roster + "'/>"
- );
- _self.doXmlRequest(function(oXml) {
- parseData(oXml);
- _self.listen();
- var cb = getVar('login_callback');
- if (cb) {
- cb(null, jpf.SUCCESS, {
- username : getVar('username')
- });
- unregister('login_callback');
- }
- }, _self.isPoll
- ? createStreamTag(null, null, sIq)
- : createBodyTag({
- rid : getRID(),
- sid : getVar('SID'),
- xmlns : jpf.xmpp.NS.httpbind
- }, sIq)
- );
- }
-
- /**
- * Open a PUSH connection to the XMPP server and wait for messages to
- * arrive (i.e. 'listen' to the stream).
- * Internal locking prevents us from firing more than one listener at a time.
- *
- * @type {void}
- */
- this.listen = function() {
- if (bListening === true) return;
-
- bListening = true;
-
- jpf.console.info('XMPP: Listening for messages...', 'xmpp');
-
- this.doXmlRequest(processStream, _self.isPoll
- ? createStreamTag()
- : createBodyTag({
- rid : getRID(),
- sid : getVar('SID'),
- xmlns : jpf.xmpp.NS.httpbind
- }, "")
- );
- };
-
- /**
- * If there is no proof that the 'listener' thread (or http connection) is
- * still open, reconnect it after the current callback sequence has completed
- * (hence the 'setTimeout' call).
- *
- * @see teleport.xmpp.methodlisten
- * @type {void}
- * @private
- */
- function restartListener() {
- clearTimeout(tListener);
- tListener = null;
- if (arguments.length) {
- if (arguments[1] != jpf.SUCCESS)
- return onError(jpf.xmpp.ERROR_CONN, arguments[2].message, arguments[1]);
- else
- parseData(arguments[0]);
- }
-
- if (getVar('connected') && !bListening)
- tListener = setTimeout(function() {
- _self.listen();
- }, _self.pollTimeout || 0);
- }
-
- /**
- * Handle the result of the stream listener and messages that arrived need
- * to be processed.
- *
- * @param {Object} oXml
- * @type {void}
- * @private
- */
- function processStream(oXml) {
- clearTimeout(tListener);
- tListener = null;
- parseData(oXml);
-
- var bNoListener = (bListening === false); //experimental
- bListening = false;
-
- // start listening again...
- if (getVar('connected') && !bNoListener)
- tListener = setTimeout(function() {
- _self.listen();
- }, _self.pollTimeout || 0);
- }
-
- /**
- * Parse the XML envelope received from the XMPP server. Since one XML
- * envelope may contain more than one message type, no if...else block can
- * be found (we check for all possible message types).
- *
- * @param {Object} oXml
- * @type {void}
- * @private
- */
- function parseData(oXml) {
- if (oXml && oXml.nodeType) {
- // do other stuff... like processing the messages? :P
- var aMessages = oXml.getElementsByTagName('message');
- if (aMessages.length)
- parseMessagePackets(aMessages);
-
- var aPresence = oXml.getElementsByTagName('presence');
-
- jpf.console.info('Number of <PRESENCE> elements: ' + aPresence.length, 'xmpp');
-
- if (aPresence.length)
- parsePresencePackets(aPresence);
-
- var aIQs = oXml.getElementsByTagName('iq');
- if (aIQs.length)
- parseIqPackets(aIQs);
- }
- else {
- if (!_self.isPoll)
- onError(jpf.xmpp.ERROR_CONN, null, jpf.OFFLINE);
- //jpf.console.warn('!!!!! Exceptional state !!!!!', 'xmpp');
- }
- }
-
- /**
- * One or more (instant-)messages have are arrived that need to be processed
- * and parsed to eventually show up in the GUI
- *
- * @see teleport.xmpp.methodparseData
- * @param {Array} aMessages
- * @type {void}
- * @private
- */
- function parseMessagePackets(aMessages) {
- var i, sJID, oUser, oBody;
-
- for (i = 0; i < aMessages.length; i++) {
- sJID = aMessages[i].getAttribute('from');
- if (sJID)
- oUser = getVar('roster').getUserFromJID(sJID); //unsed var...yet?
-
- if (aMessages[i].getAttribute('type') == "chat") {
- oBody = aMessages[i].getElementsByTagName('body')[0];
- if (oBody && oBody.firstChild) {
- jpf.console.log('XMPP incoming chat message: ' + oBody.firstChild.nodeValue, 'xmpp');
- var sFrom = aMessages[i].getAttribute('from');
- var sMsg = oBody.firstChild.nodeValue
- if (getVar('roster').updateMessageHistory(sFrom, sMsg)) {
- _self.dispatchEvent('receivechat', {
- from : sFrom,
- message: sMsg
- });
- }
- }
- }
- else if (aMessages[i].getAttribute('type') == "normal") { //normal = Remote SmartBindings
- oBody = aMessages[i].getElementsByTagName('body')[0];
- if (oBody && oBody.firstChild) {
- //Remote SmartBindings support
-
- jpf.console.info('received the following from the server: '
- + oBody.firstChild.nodeValue.replace(/\"/g, '"'), 'xmpp');
-
- _self.dispatchEvent('datachange', {
- data: oBody.firstChild.nodeValue.replace(/\"/g, '"')
- });
- }
- }
- }
- }
-
- /**
- * One or more Presence messages have arrived that indicate something has
- * changed in the roster, e.g. the status of a node changed, a node was
- * disconnected, etc. All of these messages will update the local Roster.
- *
- * @see teleport.xmpp.methodparseData
- * @param {Array} aPresence
- * @type {void}
- * @private
- */
- function parsePresencePackets(aPresence) {
- jpf.console.info('parsePresencePacket: ' + aPresence.length, 'xmpp');
-
- for (var i = 0; i < aPresence.length; i++) {
- var sJID = aPresence[i].getAttribute('from');
- if (sJID) {
- var oUser = getVar('roster').getUserFromJID(sJID);
- // record any status change...
- if (oUser)
- getVar('roster').update(oUser,
- aPresence[i].getAttribute('type') || jpf.xmpp.TYPE_AVAILABLE);
- }
- }
- }
-
- /**
- * One or more Iq messages have arrived that notify the user of system wide
- * events and results of its actions, e.g. the failure or success of setting
- * presence, connection errors, probe for supported features of nodes results,
- * etc.
- *
- * @see teleport.xmpp.methodparseData
- * @param {Array} aIQs
- * @type {void}
- * @private
- */
- function parseIqPackets(aIQs) {
- jpf.console.info('parseIqPacket: ' + aIQs.length, 'xmpp');
-
- for (var i = 0; i < aIQs.length; i++) {
- if (aIQs[i].getAttribute('type') != "result") continue;
- var aQueries = aIQs[i].getElementsByTagName('query');
- for (var j = 0; j < aQueries.length; j++) {
- //@todo: support more query types...whenever we need them
- switch (aQueries[j].getAttribute('xmlns')) {
- case jpf.xmpp.NS.roster:
- var aItems = aQueries[j].getElementsByTagName('item');
- var oRoster = getVar('roster');
- for (var k = 0; k < aItems.length; k++) {
- //@todo: should we do something with the 'subscription' attribute?
- var sGroup = (aItems[k].childNodes.length > 0)
- ? aItems[k].firstChild.firstChild.nodeValue
- : "";
- oRoster.getUserFromJID(aItems[k].getAttribute('jid'), sGroup)
- }
- break;
- default:
- break;
- }
- }
- }
- }
-
- /**
- * Provides the ability to change the presence of the user on the XMPP
- * network to any of the types in the following format:
- * 'jpf.xmpp.STATUS_*'
- *
- * @param {String} type Status type according to the RFC
- * @param {String} status Message describing the status
- * @param {String} custom Custom status type
- * @type {void}
- * @public
- */
- this.setPresence = function(type, status, custom) {
- if (!getVar('connected')) return false;
-
- this.doXmlRequest(restartListener, createBodyTag({
- rid : getRID(),
- sid : getVar('SID'),
- xmlns : jpf.xmpp.NS.httpbind
- },
- createPresenceBlock({
- type : type || jpf.xmpp.TYPE_AVAILABLE,
- status: status,
- custom: custom
- }))
- );
- };
-
- /**
- * Provides the ability to send a (chat-)message to any node inside the user's
- * Roster. If the 'type' property is set, it must be one of the constants in
- * the following format:
- * 'jpf.xmpp.MSG_*'
- *
- * @param {String} to Must be of the format 'node@domainname.ext'
- * @param {String} message
- * @param {String} thread Optional.
- * @param {String} type Optional.
- * @type {void}
- */
- this.sendMessage = function(to, message, thread, type, callback) {
- if (!message) return false;
-
- /*
- Note: This mechanism can also be used to only sent chat messages
- to only contacts. This can be more useful than using XMPP's server
- storage solution, because of the feedback to user.
- */
- if (typeof jpf.offline != "undefined" && !jpf.offline.onLine) {
- if (jpf.offline.queue.enabled) {
- //Let's record all the necesary information for future use (during sync)
- var info = {
- to : to,
- message : message,
- thread : thread,
- callback : callback,
- type : type,
- retry : function(){
- _self.sendMessage(this.to, this.message,
- this.thread, this.type, this.callback);
- },
- $object : [this.name, "new jpf.xmpp()"],
- $retry : "this.object.sendMessage(this.to, this.message, \
- this.thread, this.type, this.callback)"
- };
-
- jpf.offline.queue.add(info);
-
- return;
- }
-
- /*
- Apparently we're doing an XMPP call even though we're offline
- I'm allowing it, because the developer seems to know more
- about it than I right now
- */
-
- jpf.console.warn("Trying to sent XMPP message even though \
- application is offline.", 'xmpp');
- }
-
- if (!getVar('connected')) return false;
-
- var oUser;
- if (!to) { //What is the purpose of this functionality? (Ruben)
- oUser = getVar('roster').getLastAvailableUser();
- to = oUser.jid;
- }
- if (!to) return false; //finally: failure :'(
-
- if (!oUser)
- oUser = getVar('roster').getUserFromJID(to);
-
- this.doXmlRequest(function(data, state, extra){
- if (callback)
- callback.call(this, data, state, extra)
-
- restartListener(data, state, extra);
- },
- createBodyTag({
- rid : getRID(),
- sid : getVar('SID'),
- xmlns : jpf.xmpp.NS.httpbind
- },
- createMessageBlock({
- type : type || jpf.xmpp.MSG_CHAT,
- to : oUser.node + '@' + oUser.domain + '/' + this.resource,
- thread : thread,
- 'xml:lang' : 'en'
- },
- "<![CDATA[" + message + "]]>"))
- );
- };
-
- /**
- * Makes sure that a few header are sent along with all the requests to the
- * XMPP server. This function overrides the abstract found in jpf.http
- *
- * @see teleport.http
- * @param {Object} http
- * @type {void}
- */
- this.$HeaderHook = function(http) {
- http.setRequestHeader('Host', this.domain);
- if (this.isPoll) {
-// if (http.overrideMimeType)
-// http.overrideMimeType('text/plain; charset=utf-8');
- http.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
- }
- else {
- http.setRequestHeader('Content-type', 'text/xml; charset=utf-8');
- }
- };
-
- /**
- * This is the connector function between the JML representation of this
- * Teleport module. If specified, it will also setup the Remote SmartBinding
- * feature.
- *
- * Sample JML:
- * <j:teleport>
- * <j:xmpp id="myXMPP" url="http://jabber.org:5280/http-bind" roster-model="myRoster" connection="poll|bosh" />
- * </j:teleport>
- *
- * @param {XMLDom} x An XML document element that contains xmpp metadata
- * @type {void}
- * @exception {Error} A general Error object
- */
- this.load = function(x){
- this.server = x.getAttribute('url');
- var i, url = new jpf.url(this.server);
-
- // do some extra startup/ syntax error checking
- if (!url.host || !url.port || !url.protocol)
- throw new Error(jpf.formatErrorString(0, this,
- "XMPP initialization error",
- "Invalid XMPP server url provided."));
-
- this.domain = url.host;
- this.tagName = "xmpp";
-
- this.xmppMethod = (x.getAttribute('connection') == "poll")
- ? jpf.xmpp.CONN_POLL
- : jpf.xmpp.CONN_BOSH;
-
- this.isPoll = Boolean(this.xmppMethod & jpf.xmpp.CONN_POLL);
- if (this.isPoll)
- this.pollTimeout = parseInt(x.getAttribute("poll-timeout")) || 2000;
-
- this.timeout = parseInt(x.getAttribute("timeout")) || this.timeout;
- this.resource = x.getAttribute('resource') || jpf.appsettings.name;
-
- // provide a virtual Model to make it possible to bind with this XMPP
- // instance remotely.
- // We agreed on the following format for binding: model-contents="roster|typing|chat"
- var sModel = x.getAttribute('model');
- var aContents = (x.getAttribute('model-contents') || "all").splitSafe('\\|', 0, true);
- this.modelContent = {
- roster: aContents[0] == "all",
- chat : aContents[0] == "all",
- typing: aContents[0] == "all"
- };
- for (i = 0; i < aContents.length; i++) {
- aContents[i] = aContents[i].trim();
- if (!this.modelContent[aContents[i]])
- this.modelContent[aContents[i]] = true;
- }
- if (sModel && aContents.length) {
- this.oModel = jpf.setReference(sModel,
- jpf.nameserver.register("model", sModel, new jpf.model()));
- // set the root node for this model
- this.oModel.id =
- this.oModel.name = sModel;
- this.oModel.load('<xmpp/>');
- }
-
- // parse any custom events formatted like 'onfoo="doBar();"'
- var attr = x.attributes;
- for (i = 0; i < attr.length; i++) {
- if (attr[i].nodeName.indexOf("on") == 0)
- this.addEventListener(attr[i].nodeName,
- new Function(attr[i].nodeValue));
- }
- };
-};
-
-/**
- * Element implementing a Roster service for the jpf.xmpp object.
- * The Roster is a centralised registry for Jabber ID's (JID) to which
- * the user subscribed. Whenever the presence info of a JID changes, the roster
- * will get updated accordingly.
- *
- * @author Mike de Boer
- * @version %I%, %G%
- * @since 1.0
- * @classDescription This class intantiates a new XMPP Roster object
- * @return {jpf.xmpp.Roster} A new XMPP Roster object
- * @type {Object}
- * @constructor
- */
-jpf.xmpp.Roster = function(model, modelContent, resource) {
- this.resource = resource;
- this.username = this.domain = "";
-
- var aUsers = [];
-
- this.registerAccount = function(username, domain) {
- this.username = username || "";
- this.domain = domain || "";
- };
-
- /**
- * Lookup function; searches for a JID with node object, domain and/ or
- * resource info provided.
- * It may return an collection of JID's when little info to search with is
- * provided.
- *
- * @param {String} node
- * @param {String} domain
- * @param {String} resource
- * @type {mixed}
- */
- this.getUser = function(node, domain, resource) {
- if (typeof node == "undefined") return null;
-
- var aResult = [];
-
- // the code below is just a failsafe for user items that arrive through
- // an <IQ> query for a roster.
- if (node.indexOf('@') != -1) {
- var aTemp = node.split('@');
- node = aTemp[0];
- domain = aTemp[1];
- }
-
- var bDomain = (typeof domain != "undefined");
- var bResource = (typeof resource != "undefined");
-
- var sJID = node + (bDomain ? '@' + domain : '')
- + (bResource ? '/' + resource : '');
-
- for (var i = 0; i < aUsers.length; i++) {
- if (aUsers[i].jid.indexOf(sJID) === 0)
- aResult.push(aUsers[i]);
- }
-
- if (aResult.length === 0) return null;
-
- return (aResult.length == 1) ? aResult[0] : aResult;
- };
-
- /**
- * Lookup function; searches for a JID object with JID info provided in the
- * following, common, XMPP format: 'node@domain/resource'
- *
- * @param {String} jid
- * @type {Object}
- */
- this.getUserFromJID = function(jid) {
- var resource = "", node;
- var sGroup = (arguments.length > 1) ? arguments[1] : "";
-
- if (jid.indexOf('/') != -1) {
- resource = jid.substring(jid.indexOf('/') + 1) || "";
- jid = jid.substring(0, jid.indexOf('/'));
- }
- if (jid.indexOf('@') != -1) {
- node = jid.substring(0, jid.indexOf('@'));
- jid = jid.substring(jid.indexOf('@') + 1);
- }
- var domain = jid;
-
- var oUser = this.getUser(node, domain);//, resource);
-
- // Auto-add new users with status TYPE_UNAVAILABLE
- // Status TYPE_AVAILABLE only arrives with <presence> messages
- if (!oUser && node && domain) {
- // @todo: change the user-roster structure to be more 'resource-agnostic'
- resource = resource || this.resource;
- oUser = this.update({
- node : node,
- domain : domain,
- resources: [resource],
- jid : node + '@' + domain + '/' + resource,
- group : sGroup,
- status : jpf.xmpp.TYPE_UNAVAILABLE
- });
- }
- else if (oUser && oUser.group !== sGroup)
- oUser.group = sGroup;
-
- //fix a missing 'resource' property...
- if (resource && oUser && !oUser.resources.contains(resource)) {
- oUser.resources.push(resource);
- oUser.jid = node + '@' + domain + '/' + resource
- }
-
- return oUser;
- };
-
- /**
- * When a JID is added, deleted or updated, it will pass this function that
- * marshalls the Roster contents.
- * It ensures that the Remote SmartBindings link with a model is synchronized
- * at all times.
- *
- * @param {Object} oUser
- * @type {Object}
- */
- this.update = function(oUser) {
- if (!this.getUser(oUser.node, oUser.domain, oUser.resource)) {
- var bIsAccount = (oUser.node == this.username
- && oUser.domain == this.domain);
- aUsers.push(oUser);
- //Remote SmartBindings: update the model with the new User
- if (model && modelContent.roster) {
- oUser.xml = model.data.ownerDocument.createElement(bIsAccount ? 'account' : 'user');
- this.updateUserXml(oUser);
- jpf.xmldb.appendChild(model.data, oUser.xml);
- }
- }
-
- if (arguments.length > 1)
- oUser.status = arguments[1];
-
- // update all known properties for now (bit verbose, might be changed
- // in the future)
- return this.updateUserXml(oUser);
- };
-
- var userProps = ['node', 'domain', 'resource', 'jid', 'status'];
- /**
- * Propagate any change in the JID to the model to which the XMPP connection
- * is attached.
- *
- * @param {Object} oUser
- * @type {Object}
- */
- this.updateUserXml = function(oUser) {
- if (!oUser || !oUser.xml) return null;
- userProps.forEach(function(item) {
- oUser.xml.setAttribute(item, oUser[item]);
- });
- jpf.xmldb.applyChanges('synchronize', oUser.xml);
-
- return oUser;
- };
-
- /**
- * Append incoming chat messages to the user XML element, so they are
- * accessible to the model.
- *
- * @param {String} sJID The Jabber Identifier of the sender
- * @param {String} sMsg The actual message
- * @type {void}
- */
- this.updateMessageHistory = function(sJID, sMsg) {
- if (!model || !modelContent.chat) return;
-
- var oUser = this.getUserFromJID(sJID);
- if (!oUser || !oUser.xml) return;
-
- var oDoc = model.data.ownerDocument;
- var oMsg = oDoc.createElement('message');
- oMsg.setAttribute("from", sJID);
- oMsg.appendChild(oDoc.createTextNode(sMsg));
-
- jpf.xmldb.appendChild(oUser.xml, oMsg);
- jpf.xmldb.applyChanges('synchronize', oUser.xml);
-
- // only send events to messages from contacts, not the acount itself
- return !(oUser.node == this.username && oUser.domain == this.domain);
- };
-
- /**
- * Transform a JID object into a Stringified represention of XML.
- *
- * @param {Object} oUser
- * @type {String}
- */
- this.userToXml = function(oUser) {
- var aOut = ['<user '];
-
- userProps.forEach(function(item) {
- aOut.push(item, '="', oUser[item], '" ');
- });
-
- return aOut.join('') + '/>';
- };
-
- /**
- * API; return the last JID that has been appended to the Roster
- *
- * @type {Object}
- */
- this.getLastUser = function() {
- return aUsers[aUsers.length - 1];
- };
-
- /**
- * API; return the last JID that is available for messaging through XMPP.
- *
- * @type {Object}
- */
- this.getLastAvailableUser = function() {
- for (var i = aUsers.length - 1; i >= 0; i--) {
- if (aUsers[i].status !== jpf.xmpp.TYPE_UNAVAILABLE)
- return aUsers[i];
- }
-
- return null;
- };
-
- this.getAllUsers = function() {
- return aUsers;
- };
-};
-
-// Collection of shorthands for all namespaces known and used by this class
-jpf.xmpp.NS = {
- sasl : 'urn:ietf:params:xml:ns:xmpp-sasl',
- httpbind: 'http://jabber.org/protocol/httpbind',
- bosh : 'urn:xmpp:xbosh',
- jabber : 'jabber:client',
- bind : 'urn:ietf:params:xml:ns:xmpp-bind',
- session : 'urn:ietf:params:xml:ns:xmpp-session',
- roster : 'jabber:iq:roster',
- stream : 'http://etherx.jabber.org/streams'
-};
-
-jpf.xmpp.CONN_POLL = 0x0001;
-jpf.xmpp.CONN_BOSH = 0x0002;
-
-jpf.xmpp.ERROR_AUTH = 0x0004;
-jpf.xmpp.ERROR_CONN = 0x0008;
-
-jpf.xmpp.TYPE_AVAILABLE = ""; //no need to send available
-jpf.xmpp.TYPE_UNAVAILABLE = "unavailable";
-
-jpf.xmpp.STATUS_SHOW = "show";
-jpf.xmpp.STATUS_AWAY = "away";
-jpf.xmpp.STATUS_XA = "xa";
-jpf.xmpp.STATUS_DND = "dnd";
-
-jpf.xmpp.MSG_CHAT = "chat";
-jpf.xmpp.MSG_GROUPCHAT = "groupchat";
-jpf.xmpp.MSG_ERROR = "error";
-jpf.xmpp.MSG_HEADLINE = "headline";
-jpf.xmpp.MSG_NORMAL = "normal";
-
-
-/**
- * Instruction handler for XMPP protocols. It supports the following directives:
- * - xmpp:name.login(username, password)
- * - xmpp:name.logout()
- * - xmpp:name.notify(message, to_address, thread, type)
- *
- * @param {XMLDoc} xmlContext
- * @param {Object} options Valid options are
- * instrType {String}
- * data {String}
- * multicall {Boolean}
- * userdata {mixed}
- * arg {Array}
- * isGetRequest {Boolean}
- * @param {Function} callback
- * @type {void}
- */
-jpf.datainstr.xmpp = function(xmlContext, options, callback){
- var parsed = options.parsed || this.parseInstructionPart(
- options.instrData.join(":"), xmlContext, options.args, options);
-
- if (options.preparse) {
- options.parsed = parsed;
- options.preparse = -1;
- return;
- }
-
- var oXmpp, name = parsed.name.split(".");
- if (name.length == 1) {
- var modules = jpf.teleport.modules;
- for (var i = 0; i < modules.length; i++) {
- if (modules[i].obj.tagName == "xmpp") {
- oXmpp = modules[i].obj;
- break;
- }
- }
- }
- else {
- oXmpp = self[name[0]];
- }
-
- if (!oXmpp) {
- throw new Error(jpf.formatErrorString(0, null, "Saving/Loading data",
- name.length
- ? "Could not find XMPP object by name '" + name[0] + "' in \
- data instruction '" + options.instruction + "'"
- : "Could not find any XMPP object to execute data \
- instruction with"));
- }
-
- var args = parsed.arguments;
- switch(name.shift()){
- case "login":
- oXmpp.connect(args[0], args[1], callback);
- break;
- case "logout":
- //@todo
- break;
- case "notify":
- oXmpp.sendMessage(args[1], args[0], args[2], args[3], callback);
- break;
- default:
- throw new Error(jpf.formatErrorString(0, null, "Saving/Loading data",
- "Invalid XMPP data instruction '" + options.instruction + "'"));
- break;
- }
-};
-
-
- - -/*FILEHEAD(/var/lib/jpf/src/elements/teleport/webdav.js)SIZE(-1077090856)TIME(1238933681)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -/** - * Element implementing WebDAV remote filesystem protocol. - * Depends on implementation of WebDAV server. - * - * @define webdav - * @addnode teleport - * - * @event error Fires when a communication error has occured while making a request for this element. - * cancellable: Prevents the error from being thrown. - * bubbles: - * object: - * {Error} error the error object that is thrown when the event callback doesn't return false. - * {Number} state the state of the call - * Possible values: - * jpf.SUCCESS the request was successfull - * jpf.TIMEOUT the request has timed out. - * jpf.ERROR an error has occurred while making the request. - * jpf.OFFLINE the request was made while the application was offline. - * {mixed} userdata data that the caller wanted to be available in the callback of the http request. - * {XMLHttpRequest} http the object that executed the actual http request. - * {String} url the url that was requested. - * {Http} tpModule the teleport module that is making the request. - * {Number} id the id of the request. - * {String} message the error message. - * - * @author Mike de Boer - * @version %I%, %G% - * @since 1.0 - * @constructor - * - * @inherits jpf.BaseComm - * @inherits jpf.http - * @namespace jpf - */ - -jpf.webdav = function(){ - this.server = null; - this.timeout = 10000; - this.useHTTP = true; - this.method = "GET"; - - this.TelePortModule = true; - - this.model = null; - this.useModel = false; - - var oLocks = {}, - iLockId = 0, - aLockedStack = [], - oServerVars = {}, - aFsCache = [], - _self = this; - - // Collection of shorthands for all namespaces known and used by this class - this.NS = { - D : "DAV:", - ns0 : "DAV:", - lp1 : "DAV:", - lp2 : "http://apache.org/dav/props/" - }; - - if (!this.uniqueId) { - jpf.makeClass(this); - - this.inherit(jpf.BaseComm, jpf.http); - } - - /** - * Simple helper function to store session variables in the private space. - * - * @param {String} name - * @param {mixed} value - * @type {mixed} - * @private - */ - function register(name, value) { - oServerVars[name] = value; - - return value; - } - - /** - * Simple helper function to complete remove variables that have been - * stored in the private space by register() - * - * @param {String} name - * @type {void} - * @private - */ - function unregister() { - for (var i = 0; i < arguments.length; i++) { - if (typeof oServerVars[arguments[i]] != "undefined") { - oServerVars[arguments[i]] = null; - delete oServerVars[arguments[i]]; - } - } - } - - /** - * Simple helper function that retrieves a variable, stored in the private - * space. - * - * @param {String} name - * @type {mixed} - * @private - */ - function getVar(name) { - return oServerVars[name] || ""; - } - - this.doRequest = function(fCallback, sPath, sBody, oHeaders, bUseXml, fCallback2) { - if (!getVar("authenticated")) { - return onAuth({ - method : this.doRequest, - context: this, - args : arguments - }); - } - - if (bUseXml) { - if (!oHeaders) - oHeaders = {}; - oHeaders["Content-type"] = "text/xml; charset=utf-8"; - } - return this.get(this.server + sPath || "", - function(data, state, extra) { - if (state != jpf.SUCCESS) { - var oError; - - oError = WebDAVError("Url: " + extra.url + "\nInfo: " + extra.message); - - if (extra.tpModule.retryTimeout(extra, state, _self, oError) === true) - return true; - - throw oError; - } - - var iStatus = parseInt(extra.http.status); - if (iStatus == 401) //authentication requested - return; // 401's are handled by the browser already, so no need for additional processing... - - var sResponse = (extra.http.responseText || ""); - if (sResponse.replace(/^[\s\n\r]+|[\s\n\r]+$/g, "") != "" - && sResponse.indexOf('<?xml version=') == 0) { - try { - data = (extra.http.responseXML && extra.http.responseXML.documentElement) - ? jpf.xmlParseError(extra.http.responseXML) - : jpf.getXmlDom(extra.http.responseText); - - if (!jpf.supportNamespaces) - data.setProperty("SelectionLanguage", "XPath"); - - extra.data = data.documentElement; - } - catch(e) { - throw WebDAVError("Received invalid XML\n\n" + e.message); - } - } - - if (typeof fCallback == "function") - fCallback.call(_self, data, state, extra, fCallback2); - }, { - nocache : false, - useXML : false,//true, - ignoreOffline : true, - data : sBody || "", - headers : oHeaders, - username : getVar("auth-username") || null, - password : getVar("auth-password") || null - }); - }; - - /** - * Something went wrong during the authentication process; this function - * provides a central mechanism for dealing with this situation - * - * @param {String} msg - * @type {Boolean} - * @exception {Error} A general Error object - * @private - */ - function notAuth(msg) { - unregister('auth-password'); - - var extra = { - username : getVar('auth-username'), - server : _self.server, - message : msg || "Access denied. Please check you username or password." - } - - var cb = getVar('auth-callback'); - if (cb) { - cb(null, jpf.ERROR, extra); - unregister('auth-callback'); - } - - jpf.console.error(extra.message + ' (username: ' + extra.username - + ', server: ' + extra.server + ')', 'webdav'); - - return _self.dispatchEvent("authfailure", extra); - } - - /** - * Our connection to the server has dropped, or the WebDAV server can not be - * reached at the moment. We will cancel the authentication process and - * dispatch a 'connectionerror' event - * - * @param {String} msg - * @type {Boolean} - * @private - */ - function connError(msg) { - unregister('auth-password'); - - var extra = { - username : getVar('auth-username'), - server : _self.server, - message : msg || "Could not connect to server, please contact your System Administrator." - } - - var cb = getVar('auth-callback'); - if (cb) { - cb(null, jpf.ERROR, extra); - unregister('auth-callback'); - } - - jpf.console.error(extra.message + ' (username: ' + extra.username - + ', server: ' + extra.server + ')', 'webdav'); - - return _self.dispatchEvent("connectionerror", extra); - } - - function WebDAVError(sMsg) { - return new Error(jpf.formatErrorString(0, _self, - "WebDAV Communication error", sMsg)); - } - - function onAuth(callback) { - var oDoc, authRequired = false; - if (jpf.isIE) { - try { - oDoc = new ActiveXObject("Msxml2.DOMDocument"); - } - catch(e) {} - } - else if (document.implementation && document.implementation.createDocument) { - try { - oDoc = document.implementation.createDocument("", "", null); - } - catch (e) {} - } - - try { - if (jpf.isIE) { // only support IE for now, other browsers cannot detect 401's silently yet... - oDoc.async = false; - oDoc.load(_self.server + _self.rootPath); - } - } - catch (e) { - authRequired = true; - } - - if (authRequired) - jpf.auth.authRequired(callback); - else { - register("authenticated", true); - if (callback && callback.method) - callback.method.apply(callback.context, callback.args); - } - } - - this.authenticate = function(username, password, callback) { - register("auth-username", username); - register("auth-password", password); - register("auth-callback", callback); - - this.doRequest(function(data, state, extra) { - if (extra.http.status == 401) - return jpf.auth.authRequired(); - register("authenticated", true); - var cb = getVar("auth-callback"); - if (cb) { - cb(null, state, extra); - unregister('auth-callback'); - } - }, this.rootPath, null, {}, false, null); - }; - - this.reset = function() { - unregister("authenticated"); - unregister("auth-username"); - unregister("auth-password"); - unregister("auth-callback"); - }; - - //------------ Filesystem operations ----------------// - - this.read = function(sPath, callback) { - this.method = "GET"; - this.doRequest(function(data, state, extra) { - var iStatus = parseInt(extra.http.status); - if (iStatus == 403) { //Forbidden - var oError = WebDAVError("Unable to read file. Server says: " - + jpf.webdav.STATUS_CODES["403"]); - if (this.dispatchEvent("error", { - error : oError, - bubbles : true - }) === false) - throw oError; - } - else { - callback - ? callback.call(_self, data, state, extra) - : this.dispatchEvent('onfilecontents', {data: data}); - } - }, sPath); - }; - - this.readDir = function(sPath, callback) { - if (sPath.charAt(sPath.length - 1) != "/") - sPath += "/"; - return this.getProperties(sPath, 1, callback); - }; - - this.mkdir = function(sPath, callback) { - var oLock = this.lock(sPath); - if (!oLock.token) - return updateLockedStack(oLock, "mkdir", arguments); - - this.method = "MKCOL"; - this.doRequest(function(data, state, extra) { - var iStatus = parseInt(extra.http.status); - if (iStatus == 201) { //Created - // TODO: refresh parent node... - } - else if (iStatus == 403 || iStatus == 405 || iStatus == 409 - || iStatus == 415 || iStatus == 507) { - var oError = WebDAVError("Unable to create directory '" + sPath - + "'. Server says: " - + jpf.webdav.STATUS_CODES[String(iStatus)]); - if (this.dispatchEvent("error", { - error : oError, - bubbles : true - }) === false) - throw oError; - } - _self.unlock(oLock); - }, sPath, null, oLock.token - ? { "If": "<" + oLock.token + ">" } - : null, true, callback); - }; - - this.list = function(sPath) { - return this.getProperties(sPath, 0); - }; - - this.write = function(sPath, sContent, sLock, callback) { - var oLock = this.lock(sPath); - if (!oLock.token) - return updateLockedStack(oLock, "write", arguments); - - this.method = "PUT"; - this.doRequest(function(data, state, extra) { - var iStatus = parseInt(extra.http.status); - if (iStatus == 409 || iStatus == 405) { //Conflict || Not Allowed - var oError = WebDAVError("Unable to write to file. Server says: " - + jpf.webdav.STATUS_CODES[String(iStatus)]); - if (this.dispatchEvent("error", { - error : oError, - bubbles : true - }) === false) - throw oError; - callback.call(_self, data, jpf.ERROR, extra); - } - else { - _self.getProperties(sPath, 0, callback); - } - }, sPath, sContent, sLock - ? {"If": "<" + sLock + ">"} - : null); - }; - - this.copy = function(sFrom, sTo, bOverwrite, callback) { - if (!sTo || sFrom == sTo) return; - - var oLock = this.lock(sFrom); - if (!oLock.token) - return updateLockedStack(oLock, "copy", arguments); - - this.method = "COPY"; - var oHeaders = { - "Destination": this.server + sTo - }; - if (typeof bOverwrite == "undefined") - bOverwrite = true; - if (!bOverwrite) - oHeaders["Overwrite"] = "F"; - if (oLock.token) - oHeaders["If"] = "<" + oLock.token + ">"; - this.doRequest(function(data, state, extra) { - unregisterLock(sFrom); - var iStatus = parseInt(extra.http.status); - if (iStatus == 403 || iStatus == 409 || iStatus == 412 - || iStatus == 423 || iStatus == 424 || iStatus == 502 - || iStatus == 507) { - var oError = WebDAVError("Unable to copy file '" + sFrom - + "' to '" + sTo + "'. Server says: " - + jpf.webdav.STATUS_CODES[String(iStatus)]); - if (this.dispatchEvent("error", { - error : oError, - bubbles : true - }) === false) - throw oError; - } - else { - // nodes needs to be added to the cache, callback passed through - // to notify listener(s) - _self.getProperties(sTo, 0, callback); - } - }, sFrom, null, oHeaders); - }; - - this.move = function(sFrom, sTo, bOverwrite, callback) { - if (!sTo || sFrom == sTo) return; - - var oLock = this.lock(sFrom); - if (!oLock.token) - return updateLockedStack(oLock, "move", arguments); - - this.method = "MOVE"; - var oHeaders = { - "Destination": this.server + sTo - }; - if (typeof bOverwrite == "undefined") - bOverwrite = true; - if (!bOverwrite) - oHeaders["Overwrite"] = "F"; - if (oLock.token) - oHeaders["If"] = "<" + oLock.token + ">"; - this.doRequest(function(data, state, extra) { - unregisterLock(sFrom); - var iStatus = parseInt(extra.http.status); - if (iStatus == 403 || iStatus == 409 || iStatus == 412 - || iStatus == 423 || iStatus == 424 || iStatus == 502) { - var oError = WebDAVError("Unable to move file '" + sFrom - + "' to '" + sTo + "'. Server says: " - + jpf.webdav.STATUS_CODES[String(iStatus)]); - if (this.dispatchEvent("error", { - error : oError, - bubbles : true - }) === false) - throw oError; - } - else { //success!! - getItemByPath(sFrom).path = sTo; - } - callback.call(_self, data, state, extra); - }, sFrom, null, oHeaders); - }; - - this.remove = function(sPath, callback) { - var oLock = this.lock(sPath); - if (!oLock.token) - return updateLockedStack(oLock, "remove", arguments); - - this.method = "DELETE"; - this.doRequest(function(data, state, extra) { - unregisterLock(sPath); - var iStatus = parseInt(extra.http.status); - if (iStatus == 423 || iStatus == 424) { //Failed dependency (collections only) - var oError = WebDAVError("Unable to remove file '" + sPath - + "'. Server says: " - + jpf.webdav.STATUS_CODES[String(iStatus)]); - if (this.dispatchEvent("error", { - error : oError, - bubbles : true - }) === false) - throw oError; - } - callback.call(_self, data, state, extra); - }, sPath, null, oLock.token - ? { "If": "<" + oLock.token + ">" } - : null); - }; - - /** - * - * @param {String} sPath - * @param {String} sOwner URL of the owning party (e.g. 'javeline.com') - * @param {Number} iDepth Depth of lock recursion down the tree, should be '1' or 'Infinity' - * @param {String} sType Type of the lock, default is 'write' (no other possibility) - * @param {Number} iTimeout - * @param {String} sLock Previous lock token - * @type {void} - */ - this.lock = function(sPath, iDepth, iTimeout, sLock, callback) { - // first, check for existing lock - var oLock = getLock(sPath); - if (oLock && oLock.token) { - // renew the lock (if needed - check timeout)... - return oLock; - } - - this.method = "LOCK" - - iTimeout = iTimeout ? "Infinite, Second-4100000000" : "Second-" + iTimeout; - var oHeaders = { - "Timeout": iTimeout - }; - if (iDepth) - oHeaders["Depth"] = iDepth || "Infinity"; - if (sLock) - oHeaders["If"] = "<" + sLock + ">"; - var xml = '<?xml version="1.0" encoding="utf-8"?>\ - <D:lockinfo xmlns:D="' + this.NS.D + '">\ - <D:lockscope><D:exclusive /></D:lockscope>\ - <D:locktype><D:write /></D:locktype>\ - <D:owner><D:href>' - + document.location.toString().escapeHTML() + - '</D:href></D:owner>\ - </D:lockinfo>'; - this.doRequest(registerLock, sPath, xml, oHeaders, true, callback); - return newLock(sPath); - }; - - this.unlock = function(oLock, callback) { - if (typeof oLock == "string") - oLock = getLock(oLock); - if (!oLock || !oLock.token) return; - - this.method = "UNLOCK"; - this.doRequest(function(data, state, extra) { - unregisterLock(extra.url.replace(_self.server, '')); - }, oLock.path, null, { - "Lock-Token": "<" + oLock.token + ">" - }, true, callback); - }; - - function newLock(sPath) { - return oLocks[sPath] = { - path : sPath, - id : iLockId++, - token: null - }; - } - - function registerLock(data, state, extra) { - var iStatus = parseInt(extra.http.status), - sPath = extra.url.replace(this.server, ''), - oLock = getLock(sPath) || newLock(sPath); - if (iStatus == 409 || iStatus == 423 || iStatus == 412) { - // lock failed, so unregister it immediately - unregisterLock(extra.url.replace(_self.server, '')); - var oError = WebDAVError("Unable to apply lock to '" + sPath - + "'. Server says: " - + jpf.webdav.STATUS_CODES[String(iStatus)]); - if (this.dispatchEvent("error", { - error : oError, - bubbles : true - }) === false) - throw oError; - } - - var oOwner = $xmlns(data, "owner", _self.NS.ns0)[0]; - var oToken = $xmlns(data, "locktoken", _self.NS.D)[0]; - oLock.path = sPath; - oLock.type = "write"; - oLock.scope = $xmlns(data, "exclusive", _self.NS.D).length ? "exclusive" : "shared"; - oLock.depth = $xmlns(data, "depth", _self.NS.D)[0].firstChild.nodeValue; - oLock.owner = $xmlns(oOwner, "href", _self.NS.ns0)[0].firstChild.nodeValue; - oLock.timeout = $xmlns(data, "timeout", _self.NS.D)[0].firstChild.nodeValue; - oLock.token = $xmlns(oToken, "href", _self.NS.D)[0].firstChild.nodeValue.split(":")[1]; - - purgeLockedStack(oLock); - } - - function unregisterLock(sPath) { - var oLock = getLock(sPath); - if (!oLock) return; - purgeLockedStack(oLock, true); - oLocks[sPath] = oLock = null; - delete oLocks[sPath]; - } - - function getLock(sPath) { - return oLocks[sPath] || null; - } - - function updateLockedStack(oLock, sFunc, aArgs) { - return aLockedStack.push({ - lockId: oLock.id, - func : sFunc, - args : aArgs - }); - } - - function purgeLockedStack(oLock, bFailed) { - for (var i = aLockedStack.length - 1; i >= 0; i--) { - if (aLockedStack[i].lockId != oLock.id) continue; - if (!bFailed) - _self[aLockedStack[i].func].apply(_self, aLockedStack[i].args); - aLockedStack.remove(i); - } - } - - this.getProperties = function(sPath, iDepth, callback, oHeaders) { - // Note: caching is being done by an external model - this.method = "PROPFIND"; - // XXX maybe we want to change this to allow getting selected props - var xml = '<?xml version="1.0" encoding="utf-8" ?>\ - <D:propfind xmlns:D="' + this.NS.D + '">\ - <D:allprop />\ - </D:propfind>'; - oHeaders = oHeaders || {}; - oHeaders["Depth"] = typeof iDepth != "undefined" ? iDepth : 1 - this.doRequest(parsePropertyPackets, sPath, xml, oHeaders, true, callback); - }; - - this.setProperties = function(sPath, oPropsSet, oPropsDel, sLock) { - this.method = "PROPPATCH"; - - this.doRequest(function(data, state, extra) { - jpf.console.dir(data); - }, sPath, buildPropertiesBlock(oPropsSet, oPropsDel), - sLock ? {"If": "<" + sLock + ">"} : null, true); - }; - - /** - * create the XML for a PROPPATCH request. - * - * @param {Object} oPropsSet A mapping from namespace to a mapping of key/value pairs (where value is an *entitized* XML string) - * @param {Object} oPropsDel A mapping from namespace to a list of names - * @type {String} - * @private - */ - function buildPropertiesBlock(oPropsSet, oPropsDel) { - var aOut = ['<?xml version="1.0" encoding="utf-8" ?>', - '<D:propertyupdate xmlns:D="', _self.NS.D, '">']; - - var bHasProps = false, ns, i, j; - for (ns in oPropsSet) { - bHasProps = true; - break; - } - if (bHasProps) { - aOut.push('<D:set>\n'); - for (ns in oPropsSet) { - for (i in oPropsSet[ns]) - aOut.push('<D:prop>', oPropsSet[ns][i], '</D:prop>') - } - aOut.push('</D:set>'); - } - bHasProps = false; - for (ns in oPropsDel) { - bHasProps = true; - break; - } - if (bHasProps) { - aOut.push('<D:remove><D:prop>'); - for (ns in oPropsDel) { - for (i = 0, j = oPropsDel[ns].length; i < j; i++) - aOut.push('<', oPropsDel[ns][i], ' xmlns="', ns, '"/>') - } - aOut.push('</D:prop></D:remove>'); - } - - aOut.push('</D:propertyupdate>'); - return aOut.join(''); - } - - function parsePropertyPackets(oXml, state, extra, callback) { - if (parseInt(extra.http.status) == 403) { - // TODO: dispatch onerror event - return; - } - - var aResp = $xmlns(oXml, 'response', _self.NS.D), - aOut = []; - if (aResp.length) //we got a valid result set, so assume that any possible AUTH has succeeded - register("authenticated", true); - for (var i = aResp.length > 1 ? 1 : 0, j = aResp.length; i < j; i++) - aOut.push(parseItem(aResp[i])); - if (callback) - callback.call(_self, "<files>" + aOut.join('') + "</files>", state, extra); - } - - function parseItem(oNode) { - var sPath = $xmlns(oNode, "href", _self.NS.D)[0].firstChild.nodeValue.replace(/[\\\/]+$/, ''); - - var iId, oItem = getItemByPath(sPath); - if (oItem && typeof oItem.id == "number") - iId = oItem.id; - else - iId = aFsCache.length; - - var sType = $xmlns(oNode, "collection", _self.NS.D).length > 0 ? "folder" : "file"; - var aCType = $xmlns(oNode, "getcontenttype", _self.NS.D); - var aExec = $xmlns(oNode, "executable", _self.NS.lp2); - oItem = aFsCache[iId] = { - id : iId, - path : sPath, - type : sType, - size : parseInt(sType == "file" - ? $xmlns(oNode, "getcontentlength", _self.NS.lp1)[0].firstChild.nodeValue - : 0), - name : decodeURIComponent(sPath.split("/").pop()), - contentType : (sType == "file" && aCType.length - ? aCType[0].firstChild.nodeValue - : ""), - creationDate: $xmlns(oNode, "creationdate", _self.NS.lp1)[0].firstChild.nodeValue, - lastModified: $xmlns(oNode, "getlastmodified", _self.NS.lp1)[0].firstChild.nodeValue, - etag : $xmlns(oNode, "getetag", _self.NS.lp1)[0].firstChild.nodeValue, - lockable : ($xmlns(oNode, "locktype", _self.NS.D).length > 0), - executable : (aExec.length > 0 && aExec[0].firstChild.nodeValue == "T") - }; - - return oItem.xml = "<" + sType + " \ - id='" + iId + "' \ - type='" + sType + "' \ - size='" + oItem.size + "' \ - name='" + oItem.name + "' \ - contenttype='" + oItem.contentType + "' \ - creationdate='" + oItem.creationDate + "' \ - lockable='" + oItem.lockable.toString() + "' \ - executable='" + oItem.executable.toString() + - "'/>"; - } - - function getItemByPath(sPath) { - for (var i = 0, j = aFsCache.length; i < j; i++) { - if (aFsCache[i].path == sPath) - return aFsCache[i]; - } - return null; - } - - this.getItemById = function(iId) { - if (typeof iId == "string") - iId = parseInt(iId); - return aFsCache[iId] || null; - }; - - this.$xmlUpdate = function(action, xmlNode, listenNode, UndoObj) { - if (!this.useModel) return; - jpf.console.log('$xmlUpdate called: ', action); - jpf.console.dir(xmlNode); - jpf.console.dir(listenNode); - jpf.console.dir(UndoObj); - }; - - /** - * This is the connector function between the JML representation of this - * Teleport module. If specified, it will also setup the Remote SmartBinding - * feature. - * - * Sample JML: - * <j:teleport> - * <j:webdav id="myWebDAV" url="http://http://test.webdav.org" model="myFilesystem" model-contents="all" /> - * </j:teleport> - * - * @param {XMLDom} x An XML document element that contains WebDAV metadata - * @type {void} - * @exception {Error} A general Error object - */ - this.load = function(x){ - this.server = x.getAttribute('url'); - var i, url = new jpf.url(this.server); - - // do some extra startup/ syntax error checking - if (!url.host || !url.protocol) - throw new Error(jpf.formatErrorString(0, this, - "WebDAV initialization error", - "Invalid WebDAV server url provided.")); - - this.domain = url.host; - this.rootPath = url.path; - this.server = this.server.replace(new RegExp(this.rootPath + "$"), ""); - this.tagName = "webdav"; - - this.timeout = parseInt(x.getAttribute("timeout")) || this.timeout; - this.resource = x.getAttribute('resource') || jpf.appsettings.name; - - var sModel = x.getAttribute('model') || null; - if (sModel) - this.model = self[sModel] || null; - this.useModel = this.model ? true : false; - if (this.useModel) - jpf.xmldb.addNodeListener(this.model, this); - - //TODO: implement model updating mechanism (model="mdlFoo") - // with corresponding 'this.$xmlUpdate' handler function for model updates - - // parse any custom events formatted like 'onfoo="doBar();"' - var attr = x.attributes; - for (i = 0; i < attr.length; i++) { - if (attr[i].nodeName.indexOf("on") == 0) - this.addEventListener(attr[i].nodeName, - new Function(attr[i].nodeValue)); - } - }; -}; - -jpf.webdav.STATUS_CODES = { - '100': 'Continue', - '101': 'Switching Protocols', - '102': 'Processing', - '200': 'OK', - '201': 'Created', - '202': 'Accepted', - '203': 'None-Authoritive Information', - '204': 'No Content', - '1223': 'No Content', - '205': 'Reset Content', - '206': 'Partial Content', - '207': 'Multi-Status', - '300': 'Multiple Choices', - '301': 'Moved Permanently', - '302': 'Found', - '303': 'See Other', - '304': 'Not Modified', - '305': 'Use Proxy', - '307': 'Redirect', - '400': 'Bad Request', - '401': 'Unauthorized', - '402': 'Payment Required', - '403': 'Forbidden', - '404': 'Not Found', - '405': 'Method Not Allowed', - '406': 'Not Acceptable', - '407': 'Proxy Authentication Required', - '408': 'Request Time-out', - '409': 'Conflict', - '410': 'Gone', - '411': 'Length Required', - '412': 'Precondition Failed', - '413': 'Request Entity Too Large', - '414': 'Request-URI Too Large', - '415': 'Unsupported Media Type', - '416': 'Requested range not satisfiable', - '417': 'Expectation Failed', - '422': 'Unprocessable Entity', - '423': 'Locked', - '424': 'Failed Dependency', - '500': 'Internal Server Error', - '501': 'Not Implemented', - '502': 'Bad Gateway', - '503': 'Service Unavailable', - '504': 'Gateway Time-out', - '505': 'HTTP Version not supported', - '507': 'Insufficient Storage'//, -// 12002 ERROR_INTERNET_TIMEOUT -// 12007 ERROR_INTERNET_NAME_NOT_RESOLVED -// 12029 ERROR_INTERNET_CANNOT_CONNECT -// 12030 ERROR_INTERNET_CONNECTION_ABORTED -// 12031 ERROR_INTERNET_CONNECTION_RESET -// 12152 ERROR_HTTP_INVALID_SERVER_RESPONSE -}; - - -/** - * Instruction handler for XMPP protocols. It supports the following directives: - * - xmpp:name.login(username, password) - * - xmpp:name.logout() - * - xmpp:name.notify(message, to_address, thread, type) - * - * @param {XMLDoc} xmlContext - * @param {Object} options Valid options are - * instrType {String} - * data {String} - * multicall {Boolean} - * userdata {mixed} - * arg {Array} - * isGetRequest {Boolean} - * @param {Function} callback - * @type {void} - */ -jpf.datainstr.webdav = function(xmlContext, options, callback){ - var parsed = options.parsed || this.parseInstructionPart( - options.instrData.join(":"), xmlContext, options.args, options); - - if (options.preparse) { - options.parsed = parsed; - options.preparse = -1; - return; - } - - var oWebDAV, name = parsed.name.split("."); - if (name.length == 1) { - var modules = jpf.teleport.modules; - for (var i = 0; i < modules.length; i++) { - if (modules[i].obj.tagName == "webdav") { - oWebDAV = modules[i].obj; - break; - } - } - } - else { - oWebDAV = self[name[0]]; - } - - if (!oWebDAV) { - throw new Error(jpf.formatErrorString(0, null, "Saving/Loading data", - name.length - ? "Could not find WebDAV object by name '" + name[0] + "' in \ - data instruction '" + options.instruction + "'" - : "Could not find any WebDAV object to execute data \ - instruction with")); - } - - var args = parsed.arguments; - var oItem = oWebDAV.getItemById(args[0]); - // RULE for case aliases: first, topmost match is the preferred term for any - // action and should be used in demos/ examples in - // favor of other aliases. - switch (name.shift()) { - case "login": - case "authenticate": - oWebDAV.authenticate(args[0], args[1], callback); - break; - case "logout": - oWebDAV.reset(); - break; - case "read": - oWebDAV.read(oItem.path, callback); - break; - case "create": - window.console.log('creating file: ', oItem.path + '/' + args[1], args[2]); - oWebDAV.write(oItem.path + "/" + args[1], args[2], null, callback); - break; - case "write": - case "store": - case "save": - oWebDAV.write(oItem.path, args[1], null, callback); - break; - case "copy": - case "cp": - var oItem2 = oWebDAV.getItemById(args[1]); - oWebDAV.copy(oItem.path, oItem2.path, args[2], callback); - break; - case "rename": - oItem = oWebDAV.getItemById(args[1]); - if (!oItem) break; - - var sBasepath = oItem.path.replace(oItem.name, ''); - jpf.console.log('renaming: ', oItem.path, sBasepath + args[0]); - //TODO: implement 'Overwrite' setting... - oWebDAV.move(oItem.path, sBasepath + args[0], false, callback); - break; - case "move": - case "mv": - //TODO: implement 'Overwrite' setting... - oWebDAV.move(oItem.path, oWebDAV.getItemById(args[1]).path + "/" - + oItem.name, false, callback); - break; - case "remove": - case "rmdir": - case "rm": - oWebDAV.remove(oItem.path, callback); - break; - case "scandir": - case "readdir": - oWebDAV.readDir(oItem.path, callback); - break; - case "getroot": - oWebDAV.getProperties(oWebDAV.rootPath, 0, callback); - break; - case "mkdir": - break; - case "lock": - oWebDAV.lock(oItem.path, null, null, null, callback); - break; - case "unlock": - oWebDAV.unlock(oItem.path, callback); - break; - default: - throw new Error(jpf.formatErrorString(0, null, "Saving/Loading data", - "Invalid WebDAV data instruction '" + options.instruction + "'")); - break; - } -}; - - - - -/*FILEHEAD(/var/lib/jpf/src/elements/teleport/http.js)SIZE(-1077090856)TIME(1238944817)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * Object allowing for easy http communication from within the browser. This
- * object does what is commonly known as Ajax. It Asynchronously communicates
- * using Javascript And in most cases it sends or receives Xml.
- * Example:
- * Retrieving content over http synchronously:
- * <code>
- * var http = new jpf.http();
- * var data = http.get("http://www.example.com/mydata.jsp", null, {async: false});
- * alert(data);
- * </code>
- * Example:
- * Retrieving content over http asynchronously:
- * <code>
- * var http = new jpf.http();
- * http.get("http://www.example.com/mydata.jsp", function(data, state, extra){
- * if (state != jpf.SUCCESS)
- * return alert('an error has occurred');
- *
- * alert(data);
- * });
- * </code>
- * Example:
- * Async http request with retry.
- * <code>
- * var http = new jpf.http();
- * http.get("http://www.example.com/mydata.jsp", function(data, state, extra){
- * if (state != jpf.SUCCESS) {
- * var oError = new Error(jpf.formatErrorString(0, null,
- * "While loading data", "Could not load data" + extra.message);
- *
- * if (extra.tpModule.retryTimeout(extra, state, null, oError) === true)
- * return true;
- *
- * throw oError;
- * }
- *
- * alert(data);
- * });
- * </code>
- *
- * @event error Fires when a communication error occurs.
- * bubbles: yes
- * cancellable: Prevents a communication error to be thrown.
- * object:
- * {Error} error the error object that is thrown when the event callback doesn't return false.
- * {Number} state the state of the call
- * Possible values:
- * jpf.SUCCESS the request was successfull
- * jpf.TIMEOUT the request has timed out.
- * jpf.ERROR an error has occurred while making the request.
- * jpf.OFFLINE the request was made while the application was offline.
- * {mixed} userdata data that the caller wanted to be available in the callback of the http request.
- * {XMLHttpRequest} http the object that executed the actual http request.
- * {String} url the url that was requested.
- * {Http} tpModule the teleport module that is making the request.
- * {Number} id the id of the request.
- * {String} message the error message.
- *
- * @constructor
- * @define http
- * @addnode teleport
- *
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.4
- */
-jpf.http = function(){
- this.queue = [null];
- this.callbacks = {};
- this.cache = {};
-
- /**
- * {Numbers} Sets the timeout of http requests in milliseconds
- */
- this.timeout = 10000; //default 10 seconds
- if (!this.uniqueId)
- this.uniqueId = jpf.all.push(this) - 1;
-
- var _self = this;
-
- // Register Communication Module
- jpf.teleport.register(this);
-
- this.toString = this.toString || function(){
- return "[Javeline TelePort Component : (HTTP)]";
- }
-
- var namespace = jpf.appsettings.name + ".jpf.http";
-
- /**
- * Saves the jpf http cache to the available javeline storage engine.
- */
- this.saveCache = function(){
- if (!jpf.serialize)
- throw new Error(jpf.formatErrorMessage(1079, this,
- "HTTP save cache",
- "Could not find JSON library."));
-
- jpf.console.info("[HTTP] Loading HTTP Cache", "teleport");
-
- var strResult = jpf.serialize(comm.cache);
- jpf.storage.put("cache_" + _self.name, strResult,
- jpf.appsettings.name + ".jpf.http");
- };
-
- /**
- * Loads the jpf http cache from the available javeline storage engine.
- */
- this.loadCache = function(){
- var strResult = jpf.storage.get("cache_" + _self.name,
- jpf.appsettings.name + ".jpf.http");
-
- jpf.console.info("[HTTP] Loading HTTP Cache", "steleport");
-
- if (!strResult)
- return false;
-
- this.cache = jpf.unserialize(strResult);
-
- return true;
- };
-
- /**
- * Removes the stored http cache from the available javeline storage engine.
- */
- this.clearCache = function(){
- jpf.storage.remove("cache_" + _self.name,
- jpf.appsettings.name + ".jpf.http");
- };
-
- /**
- * Makes an http request that receives xml
- * For a description of the parameters see {@link teleport.http.method.get}
- * @param {String} url the url that is called
- * @param {Function} callback the handler of the request success, error or timed out state.
- * @param {Object} options the options for the http request
- */
- this.getXml = function(url, callback, options){
- if(!options) options = {};
- options.useXML = true;
- return this.get(url, callback, options);
- };
-
- /**
- * Makes an http request.
- * @param {String} url the url that is called
- * @param {Function} callback the handler of the request success, error or timed out state.
- * @param {Object} options the options for the http request
- * Properties:
- * {Boolean} async whether the request is sent asynchronously. Defaults to true.
- * {mixed} userdata passed to the callback function.
- * {String} method the request method (POST|GET|PUT|DELETE). Defaults to GET.
- * {Boolean} nocache whether browser caching is prevented.
- * {String} data the data sent in the body of the message.
- * {Boolean} useXML whether the result should be interpreted as xml.
- * {Boolean} autoroute whether the request can fallback to a server proxy.
- * {Boolean} caching whether the request should use internal caching.
- * {Boolean} ignoreOffline whether to ignore offline catching.
- */
- this.get = function(url, callback, options, id){
- if(!options)
- options = {};
-
- var bHasOffline = (typeof jpf.offline != "undefined");
- if (bHasOffline && !jpf.offline.onLine && options.notWhenOffline)
- return false;
-
- if (bHasOffline && !jpf.offline.onLine && !options.ignoreOffline) {
- if (jpf.offline.queue.enabled) {
- //Let's record all the necesary information for future use (during sync)
- var info = jpf.extend({
- url : url,
- callback : callback,
- retry : function(){
- _self.get(this.url, this.callback, this, id);
- },
- $object : [this.name, "jpf.oHttp", "new jpf.http()"],
- $retry : "this.object.get(this.url, this.callback, this)"
- }, options);
-
- jpf.offline.queue.add(info);
-
- return;
- }
-
- /*
- Apparently we're doing an HTTP call even though we're offline
- I'm allowing it, because the developer seems to know more
- about it than I right now
- */
-
- jpf.console.warn("Executing HTTP request even though application is offline");
- }
-
- var async = options.async
- || typeof options.async == "undefined" || jpf.isOpera;
-
- if (jpf.isSafari)
- url = jpf.html_entity_decode(url);
-
- var data = options.data || "";
-
- if (jpf.isNot(id)) {
- if (this.cache[url] && this.cache[url][data]) {
- var http = {
- responseText : this.cache[url][data],
- responseXML : {},
- status : 200,
- isCaching : true
- }
- }
- else
- var http = jpf.getHttpReq();
-
- id = this.queue.push({
- http : http,
- url : url,
- callback : callback,
- retries : 0,
- options : options
- }) - 1;
-
- if (http.isCaching) {
- if (async)
- return setTimeout("jpf.lookup(" + this.uniqueId
- + ").receive(" + id + ");", 50);
- else
- return this.receive(id);
- }
- }
- else {
- var http = this.queue[id].http;
-
- if (http.isCaching)
- http = jpf.getHttpReq();
- else
- http.abort();
- }
-
- if (async) {
- if (jpf.hasReadyStateBug) {
- this.queue[id].starttime = new Date().getTime();
- this.queue[id].timer = setInterval(function(){
- var diff = new Date().getTime() - _self.queue[id].starttime;
- if (diff > _self.timeout) {
- _self.$timeout(id);
- return
- };
-
- if (_self.queue[id].http.readyState == 4) {
- clearInterval(_self.queue[id].timer);
- _self.receive(id);
- }
- }, 20);
- }
- else
- {
- http.onreadystatechange = function(){
- if (!_self.queue[id] || http.readyState != 4)
- return;
-
- _self.receive(id);
- }
- }
- }
-
- var autoroute = this.autoroute && jpf.isOpera
- ? true //Bug in opera
- : (options.autoroute || this.shouldAutoroute);
- var httpUrl = autoroute ? this.routeServer : url;
-
- if (!options.hideLogMessage) {
- jpf.console.info("[HTTP] Making request[" + id + "] using "
- + (this.method || options.method || "GET") + " to " + url
- + (autoroute
- ? "<span style='color:green'>[via: " + httpUrl + "]</span>"
- : ""),
- "teleport",
- new String(data && data.xml ? data.xml : data));
- }
-
- var errorFound = false;
- try {
- if (options.nocache)
- httpUrl = jpf.getNoCacheUrl(httpUrl);
-
- if (jpf.appsettings.queryAppend) {
- httpUrl += (httpUrl.indexOf("?") == -1 ? "?" : "&")
- + jpf.appsettings.queryAppend;
- }
-
- http.open(this.method || options.method || "GET", httpUrl,
- async, options.username || null, options.password || null);
-
- //@todo OPERA ERROR's here... on retry [is this still applicable?]
- http.setRequestHeader("User-Agent", "Javeline TelePort 2.0"); //@deprecated
- http.setRequestHeader("X-Requested-With", "XMLHttpRequest");
- http.setRequestHeader("Content-type", this.contentType
- || (this.useXML || options.useXML ? "text/xml" : "text/plain"));
-
- if (autoroute) {
- http.setRequestHeader("X-Route-Request", url);
- http.setRequestHeader("X-Proxy-Request", url);
- http.setRequestHeader("X-Compress-Response", "gzip");
- }
- }
- catch (e) {
- errorFound = true;
- }
-
- if (errorFound) {
- var useOtherXH = false;
-
- if (self.XMLHttpRequestUnSafe) {
- try {
- http = new XMLHttpRequestUnSafe();
- http.onreadystatechange = function(){
- if (!_self.queue[id] || http.readyState != 4)
- return;
-
- _self.receive(id);
- }
- http.open(this.method || options.method || "GET", (options.nocache
- ? jpf.getNoCacheUrl(httpUrl)
- : httpUrl), async);
-
- this.queue[id].http = http;
- options.async = true; //force async
- useOtherXH = true;
- }
- catch (e) {}
- }
-
- // Retry request by routing it
- if (!useOtherXH && this.autoroute && !autoroute) {
- if (!jpf.isNot(id))
- clearInterval(this.queue[id].timer);
-
- this.shouldAutoroute = true;
-
- options.autoroute = true;
- return this.get(url, receive, options, id);
- }
-
- if (!useOtherXH) {
- //Routing didn't work either... Throwing error
- var noClear = callback ? callback(null, jpf.ERROR, {
- userdata: options.userdata,
- http : http,
- url : url,
- tpModule: this,
- id : id,
- message : "Permission denied accessing remote resource: " + url
- }) : false;
- if (!noClear)
- this.clearQueueItem(id);
-
- return;
- }
- }
-
- if (this.$HeaderHook)
- this.$HeaderHook(http);
-
- //Set request headers
- if (options.headers) {
- for (var name in options.headers)
- http.setRequestHeader(name, options.headers[name]);
- }
-
- function send(isLocal){
- var hasError;
-
- if (isLocal)
- http.send(data);
- else {
- try{
- http.send(data);
- }
- catch(e){
- hasError = true;
- }
- }
-
- if (hasError) {
- var msg = window.navigator.onLine
- ? "File or Resource not available " + url
- : "Browser is currently working offline";
-
- jpf.console.info(msg, "teleport");
-
- var state = window.navigator.onLine
- ? jpf.ERROR
- : jpf.TIMEOUT;
-
- // File not found
- var noClear = callback ? callback(null, state, {
- userdata : options.userdata,
- http : http,
- url : url,
- tpModule : this,
- id : id,
- message : msg
- }) : false;
- if(!noClear) this.clearQueueItem(id);
-
- return;
- }
- }
-
- if (!async) {
- send.call(this);
- return this.receive(id);
- }
- else {
- if (jpf.isIE && location.protocol == "file:"
- && url.indexOf("http://") == -1) {
- setTimeout(function(){
- send.call(_self, true);
- });
- }
- else
- send.call(_self);
-
- return id;
- }
- };
-
- /**
- * @private
- */
- this.receive = function(id){
- if (!this.queue[id])
- return false;
-
- var qItem = this.queue[id];
- var http = qItem.http;
- var callback = qItem.callback;
-
- clearInterval(qItem.timer);
-
- if (window.navigator.onLine === false && (location.protocol != "file:"
- || qItem.url.indexOf("http://") > -1))
- return false;
-
- // Test if HTTP object is ready
- try {
- if (http.status) {}
- }
- catch (e) {
- return setTimeout(function(){
- _self.receive(id)
- }, 10);
- }
-
- if (!qItem.options.hideLogMessage) {
- jpf.console.info("[HTTP] Receiving [" + id + "]"
- + (http.isCaching
- ? "[<span style='color:orange'>cached</span>]"
- : "")
- + " from " + qItem.url,
- "teleport",
- http.responseText);
- }
-
- //Gonna check for validity of the http response
- var errorMessage = [];
-
- var extra = {
- tpModule : this,
- http : http,
- url : qItem.url,
- callback : callback,
- id : id,
- retries : qItem.retries || 0,
- userdata : qItem.options.userdata
- }
-
- // Check HTTP Status
- if (http.status > 600)
- return this.$timeout(id); //The message didn't receive the server. We consider this a timeout (i.e. 12027)
-
- extra.data = http.responseText; //Can this error?
-
- if (http.status >= 400 && http.status < 600) {
- //@todo This should probably have an RPC specific handler
- if (http.status == 401) {
- var wasDelayed = qItem.isAuthDelayed;
- qItem.isAuthDelayed = true;
- if (jpf.auth.authRequired(extra, wasDelayed) === true)
- return;
- }
-
- errorMessage.push("HTTP error [" + id + "]:" + http.status + "\n" + http.responseText);
- }
-
- // Check for XML Errors
- if (qItem.options.useXML || this.useXML) {
- /* Note (Mike, Oct 14th 2008): for WebDAV, I had to copy the lines below,
- it required custom responseXML handling/
- parsing.
- If you alter this code, please correct
- webdav.js appropriately.
- */
- if ((http.responseText || "").replace(/^[\s\n\r]+|[\s\n\r]+$/g, "") == "")
- errorMessage.push("Received an empty XML document (0 bytes)");
- else {
- try {
- var xmlDoc = (http.responseXML && http.responseXML.documentElement)
- ? jpf.xmlParseError(http.responseXML)
- : jpf.getXmlDom(http.responseText);
-
- if (!jpf.supportNamespaces)
- xmlDoc.setProperty("SelectionLanguage", "XPath");
-
- extra.data = xmlDoc.documentElement;
- }
- catch(e){
- errorMessage.push("Received invalid XML\n\n" + e.message);
- }
- }
- }
-
- //Process errors if there are any
- if (errorMessage.length) {
- extra.message = errorMessage.join("\n");
-
- // Send callback error state
- if (!callback || !callback(null, jpf.ERROR, extra))
- this.clearQueueItem(id);
-
- return;
- }
-
- if (qItem.options.caching) {
- if (!this.cache[qItem.url])
- this.cache[qItem.url] = {};
-
- this.cache[qItem.url][qItem.options.data] = http.responseText;
- }
-
- //Http call was successfull Success
- if (!callback || !callback(extra.data, jpf.SUCCESS, extra))
- this.clearQueueItem(id);
-
- return extra.data;
- };
-
- this.$timeout = function(id){
- if (!this.queue[id])
- return false;
-
- var qItem = this.queue[id];
- var http = qItem.http;
-
- clearInterval(qItem.timer);
-
- // Test if HTTP object is ready
- try {
- if (http.status) {}
- }
- catch (e) {
- return setTimeout(function(){
- _self.$timeout(id)
- }, 10);
- }
-
- var callback = qItem.callback;
-
- http.abort();
-
- jpf.console.info("HTTP Timeout [" + id + "]", "teleport");
-
- var noClear = callback ? callback(null, jpf.TIMEOUT, {
- userdata: qItem.options.userdata,
- http : http,
- url : qItem.url,
- tpModule: this,
- id : id,
- message : "HTTP Call timed out",
- retries : qItem.retries || 0
- }) : false;
- if (!noClear)
- this.clearQueueItem(id);
- };
-
- /**
- * Checks if the request has times out. If so it's retried
- * three times before an exception is thrown. Request retrying is a very
- * good way to create robust Ajax applications. In many cases, even with
- * good connections requests time out.
- * @param {Object} extra the information object given as a third argument of the http request callback.
- * @param {Number} state the return code of the http request.
- * Possible values:
- * jpf.SUCCESS the request was successfull
- * jpf.TIMEOUT the request has timed out.
- * jpf.ERROR an error has occurred while making the request.
- * jpf.OFFLINE the request was made while the application was offline.
- * @param {JmlNode} jmlNode the element receiving the error event.
- * @param {Error} oError the error to be thrown when the request is not retried.
- * @param {Number} maxRetries the number of retries that are done before the request times out. Default is 3.
- */
- this.retryTimeout = function(extra, state, jmlNode, oError, maxRetries){
- if (state == jpf.TIMEOUT
- && extra.retries < (maxRetries || jpf.maxHttpRetries))
- return extra.tpModule.retry(extra.id);
-
- oError = oError || new Error(jpf.formatErrorString(0,
- this, "Communication " + (state == jpf.TIMEOUT
- ? "timeout"
- : "error"), "Url: " + extra.url + "\nInfo: " + extra.message));
-
- if ((jmlNode || jpf).dispatchEvent("error", jpf.extend({
- error : oError,
- state : state,
- bubbles : true
- }, extra)) === false)
- return true;
- };
-
- /**
- * Removes the item from the queue. This is usually done automatically.
- * However when the callback returns true the queue isn't cleared, for instance
- * when a request is retried. The id of the call
- * is found on the 'extra' object. The third argument of the callback.
- * Example:
- * <code>
- * http.clearQueueItem(extra.id);
- * </code>
- * @param {Number} id the id of the call that should be removed from the queue.
- */
- this.clearQueueItem = function(id){
- if (!this.queue[id])
- return false;
-
- clearInterval(this.queue[id].timer);
-
- jpf.teleport.releaseHTTP(this.queue[id].http);
-
- this.queue[id] = null;
- delete this.queue[id];
-
- return true;
- };
-
- /**
- * Retries a call based on it's id. The id of the call is found on the
- * 'extra' object. The third argument of the callback.
- * Example:
- * <code>
- * function callback(data, state, extra){
- * if (state == jpf.TIMEOUT && extra.retries < jpf.maxHttpRetries)
- * return extra.tpModule.retry(extra.id);
- *
- * //Do stuff here
- * }
- * </code>
- * @param {Number} id the id of the call that should be retried.
- */
- this.retry = function(id){
- if (!this.queue[id])
- return false;
-
- var qItem = this.queue[id];
-
- clearInterval(qItem.timer);
-
- jpf.console.info("[HTTP] Retrying request [" + id + "]", "teleport");
-
- qItem.retries++;
- this.get(qItem.url, qItem.callback, qItem.options, id);
-
- return true;
- };
-
- /**
- * see {@link teleport.http.method.clearqueueitem}
- */
- this.cancel = function(id){
- if (id === null)
- id = this.queue.length - 1;
-
- if (!this.queue[id])
- return false;
-
- //this.queue[id][0].abort();
- this.clearQueueItem(id);
- };
-
- if (!this.load) {
- /**
- * @private
- */
- this.load = function(x){
- var receive = x.getAttribute("receive");
-
- for (var i = 0; i < x.childNodes.length; i++) {
- if (x.childNodes[i].nodeType != 1)
- continue;
-
- var url = x.childNodes[i].getAttribute("url");
- var callback = self[x.childNodes[i].getAttribute("receive") || receive];
- var options = {
- useXML : x.childNodes[i].getAttribute("type") == "XML",
- async : !jpf.isFalse(x.childNodes[i].getAttribute("async"))
- }
-
- this[x.childNodes[i].getAttribute("name")] = function(data, userdata){
- options.userdata = userdata;
- options.data = data;
- return this.get(url, callback, options);
- }
- }
- };
-
- /**
- * @private
- */
- this.instantiate = function(x){
- var url = x.getAttribute("src");
- var options = {
- async : x.getAttribute("async") != "false",
- nocache : true
- }
-
- this.getURL = function(data, userdata){
- options.data = data;
- options.userdata = userdata;
- return this.get(url, this.callbacks.getURL, options);
- }
-
- var name = "http" + Math.round(Math.random() * 100000);
- jpf.setReference(name, this);
-
- return name + ".getURL()";
- };
-
- /**
- * @private
- */
- this.call = function(method, args){
- this[method].call(this, args);
- };
- }
-};
-
-//Init.addConditional(function(){jpf.Comm.register("http", "variables", HTTP);}, null, ['Kernel']);
-jpf.Init.run('http');
- - -/*FILEHEAD(/var/lib/jpf/src/elements/teleport/iframe.js)SIZE(-1077090856)TIME(1237370962)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-jpf.Init.run('XmlDatabase');
- - -/*FILEHEAD(/var/lib/jpf/src/elements/teleport/rpc/header.js)SIZE(-1077090856)TIME(1238944817)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * Implementation of an RPC protocol which encodes the variable information in
- * the HTTP headers of the request.
- * Example:
- * Javeline Markup Language
- * <code>
- * <j:teleport> - * <j:rpc id="comm" protocol="header"> - * <j:method
- * name = "searchProduct"
- * receive = "processSearch"> - * <j:variable name="search" /> - * <j:variable name="page" /> - * <j:variable name="textbanner" value="1" /> - * </j:method> - * <j:method
- * name = "loadProduct">
- * <j:variable name="id" /> - * <j:variable name="search_id" /> - * </j:method> - * </j:rpc> - * </j:teleport>
- *
- * <j:script>
- * //This function is called when the search returns
- * function processSearch(data, state, extra){
- * alert(data)
- * }
- *
- * //Execute a search for the product car
- * comm.searchProduct('car', 10);
- * </j:script>
- * </code>
- *
- * @constructor
- *
- * @addenum rpc[@protocol]:header
- *
- * @inherits jpf.BaseComm
- * @inherits jpf.http
- * @inherits jpf.rpc
- *
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.4
- *
- * @default_private
- */
-jpf.header = function(){
- this.supportMulticall = false;
- this.method = "GET";
- this.vartype = "header";
- this.isXML = true;
- this.namedArguments = true;
-
- // Register Communication Module
- jpf.teleport.register(this);
-
- // Stand Alone
- if (!this.uniqueId) {
- jpf.makeClass(this);
- this.inherit(jpf.BaseComm, jpf.http, jpf.rpc);
- }
-
- this.unserialize = function(str){
- return str;
- }
-
- // Create message to send
- this.serialize = function(functionName, args){
- for (var hFunc = [], i = 0; i < args.length; i++) {
- if (!args[i][0] || !args[i][1])
- continue;
-
- jpf.console.info("<strong>" + args[i][0] + ":</strong> " + args[i][1] + "<br />", "teleport");
-
- http.setRequestHeader(args[i][0], args[i][1]);
- }
-
- this.$HeaderHook = new Function('http', hFunc.join("\n"));
-
- return "";
- }
-
- this.$load = function(x){
- if (x.getAttribute("method-name")) {
- var mName = x.getAttribute("method-name");
- var nodes = x.childNodes;
-
- for (var i = 0; i < nodes.length; i++) {
- var y = nodes[i];
- var v = y.insertBefore(x.ownerDocument.createElement("variable"),
- y.firstChild);
- v.setAttribute("name", mName);
- v.setAttribute("value", y.getAttribute("name"));
- }
- }
- }
-}
-
- - -/*FILEHEAD(/var/lib/jpf/src/elements/teleport/rpc/soap.js)SIZE(-1077090856)TIME(1238944817)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * Implementation of the SOAP RPC protocol.
- * Implementation of the Common Gateway Interface (CGI) as a module for the RPC
- * plugin of jpf.teleport.
- * Example:
- * Javeline Markup Language
- * <code>
- * <j:teleport> - * <j:rpc id="comm"
- * protocol = "soap"
- * url = "http://example.com/show-product.php"
- * soap-prefix = "m"
- * soap-xmlns = "http://example.com"> - * <j:method
- * name = "searchProduct"
- * receive = "processSearch"> - * <j:variable name="search" /> - * <j:variable name="page" /> - * <j:variable name="textbanner" value="1" /> - * </j:method> - * <j:method
- * name = "loadProduct"> - * <j:variable name="id" /> - * <j:variable name="search_id" /> - * </j:method> - * </j:rpc> - * </j:teleport>
- *
- * <j:script>
- * //This function is called when the search returns
- * function processSearch(data, state, extra){
- * alert(data)
- * }
- *
- * //Execute a search for the product car
- * comm.searchProduct('car', 10);
- * </j:script>
- * </code>
- *
- * @constructor
- *
- * @addenum rpc[@protocol]:soap
- *
- * @inherits jpf.BaseComm
- * @inherits jpf.http
- * @inherits jpf.rpc
- *
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.4
- *
- * @private
- */
-jpf.soap = function(){
- this.supportMulticall = false;
- this.method = "POST";
- this.useXML = true;
-
- this.nsName = "m";
- this.nsURL = "http://www.javeline.org";
-
- this.namedArguments = true;
-
- // Register Communication Module
- jpf.teleport.register(this);
-
- // Stand Alone
- if (!this.uniqueId) {
- jpf.makeClass(this);
- this.inherit(jpf.BaseComm, jpf.http, jpf.rpc);
- }
-
- // Serialize Objects
- var serialize = {
- host : this,
-
- object : function(o){
- var wo = o;//.valueOf();
-
- for (prop in wo) {
- if (typeof wo[prop] != "function" && prop != "type") {
- retstr += this.host.doSerialize(wo[prop], prop);
- }
- }
-
- return retstr;
- },
-
- string : function(s){
- return s.replace(/\]\]/g, "] ]");//"<![CDATA[" + s.replace(/\]\]/g, "] ]") + "]]>";
- },
-
- number : function(i){
- return i;
- },
-
- "boolean" : function(b){
- return b == true ? 1 : 0;
- },
-
- date : function(d){
- //Could build in possibilities to express dates
- //in weeks or other iso8601 possibillities
- //hmmmm ????
- //19980717T14:08:55
- return doYear(d.getUTCYear()) + doZero(d.getMonth())
- + doZero(d.getUTCDate()) + "T" + doZero(d.getHours())
- + ":" + doZero(d.getMinutes()) + ":" + doZero(d.getSeconds());
-
- function doZero(nr) {
- nr = String("0" + nr);
- return nr.substr(nr.length-2, 2);
- }
-
- function doYear(year) {
- if (year > 9999 || year < 0)
- XMLRPC.handleError(new Error("Unsupported year: " + year));
-
- year = String("0000" + year)
- return year.substr(year.length - 4, 4);
- }
- },
-
- array : function(a){
- var retstr = "";
- for(var i = 0; i < a.length; i++)
- retstr += this.host.doSerialize(a[i], "item");
-
- return retstr;
- }
- }
-
- this.doSerialize = function(args, name){
- var c = name ? args : args[1];
- var name = name ? name : args[0];
-
- if (typeof c == "function") throw new Error("Cannot Parse functions");
-
- if (c === false)
- return '<' + name + ' xsi:null="1"/>';
- else
- return '<' + name + ' ' + this.getXSIType(c) + '>'
- + serialize[c.dataType || "object"](c) + '</' + name + '>';
- }
-
- // get xsi:type
- this.getXSIType = function(c){
- if (!c.dataType) return '';
- else if (c.dataType == "array")
- return 'xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="xsd:ur-type['
- + c.length + ']"';
- else if (c.dataType == "number")
- return 'xsi:type="' + (parseInt(c) == c ? "xsd:int" : "xsd:float")
- + '"';
- else if (c.dataType == "data")
- return 'xsi:type="xsd:timeInstant"';
- else
- return 'xsi:type="xsd:' + c.dataType + '"';
- }
-
- // Create message to send
- this.serialize = function(functionName, args){
- //Construct the SOAP message
-
- var message = '<?xml version="1.0"?>' +
- '<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/1999/XMLSchema" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance">' +
- '<SOAP-ENV:Body>' +
- '<' + this.nsName + ':' + functionName + ' xmlns:'
- + this.nsName + '="' + this.nsURL + '">'
-
- for (var i = 0; i < args.length; i++) {
- message += this.doSerialize(args[i]);
- }
-
- message += '</' + this.nsName + ':' + functionName
- + '></SOAP-ENV:Body></SOAP-ENV:Envelope>';
-
- return message;
- }
-
- this.$HeaderHook = function(http){
- http.setRequestHeader('SOAPAction', '"'
- + this.url.replace(/http:\/\/.*\/([^\/]*)$/, "$1") + '"');
- }
-
- this.unserialize = function(data){
- return data;
- var ret, i;
-
- //xsi:type
- var type = data.getAttribute("xsi:type");
- switch (type) {
- case "xsd:string":
- return (data.firstChild)
- ? new String(data.firstChild.nodeValue)
- : "";
- break;
- case "xsd:int":
- case "xsd:double":
- case "xsd:float":
- return (data.firstChild) ? new Number(data.firstChild.nodeValue) : 0;
- break;
- case "xsd:timeInstant":
- /*
- Have to read the spec to be able to completely
- parse all the possibilities in iso8601
- 07-17-1998 14:08:55
- 19980717T14:08:55
- */
-
- var sn = jpf.dateSeparator;
-
- if(/^(\d{4})(\d{2})(\d{2})T(\d{2}):(\d{2}):(\d{2})/
- .test(data.firstChild.nodeValue)){//data.text)){
- return new Date(RegExp.$2 + sn + RegExp.$3 + sn +
- RegExp.$1 + " " + RegExp.$4 + ":" +
- RegExp.$5 + ":" + RegExp.$6);
- }
- else {
- return new Date();
- }
- break;
- case "xsd:boolean":
- return Boolean(isNaN(parseInt(data.firstChild.nodeValue))
- ? (data.firstChild.nodeValue == "true")
- : parseInt(data.firstChild.nodeValue))
- break;
- case "SOAP-ENC:base64":
- return jpf.crypt.Base64.decode(data.firstChild.nodeValue);
- break;
- case "SOAP-ENC:Array":
- var nodes = data.childNodes;
-
- ret = [];
- for (var i = 0; i < nodes.length; i++) {
- if(nodes[i].nodeType != 1)
- continue;
- ret.push(this.unserialize(nodes[i]));
- }
-
- return ret;
- break;
- default:
- //Custom Type
- if (type && !self[type])
- throw new Error(jpf.formatErrorString(1084, null, "SOAP", "Invalid Object Specified in SOAP message: " + type));
-
- var nodes = data.childNodes;
- var o = type ? new self[type] : {};
-
- ret = new Array();
- for(var i = 0; i < nodes.length; i++) {
- if (nodes[i].nodeType != 1) continue;
- ret[nodes[i].tagName] = this.unserialize(nodes[i]);
- }
-
- return ret;
- break;
- }
- }
-
- // Check Received Data for errors
- this.isValid = function(extra){
- /*
- var fault = data.selectSingleNode("Fault");
- if (fault) {
- var nr = fault.selectSingleNode("faultcode/text()").nodeValue;
- var msg = "\n" + fault.selectSingleNode("faultstring/text()").nodeValue;
- throw new Error(nr, msg);
- }
- else if (data.getElementsByTagName("Errors")) {
- var fault = data.getElementsByTagName("Errors")[0];
- var nr = fault.selectSingleNode("node()/node()/text()").nodeValue;
- var msg = "\n" + fault.selectSingleNode("node()/node()[2]/text()").nodeValue;
- throw new Error(nr, msg);
- }
- */
-
- var data = extra.data;
-
- // IE Hack
- if (!jpf.supportNamespaces)
- data.ownerDocument.setProperty("SelectionNamespaces",
- "xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xds='http://www.w3.org/2001/XMLSchema' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'");
-
- rvalue = data.getElementsByTagName("SOAP-ENV:Body")[0];///node()/node()[2]
- if (!rvalue && data.getElementsByTagNameNS)
- rvalue = data.getElementsByTagNameNS("http://schemas.xmlsoap.org/soap/envelope/", "Body")[0]
-
- extra.data = rvalue;
-
- return true;
- }
-
- this.$load = function(x){
- if (x.getAttribute("soap-prefix"))
- this.nsName = x.getAttribute("soap-prefix");
- if (x.getAttribute("soap-xmlns"))
- this.nsURL = x.getAttribute("soap-xmlns");
- }
-}
-
- - -/*FILEHEAD(/var/lib/jpf/src/elements/teleport/rpc/jsonrpc.js)SIZE(-1077090856)TIME(1238944817)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * Implementation of the JSON-RPC protocol as a module for the RPC
- * plugin of jpf.teleport.
- * Example:
- * Javeline Markup Language
- * <code>
- * <j:teleport> - * <j:rpc id="comm" protocol="jsonrpc"> - * <j:method
- * name = "searchProduct"
- * receive = "processSearch"> - * <j:variable name="search" /> - * <j:variable name="page" /> - * <j:variable name="textbanner" value="1" /> - * </j:method> - * <j:method
- * name = "loadProduct">
- * <j:variable name="id" /> - * <j:variable name="search_id" /> - * </j:method> - * </j:rpc> - * </j:teleport>
- *
- * <j:script>
- * //This function is called when the search returns
- * function processSearch(data, state, extra){
- * alert(data)
- * }
- *
- * //Execute a search for the product car
- * comm.searchProduct('car', 10);
- * </j:script>
- * </code>
- *
- * @constructor
- *
- * @addenum rpc[@protocol]:jsonrpc
- *
- * @inherits jpf.BaseComm
- * @inherits jpf.http
- * @inherits jpf.rpc
- *
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.4
- *
- * @default_private
- */
-jpf.jsonrpc = function(){
- this.supportMulticall = false;
- this.multicall = false;
-
- this.method = "POST";
- this.useXML = false;
- this.id = 0;
- this.namedArguments = false;
-
- // Register Communication Module
- jpf.teleport.register(this);
-
-
- // Stand Alone
- if (!this.uniqueId) {
- jpf.makeClass(this);
- this.inherit(jpf.BaseComm, jpf.http, jpf.rpc);
- }
-
- this.getSingleCall = function(name, args, obj){
- obj.push({
- method: name,
- params: args
- });
- }
-
- // Create message to send
- this.serialize = function(functionName, args){
- this.fName = functionName;
- this.id++;
-
- //Construct the XML-RPC message
- var message = '{"method":"' + functionName + '","params":'
- + jpf.serialize(args) + ',"id":' + this.id + '}';
- return message;
- }
-
- this.$HeaderHook = function(http){
- http.setRequestHeader('X-JSON-RPC', this.fName);
- }
-
- this.unserialize = function(str){
- var obj = eval('obj=' + str);
- return obj.result;
- }
-}
-
- - -/*FILEHEAD(/var/lib/jpf/src/elements/teleport/rpc/jphp.js)SIZE(-1077090856)TIME(1238944817)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * Implementation of an RPC protocol which encodes the data in a serialized
- * format in the same way as the php serialize() function does. It requires
- * json in return. This protocol was originally designed to make use of the
- * native unserializer methods on both sides of the line.
- * Example:
- * Javeline Markup Language
- * <code>
- * <j:teleport> - * <j:rpc id="comm" protocol="jphp"> - * <j:method
- * name = "searchProduct"
- * receive = "processSearch" /> - * <j:method
- * name = "loadProduct" />
- * </j:rpc> - * </j:teleport>
- *
- * <j:script>
- * //This function is called when the search returns
- * function processSearch(data, state, extra){
- * alert(data)
- * }
- *
- * //Execute a search for the product car
- * comm.searchProduct('car', 10);
- * </j:script>
- * </code>
- *
- * @constructor
- *
- * @addenum rpc[@protocol]:jphp
- *
- * @inherits jpf.BaseComm
- * @inherits jpf.http
- * @inherits jpf.rpc
- *
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.4
- *
- * @default_private
- */
-jpf.jphp = function(){
- this.supportMulticall = true;
- this.multicall = false;
- this.mcallname = "multicall";
- this.method = "POST";
- this.useXML = true;
- this.namedArguments = false;
-
- // Register Communication Module
- jpf.teleport.register(this);
-
- // Stand Alone
- if (!this.uniqueId) {
- jpf.makeClass(this);
- /**
- * @inherits jpf.BaseComm
- * @inherits jpf.http
- * @inherits jpf.rpc
- */
- this.inherit(jpf.BaseComm, jpf.http, jpf.rpc);
- }
-
- // Serialize Objects
- var serialize = {
- host: this,
-
- object: function(ob){
- var ob = ob.valueOf();
-
- var length = 0, x = "";
- for (prop in ob) {
- if (typeof this[prop] != "function") {
- length++;
- //WEIRD FUCKED UP INTERNET EXPLORER BUG
- var r = prop;
- x += this.host.doSerialize(r) + ";"
- + this.host.doSerialize(ob[r])
- + (typeof ob[r] == "object" || typeof ob[r] == "array"
- ? "" : ";");
- }
- }
-
- if (ob.className)
- return "O:" + ob.className.length + ":\"" + ob.className
- + "\":" + length + ":{" + x.substr(0, x.length) + "}";
- return "a:" + length + ":{" + x.substr(0, x.length) + "}";
- },
-
- string: function(str){
- var str = str.replace(/[\r]/g, "");
- str = str.replace(/\]\]/g, "\]-\]-\]").replace(/\]\]/g, "\]-\]-\]");
- return "s:" + str.length + ":\"" + str + "\"";
- },
-
- number: function(nr){
- if (nr == parseInt(nr))
- return "i:" + nr;
- else
- if (nr == parseFloat(nr))
- return "d:" + nr;
- else
- return this["boolean"](false);
- },
-
- "boolean": function(b){
- return "b:" + (b == true ? 1 : 0);
- },
-
- array: function(ar){
- var x = "a:" + ar.length + ":{";
- for (var i = 0; i < ar.length; i++)
- x += "i:" + i + ";" + this.host.doSerialize(ar[i])
- + (i < ar.length
- && typeof ar[i] != "object"
- && typeof ar[i] != "array" ? ";" : "");
-
- return x + "}";
- }
- }
-
- this.unserialize = function(str){
- return eval(str.replace(/\|-\|-\|/g, "]]").replace(/\|\|\|/g, "\\n"));
- }
-
- this.doSerialize = function(args){
- if (typeof args == "function") {
- throw new Error("Cannot Parse functions");
- }
- else
- if (jpf.isNot(args))
- return serialize["boolean"](false);
-
- return serialize[args.dataType || "object"](args);
- }
-
- // Create message to send
- this.serialize = function(functionName, args){
- //Construct the XML-RPC message
- var message = "<?xml version='1.0' encoding='UTF-16'?><run m='"
- + functionName + "'><![CDATA[";
- //for(i=0;i<args.length;i++){
- message += this.doSerialize(args);
- //}
-
- return message + "]]></run>";
- }
-
- // Check Received Data for errors
- this.isValid = function(extra){
- var data = extra.data;
-
- //handle method result
- if (data && data.tagName == "data") {
- data = data.firstChild.nodeValue;
-
- //error handling
- if (data && data[0] == "error") {
- extra.message = data[1];
- return false;
- }
- }
- else {
- extra.message = "Malformed RPC Message: Parse Error\n\n:'" + http.responseText + "'";
- return false;
- }
-
- extra.data = data;
- return true;
- }
-}
-
- - -/*FILEHEAD(/var/lib/jpf/src/elements/teleport/rpc/xmlrpc.js)SIZE(-1077090856)TIME(1238944817)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * Implementation of the XML-RPC protocol as a module for the RPC
- * plugin of jpf.teleport.
- * Example:
- * Javeline Markup Language
- * <code>
- * <j:teleport> - * <j:rpc id="comm" protocol="xmlrpc"> - * <j:method
- * name = "searchProduct"
- * receive = "processSearch" /> - * <j:method
- * name = "loadProduct" /> - * </j:rpc> - * </j:teleport>
- *
- * <j:script>
- * //This function is called when the search returns
- * function processSearch(data, state, extra){
- * alert(data)
- * }
- *
- * //Execute a search for the product car
- * comm.searchProduct('car', 10);
- * </j:script>
- * </code>
- *
- * @constructor
- *
- * @addenum rpc[@protocol]:xmlrpc
- *
- * @inherits jpf.BaseComm
- * @inherits jpf.http
- * @inherits jpf.rpc
- *
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.4
- *
- * @default_private
- */
-jpf.xmlrpc = function(){
- this.supportMulticall = true;
- this.multicall = false;
- this.mcallname = "system.multicall";
- this.method = "POST";
- this.useXML = true;
-
- this.namedArguments = false;
-
- // Register Communication Module
- jpf.teleport.register(this);
-
- // Stand Alone
- if (!this.uniqueId) {
- jpf.makeClass(this);
- this.inherit(jpf.BaseComm, jpf.http, jpf.rpc);
- }
-
- // Serialize Objects
- var serialize = {
- host: this,
-
- object: function(o){
- var wo = o;//.valueOf();
- retstr = "<struct>";
-
- for (prop in wo) {
- if (typeof wo[prop] != "function" && prop != "type") {
- retstr += "<member><name>" + prop + "</name><value>"
- + this.host.doSerialize(wo[prop]) + "</value></member>";
- }
- }
- retstr += "</struct>";
-
- return retstr;
- },
-
- string: function(s){
- //<![CDATA[***your text here***]]>
- //return "<string><![CDATA[" + s.replace(/\]\]\>/g, "").replace(/\<\!\[\CDATA\[/g, "") + "]]></string>";//.replace(/</g, "<").replace(/&/g, "&")
- return "<string><![CDATA[" + s.replace(/&/g, "&")
- .replace(/</g, "<").replace(/>/g, ">") + "]]></string>";
- //var str = "<string>" + s.replace(/\&/g, "&").replace(/\</g, "<").replace(/\>/g, ">") + "</string>";//.replace(/</g, "<").replace(/&/g, "&")
- return str;
- },
-
- number: function(i){
- if (i == parseInt(i)) {
- return "<int>" + i + "</int>";
- }
- else
- if (i == parseFloat(i)) {
- return "<double>" + i + "</double>";
- }
- else {
- return this["boolean"](false);
- }
- },
-
- "boolean": function(b){
- if (b == true)
- return "<boolean>1</boolean>";
- else
- return "<boolean>0</boolean>";
- },
-
- date: function(d){
- //Could build in possibilities to express dates
- //in weeks or other iso8601 possibillities
- //hmmmm ????
- //19980717T14:08:55
- return "<dateTime.iso8601>" + doYear(d.getUTCYear())
- + doZero(d.getMonth()) + doZero(d.getUTCDate()) + "T"
- + doZero(d.getHours()) + ":" + doZero(d.getMinutes()) + ":"
- + doZero(d.getSeconds()) + "</dateTime.iso8601>";
-
- function doZero(nr){
- nr = String("0" + nr);
- return nr.substr(nr.length - 2, 2);
- }
-
- function doYear(year){
- if (year > 9999 || year < 0)
- XMLRPC.handleError(new Error(jpf.formatErrorString(1085,
- null, "XMLRPC serialization", "Unsupported year: " + year)));
-
- year = String("0000" + year)
- return year.substr(year.length - 4, 4);
- }
- },
-
- array: function(a){
- var retstr = "<array><data>";
- for (var i = 0; i < a.length; i++) {
- retstr += "<value>";
- retstr += this.host.doSerialize(a[i])
- retstr += "</value>";
- }
- return retstr + "</data></array>";
- }
- }
-
- this.getSingleCall = function(name, args, obj){
- obj.push({
- m: name,
- p: args
- });
- }
-
- this.doSerialize = function(args){
- if (typeof args == "function") {
- throw new Error(jpf.formatErrorString(1086, null, "XMLRPC serialization", "Cannot Parse functions"));
- }
- else
- if (jpf.isNot(args))
- return serialize["boolean"](false);
-
- return serialize[args.dataType || "object"](args);
- }
-
- // Create message to send
- this.serialize = function(functionName, args){
- //Construct the XML-RPC message
- var message = '<?xml version="1.0" encoding=\"UTF-8\"?><methodCall><methodName>'
- + functionName + '</methodName><params>';
- for (var i = 0; i < args.length; i++) {
- message += '<param><value>' + this.doSerialize(args[i]) + '</value></param>';
- }
- message += '</params></methodCall>';
-
- return message;
- }
-
- this.unserialize = function(data){
- var ret, i;
-
- switch (data.tagName) {
- case "string":
- if (jpf.isGecko) {
- data = (new XMLSerializer()).serializeToString(data);
- data = data.replace(/^\<string\>/, '');
- data = data.replace(/\<\/string\>$/, '');
- data = data.replace(/\</g, "<");
- data = data.replace(/\>/g, ">");
-
- return data;
- }
-
- return (data.firstChild) ? data.firstChild.nodeValue : "";
- break;
- case "int":
- case "i4":
- case "double":
- return (data.firstChild) ? new Number(data.firstChild.nodeValue) : 0;
- break;
- case "dateTime.iso8601":
- /*
- Have to read the spec to be able to completely
- parse all the possibilities in iso8601
- 07-17-1998 14:08:55
- 19980717T14:08:55
- */
- var sn = jpf.dateSeparator;
-
- if (/^(\d{4})(\d{2})(\d{2})T(\d{2}):(\d{2}):(\d{2})/
- .test(data.firstChild.nodeValue)) {
- ;//data.text)){
- return new Date(RegExp.$2 + sn + RegExp.$3 + sn +
- RegExp.$1 +
- " " +
- RegExp.$4 +
- ":" +
- RegExp.$5 +
- ":" +
- RegExp.$6);
- }
- else {
- return new Date();
- }
-
- break;
- case "array":
- data = jpf.getNode(data, [0]);
-
- if (data && data.tagName == "data") {
- ret = new Array();
-
- var i = 0;
- while (child = jpf.getNode(data, [i++])) {
- ret.push(this.unserialize(child));
- }
-
- return ret;
- }
- else {
- this.handleError(new Error(jpf.formatErrorString(1087, null, "", "Malformed XMLRPC Message")));
- return false;
- }
- break;
- case "struct":
- ret = {};
-
- var i = 0;
- while (child = jpf.getNode(data, [i++])) {
- if (child.tagName == "member") {
- ret[jpf.getNode(child, [0]).firstChild.nodeValue] =
- this.unserialize(jpf.getNode(child, [1]));
- }
- else {
- this.handleError(new Error(jpf.formatErrorString(1087, null, "", "Malformed XMLRPC Message2")));
- return false;
- }
- }
- return ret;
- break;
- case "boolean":
- return Boolean(isNaN(parseInt(data.firstChild.nodeValue))
- ? (data.firstChild.nodeValue == "true")
- : parseInt(data.firstChild.nodeValue))
- break;
- case "base64":
- return jpf.crypt.Base64.decode(data.firstChild.nodeValue);
- break;
- case "value":
- child = jpf.getNode(data, [0]);
- return (!child) ? ((data.firstChild)
- ? new String(data.firstChild.nodeValue) : "")
- : this.unserialize(child);
- break;
- default:
- throw new Error(jpf.formatErrorString(1088, null, "", "Malformed XMLRPC Message: " + data.tagName));
- return false;
- break;
- }
- }
-
- // Check Received Data for errors
- this.isValid = function(extra){
- var data = extra.data;
-
- if (jpf.getNode(data, [0]).tagName == "fault") {
- if (!jpf.isSafari) {
- var nr = data.selectSingleNode("//member[name/text()='faultCode']/value/int/text()").nodeValue;
- var msg = "\n" + data.selectSingleNode("//member[name/text()='faultString']/value/string/text()").nodeValue;
- }
- else {
- nr = msg = ""
- }
-
- extra.message = msg;
- return false;
- }
-
- extra.data = jpf.getNode(data, [0, 0, 0]);
-
- return true;
- }
-}
-
- - -/*FILEHEAD(/var/lib/jpf/src/elements/teleport/rpc/cgi.js)SIZE(-1077090856)TIME(1238944817)*/ - -/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- */
-
-
-/**
- * Implementation of the Common Gateway Interface (CGI) as a module for the RPC
- * plugin of jpf.teleport.
- * Example:
- * Javeline Markup Language
- * <code>
- * <j:teleport>
- * <j:rpc id="comm" protocol="cgi">
- * <j:method
- * name = "searchProduct"
- * url = "http://example.com/search.php"
- * receive = "processSearch">
- * <j:variable name="search" />
- * <j:variable name="page" />
- * <j:variable name="textbanner" value="1" />
- * </j:method>
- * <j:method
- * name = "loadProduct"
- * url = "http://example.com/show-product.php">
- * <j:variable name="id" />
- * <j:variable name="search_id" />
- * </j:method>
- * </j:rpc>
- * </j:teleport>
- *
- * <j:script>
- * //This function is called when the search returns
- * function processSearch(data, state, extra){
- * alert(data)
- * }
- *
- * //Execute a search for the product car
- * comm.searchProduct('car', 10);
- * </j:script>
- * </code>
- * Remarks:
- * Calls can be made to a server using cgi variables with a special {@link term.datainstruction data instruction}
- * format.
- * <code>
- * get="url:http://www.bla.nl?blah=10&foo={@bar}&example=[10+5]"
- * set="url.post:http://www.bla.nl?blah=10&foo={/bar}&example=[10+5]"
- * </code>
- *
- * @addenum rpc[@protocol]:cgi
- *
- * @constructor
- *
- * @inherits jpf.BaseComm
- * @inherits jpf.http
- * @inherits jpf.rpc
- *
- * @author Ruben Daniels
- * @version %I%, %G%
- * @since 0.4
- *
- * @default_private
- */
-jpf.cgi = function(){
- this.supportMulticall = false;
- this.namedArguments = true;
-
- // Register Communication Module
- jpf.teleport.register(this);
-
- // Stand Alone
- if (!this.uniqueId) {
- jpf.makeClass(this);
- this.inherit(jpf.BaseComm, jpf.http, jpf.rpc);
- }
-
- this.unserialize = function(str){
- return str;
- }
-
- this.getSingleCall = function(name, args, obj){
- obj.push(args);
- }
-
- // Create message to send
- this.serialize = function(functionName, args){
- var vars = [];
-
- function recur(o, stack){
- if (o && o.dataType == "array") {
- for (var j = 0; j < o.length; j++)
- recur(o[j], stack + "%5B" + j + "%5D");//" + j + "
- }
- else if (typeof o == "object") {
- for (prop in o) {
- if (jpf.isSafariOld && (!o[prop] || typeof p[prop] != "object"))
- continue;
-
- if (typeof o[prop] == "function")
- continue;
- recur(o[prop], stack + "%5B" + encodeURIComponent(prop) + "%5D");
- }
- }
- else {
- if (typeof o != "undefined" && o !== null)
- vars.push(stack + "=" + encodeURIComponent(o));
- }
- };
-
- if (this.multicall) {
- vars.push("func" + "=" + this.mcallname);
- for (var i = 0; i < args[0].length; i++)
- recur(args[0][i], "f%5B" + i + "%5D");
- }
- else {
- for (prop in args) {
- if (jpf.isSafariOld && (!args[prop] || typeof args[prop] == "function"))
- continue;
-
- recur(args[prop], prop);
- }
- }
-
- if (!this.baseUrl)
- this.baseUrl = this.url;
-
- this.url = this.urls[functionName]
- ? this.urls[functionName]
- : this.baseUrl;
-
- if (this.method != "GET")
- return vars.join("&");
-
- this.url = this.url + (vars.length
- ? (this.url.indexOf("?") > -1 ? "&" : "?") + vars.join("&")
- : "");
-
- return "";
- }
-
- this.$load = function(x){
- this.method = (x.getAttribute("http-method") || "GET").toUpperCase();
- this.contentType = this.method == "GET"
- ? null
- : "application/x-www-form-urlencoded";
-
- if (x.getAttribute("method-name")) {
- var mName = x.getAttribute("method-name");
- var nodes = x.childNodes;
-
- for (var v, i = 0; i < nodes.length; i++) {
- if (nodes[i].nodeType != 1)
- continue;
-
- v = nodes[i].insertBefore(x.ownerDocument.createElement("variable"),
- nodes[i].firstChild);
- v.setAttribute("name", mName);
- v.setAttribute("value", nodes[i].getAttribute("name"));
- }
- }
- }
-
- /**
- * Submit a form with ajax (GET)
- *
- * @param {HTMLElement} form the html form element to submit.
- * @param {Function} callback called when the http call returns.
- */
- this.submitForm = function(form, callback){
- if (!this['postform'])
- this.addMethod('postform', callback);
-
- var args = [];
- for (var i = 0; i < form.elements.length; i++) {
- if (!form.elements[i].name)
- continue;
- if (form.elements[i].tagname = 'input'
- && (form.elements[i].type == 'checkbox'
- || form.elements[i].type == 'radio')
- && !form.elements[i].checked)
- continue;
-
- if (form.elements[i].tagname = 'select' && form.elements[i].multiple) {
- for (j = 0; j < form.elements[i].options.length; j++) {
- if (form.elements[i].options[j].selected)
- args.push(form.elements[i].name
- + "="
- + encodeURIComponent(form.elements[i].options[j].value));
- }
- }
- else {
- args.push(form.elements[i].name
- + "="
- + encodeURIComponent(form.elements[i].value));
- }
- }
-
- var loc = (form.action || location.href);
- this.urls['postform'] = loc + (loc.indexOf("?") > -1 ? "&" : "?") + args.join("&");
- this['postform'].call(this);
-
- return false;
- }
-}
-
-jpf.namespace("datainstr.url", function(xmlContext, options, callback){
- if (!options.parsed) {
- var url = options.instrData.join(":");
-
- if (xmlContext) {
- //Xpath
- url = url.replace(/\{(.*?)\}/g,
- function(m, xpath){
- var o = xmlContext.selectSingleNode(xpath);
- return o
- ? (o.nodeType >= 2 && o.nodeType <= 4
- ? o.nodeValue
- : o.xml || o.serialize()) //jpf.xmldb.convertXml(o, "cgivars"))
- : ""
- });
-
- //Javascript
- /*url = url.replace(/\[(.*?)\]/g,
- function(m, js){
- var o;
-
- try{
- with (options) {
- o = eval(js);
- }
- }
- catch(e){
- throw new Error(jpf.formatErrorString(0, null,
- "Saving/Loading data", "Could not execute javascript \
- code in process instruction '" + js
- + "' with error " + e.message));
- }
-
- return o || "";
- });*/
- }
-
- var split = url.split("?");
- url = split.shift();
- var query = split.join("?");
- var args = options.args;
- var httpBody = (args && args.length)
- ? (args[0].nodeType
- ? args[0].xml || args[0].serialize()
- : jpf.serialize(args[0]))
- : query;
-
- if (options.preparse) {
- options.parsed = [url, query, httpBody];
- options.preparse = -1;
- return;
- }
- }
- else {
- var url = options.parsed[0];
- var query = options.parsed[1];
- var httpBody = options.parsed[2];
- }
-
- var oHttp = new jpf.http();
- oHttp.contentType = "application/x-www-form-urlencoded";
- oHttp.method = (options.instrType.replace(/url.?/, "") || "GET").toUpperCase();
- oHttp.get(jpf.getAbsolutePath(jpf.appsettings.baseurl, url + (oHttp.method == "GET" ? "?" + query : "")), callback,
- jpf.extend({data : httpBody}, options));
-});
-
-
- - -/*FILEHEAD(/var/lib/jpf/src/elements/appsettings/iepngfix.js)SIZE(-1077090856)TIME(1238933680)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - -jpf.iepngfix = (function() { - var sNodes = null, - aNodes = null, - applyPositioning = true, - // Path to a transparent GIF image - shim = 'images/blank.gif'; - - var fnLoadPngs = function() { - if (aNodes === null) { - if (sNodes) - aNodes = sNodes.splitSafe(','); - else - aNodes = [document]; - } - - for (var j = 0, l = aNodes.length, node; j < l; j++) { - if (typeof aNodes[j] == "string") - aNodes[j] = document.getElementById(aNodes[j]); - node = aNodes[j]; - if (!node) continue; - - for (var i = node.all.length - 1, obj = null; (obj = node.all[i]); i--) { - // background pngs - if (obj.currentStyle.backgroundImage.match(/\.png/i) !== null) { - bg_fnFixPng(obj); - } - // image elements - if (obj.tagName == 'IMG' && obj.src.match(/\.png$/i) !== null){ - el_fnFixPng(obj); - } - // apply position to 'active' elements - if (applyPositioning && (obj.tagName == 'A' || obj.tagName == 'INPUT') - && obj.style.position === ''){ - obj.style.position = 'relative'; - } - } - } - }; - - var bg_fnFixPng = function(obj) { - var mode = 'scale'; - var bg = obj.currentStyle.backgroundImage; - var src = bg.substring(5, bg.length - 2); - if (obj.currentStyle.backgroundRepeat == 'no-repeat') - mode = 'crop'; - obj.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" - + src + "', sizingMethod='" + mode + "')"; - obj.style.backgroundImage = 'url(' + shim + ')'; - }; - - var el_fnFixPng = function(img) { - var src = img.src; - img.style.width = img.width + "px"; - img.style.height = img.height + "px"; - img.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" - + src + "', sizingMethod='scale')"; - img.src = shim; - }; - - return { - limitTo: function(s) { - sNodes = s; - return this; - }, - run: fnLoadPngs - }; -})(); - - - -/*FILEHEAD(/var/lib/jpf/src/jpack_end.js)SIZE(-1077090856)TIME(1238933683)*/ - -jpf.Init.addConditional(function(){
- jpf.dispatchEvent("domready");
-}, null, ["body", "class"]);
-
-/*if(document.body)
- jpf.Init.run('body');
-else*/
- jpf.addDomLoadEvent(function(){jpf.Init.run('body');});
-
-//Start
-jpf.start();
- - -/*FILEHEAD(/var/lib/jpf/src/loader-jaw.js)SIZE(-1077090856)TIME(1238933683)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - - -/*FILEHEAD(/var/lib/jpf/src/jpf-jaw.js)SIZE(-1077090856)TIME(1238933683)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - - - -/*FILEHEAD(/var/lib/jpf/src/loader.js)SIZE(-1077090856)TIME(1238933683)*/ - -/* - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - * - */ - -/* *************************************************************** -** -** Bootloader for Javeline PlatForm -** -** First include jpf.js, then include this file (loader.js) -** Then just go about it as you would with the packaged version -** Adapt this file to include your preferred modules -** -****************************************************************/ - - - -/*FILEHEAD(/var/lib/jpf/src/test/assets/jscontext.js)SIZE(-1077090856)TIME(1238933670)*/ - - - -/*FILEHEAD(/var/lib/jpf/src/test/assets/jsunittest.js)SIZE(-1077090856)TIME(1238933670)*/ - diff --git a/ajax-broker/logo.png b/ajax-broker/logo.png Binary files differdeleted file mode 100644 index bb5195a..0000000 --- a/ajax-broker/logo.png +++ /dev/null diff --git a/ajax-broker/resources/FAVideo.swf b/ajax-broker/resources/FAVideo.swf Binary files differdeleted file mode 100644 index 6f93fd4..0000000 --- a/ajax-broker/resources/FAVideo.swf +++ /dev/null diff --git a/ajax-broker/resources/ajax_logo.png b/ajax-broker/resources/ajax_logo.png Binary files differdeleted file mode 100644 index 578aa80..0000000 --- a/ajax-broker/resources/ajax_logo.png +++ /dev/null diff --git a/ajax-broker/resources/arrow_down.gif b/ajax-broker/resources/arrow_down.gif Binary files differdeleted file mode 100644 index 01d9f67..0000000 --- a/ajax-broker/resources/arrow_down.gif +++ /dev/null diff --git a/ajax-broker/resources/arrow_gray_down.gif b/ajax-broker/resources/arrow_gray_down.gif Binary files differdeleted file mode 100644 index 3fce30c..0000000 --- a/ajax-broker/resources/arrow_gray_down.gif +++ /dev/null diff --git a/ajax-broker/resources/arrow_gray_right.gif b/ajax-broker/resources/arrow_gray_right.gif Binary files differdeleted file mode 100644 index a473caa..0000000 --- a/ajax-broker/resources/arrow_gray_right.gif +++ /dev/null diff --git a/ajax-broker/resources/arrow_right.gif b/ajax-broker/resources/arrow_right.gif Binary files differdeleted file mode 100644 index 398b498..0000000 --- a/ajax-broker/resources/arrow_right.gif +++ /dev/null diff --git a/ajax-broker/resources/arrow_white_down.gif b/ajax-broker/resources/arrow_white_down.gif Binary files differdeleted file mode 100644 index 9df0a72..0000000 --- a/ajax-broker/resources/arrow_white_down.gif +++ /dev/null diff --git a/ajax-broker/resources/arrow_white_right.gif b/ajax-broker/resources/arrow_white_right.gif Binary files differdeleted file mode 100644 index aac9ce5..0000000 --- a/ajax-broker/resources/arrow_white_right.gif +++ /dev/null diff --git a/ajax-broker/resources/backgrounds.png b/ajax-broker/resources/backgrounds.png Binary files differdeleted file mode 100644 index 48b5f88..0000000 --- a/ajax-broker/resources/backgrounds.png +++ /dev/null diff --git a/ajax-broker/resources/bullet_green.png b/ajax-broker/resources/bullet_green.png Binary files differdeleted file mode 100644 index eb062f3..0000000 --- a/ajax-broker/resources/bullet_green.png +++ /dev/null diff --git a/ajax-broker/resources/buttons.png b/ajax-broker/resources/buttons.png Binary files differdeleted file mode 100644 index 475d8bc..0000000 --- a/ajax-broker/resources/buttons.png +++ /dev/null diff --git a/ajax-broker/resources/corner_left_bottom.gif b/ajax-broker/resources/corner_left_bottom.gif Binary files differdeleted file mode 100644 index bd96eca..0000000 --- a/ajax-broker/resources/corner_left_bottom.gif +++ /dev/null diff --git a/ajax-broker/resources/corner_left_top.gif b/ajax-broker/resources/corner_left_top.gif Binary files differdeleted file mode 100644 index bd39641..0000000 --- a/ajax-broker/resources/corner_left_top.gif +++ /dev/null diff --git a/ajax-broker/resources/corner_right_bottom.gif b/ajax-broker/resources/corner_right_bottom.gif Binary files differdeleted file mode 100644 index bf2ab92..0000000 --- a/ajax-broker/resources/corner_right_bottom.gif +++ /dev/null diff --git a/ajax-broker/resources/corner_right_top.gif b/ajax-broker/resources/corner_right_top.gif Binary files differdeleted file mode 100644 index 9332054..0000000 --- a/ajax-broker/resources/corner_right_top.gif +++ /dev/null diff --git a/ajax-broker/resources/debug_title.gif b/ajax-broker/resources/debug_title.gif Binary files differdeleted file mode 100644 index 9d059dc..0000000 --- a/ajax-broker/resources/debug_title.gif +++ /dev/null diff --git a/ajax-broker/resources/error.png b/ajax-broker/resources/error.png Binary files differdeleted file mode 100644 index 5a3b87b..0000000 --- a/ajax-broker/resources/error.png +++ /dev/null diff --git a/ajax-broker/resources/exclamation.png b/ajax-broker/resources/exclamation.png Binary files differdeleted file mode 100644 index 4d9cee2..0000000 --- a/ajax-broker/resources/exclamation.png +++ /dev/null diff --git a/ajax-broker/resources/javeline_logo.gif b/ajax-broker/resources/javeline_logo.gif Binary files differdeleted file mode 100644 index cd3e56e..0000000 --- a/ajax-broker/resources/javeline_logo.gif +++ /dev/null diff --git a/ajax-broker/resources/javeline_logo_small.png b/ajax-broker/resources/javeline_logo_small.png Binary files differdeleted file mode 100644 index df5e21b..0000000 --- a/ajax-broker/resources/javeline_logo_small.png +++ /dev/null diff --git a/ajax-broker/resources/jpf_logo.png b/ajax-broker/resources/jpf_logo.png Binary files differdeleted file mode 100644 index 86ee649..0000000 --- a/ajax-broker/resources/jpf_logo.png +++ /dev/null diff --git a/ajax-broker/resources/network_check.txt b/ajax-broker/resources/network_check.txt deleted file mode 100644 index 56a6051..0000000 --- a/ajax-broker/resources/network_check.txt +++ /dev/null @@ -1 +0,0 @@ -1
\ No newline at end of file diff --git a/ajax-broker/resources/null.mp3 b/ajax-broker/resources/null.mp3 Binary files differdeleted file mode 100644 index 43cc613..0000000 --- a/ajax-broker/resources/null.mp3 +++ /dev/null diff --git a/ajax-broker/resources/platform_logo.gif b/ajax-broker/resources/platform_logo.gif Binary files differdeleted file mode 100644 index db20f3a..0000000 --- a/ajax-broker/resources/platform_logo.gif +++ /dev/null diff --git a/ajax-broker/resources/progress.gif b/ajax-broker/resources/progress.gif Binary files differdeleted file mode 100644 index 085ccae..0000000 --- a/ajax-broker/resources/progress.gif +++ /dev/null diff --git a/ajax-broker/resources/shadow.gif b/ajax-broker/resources/shadow.gif Binary files differdeleted file mode 100644 index afe49d6..0000000 --- a/ajax-broker/resources/shadow.gif +++ /dev/null diff --git a/ajax-broker/resources/smin.gif b/ajax-broker/resources/smin.gif Binary files differdeleted file mode 100644 index 2be3969..0000000 --- a/ajax-broker/resources/smin.gif +++ /dev/null diff --git a/ajax-broker/resources/soundmanager2.swf b/ajax-broker/resources/soundmanager2.swf Binary files differdeleted file mode 100644 index 1efaf01..0000000 --- a/ajax-broker/resources/soundmanager2.swf +++ /dev/null diff --git a/ajax-broker/resources/soundmanager2_flash9.swf b/ajax-broker/resources/soundmanager2_flash9.swf Binary files differdeleted file mode 100644 index 2532592..0000000 --- a/ajax-broker/resources/soundmanager2_flash9.swf +++ /dev/null diff --git a/ajax-broker/resources/splitter_docs.gif b/ajax-broker/resources/splitter_docs.gif Binary files differdeleted file mode 100644 index 340a390..0000000 --- a/ajax-broker/resources/splitter_docs.gif +++ /dev/null diff --git a/ajax-broker/resources/splitter_handle_horizontal.gif b/ajax-broker/resources/splitter_handle_horizontal.gif Binary files differdeleted file mode 100644 index 38bdcef..0000000 --- a/ajax-broker/resources/splitter_handle_horizontal.gif +++ /dev/null diff --git a/ajax-broker/resources/splitter_handle_vertical.gif b/ajax-broker/resources/splitter_handle_vertical.gif Binary files differdeleted file mode 100644 index 8b1ee9d..0000000 --- a/ajax-broker/resources/splitter_handle_vertical.gif +++ /dev/null diff --git a/ajax-broker/resources/splus.gif b/ajax-broker/resources/splus.gif Binary files differdeleted file mode 100644 index adb56fa..0000000 --- a/ajax-broker/resources/splus.gif +++ /dev/null diff --git a/ajax-broker/resources/tableHeader.gif b/ajax-broker/resources/tableHeader.gif Binary files differdeleted file mode 100644 index 843d79e..0000000 --- a/ajax-broker/resources/tableHeader.gif +++ /dev/null diff --git a/ajax-broker/resources/tableHeaderActive.gif b/ajax-broker/resources/tableHeaderActive.gif Binary files differdeleted file mode 100644 index 146f647..0000000 --- a/ajax-broker/resources/tableHeaderActive.gif +++ /dev/null diff --git a/ajax-broker/resources/tableHeaderSorted.gif b/ajax-broker/resources/tableHeaderSorted.gif Binary files differdeleted file mode 100644 index 85c2825..0000000 --- a/ajax-broker/resources/tableHeaderSorted.gif +++ /dev/null diff --git a/ajax-broker/resources/tableHeaderSortedActive.gif b/ajax-broker/resources/tableHeaderSortedActive.gif Binary files differdeleted file mode 100644 index 72ba560..0000000 --- a/ajax-broker/resources/tableHeaderSortedActive.gif +++ /dev/null diff --git a/ajax-broker/resources/time.png b/ajax-broker/resources/time.png Binary files differdeleted file mode 100644 index 70b43c0..0000000 --- a/ajax-broker/resources/time.png +++ /dev/null diff --git a/ajax-broker/resources/wmvplayer.xaml b/ajax-broker/resources/wmvplayer.xaml deleted file mode 100644 index a296ffc..0000000 --- a/ajax-broker/resources/wmvplayer.xaml +++ /dev/null @@ -1,67 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -JW WMV Player version 1.1, created with M$ Silverlight 1.0. - -This file contains all logic for the JW WMV Player. For a functional setup, -the following two files are also needed: -- silverlight.js (for instantiating the silverlight plugin) -- wmvplayer.js (this file contains all the scripting logic) - -More info: http://www.jeroenwijering.com/?item=JW_WMV_Player ---> - -<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="320" Height="260"> - <Canvas x:Name="PlayerDisplay" Width="320" Height="240" Background="#FF000000" Visibility="Collapsed"> - <Image x:Name="PlaceholderImage" Width="320" Height="240" /> - <MediaElement x:Name="VideoWindow" Width="320" Height="240" /> - <Canvas x:Name="MuteIcon" Width="40" Height="40" Canvas.Left="140" Canvas.Top="100" Visibility="Collapsed"> - <Path x:Name="MuteIconBack" Width="40" Height="40" Fill="#77000000" Data="F1 M4,0 L36,0 C38,0 40,2 40,4 L40,36 C40,38 38,40 36,40 L4,40 C2,40 0,38 0,36 L0,4 C0,2 2,0 4,0 Z"/> - <Path x:Name="MuteIconFront" Width="18" Height="18" Canvas.Left="13" Canvas.Top="11" Fill="#FFFFFFFF" Data="F1 M0,4 L4,4 L4,14 L0,14 L0,4 M6,4 L11,0 L11,18 L6,14 L6,4 M14,8 L18,8 L18,10 L14,10 L14,8 Z"/> - </Canvas> - <Canvas x:Name="BufferIcon" Width="32" Height="32" Canvas.Left="148" Canvas.Top="98" Visibility="Collapsed"> - <Canvas.RenderTransform> - <RotateTransform x:Name="BufferRotation" Angle="0" CenterX="16" CenterY="16" /> - </Canvas.RenderTransform> - <Canvas.Triggers> - <EventTrigger RoutedEvent="Canvas.Loaded"> - <BeginStoryboard> - <Storyboard> - <DoubleAnimationUsingKeyFrames Storyboard.TargetName="BufferRotation" Storyboard.TargetProperty="Angle" Duration="0:0:1.2" RepeatBehavior="Forever"> - <DiscreteDoubleKeyFrame Value="30" KeyTime="0:0:0.1" /> - <DiscreteDoubleKeyFrame Value="60" KeyTime="0:0:0.2" /> - <DiscreteDoubleKeyFrame Value="90" KeyTime="0:0:0.3" /> - <DiscreteDoubleKeyFrame Value="120" KeyTime="0:0:0.4" /> - <DiscreteDoubleKeyFrame Value="150" KeyTime="0:0:0.5" /> - <DiscreteDoubleKeyFrame Value="180" KeyTime="0:0:0.6" /> - <DiscreteDoubleKeyFrame Value="210" KeyTime="0:0:0.7" /> - <DiscreteDoubleKeyFrame Value="240" KeyTime="0:0:0.8" /> - <DiscreteDoubleKeyFrame Value="270" KeyTime="0:0:0.9" /> - <DiscreteDoubleKeyFrame Value="300" KeyTime="0:0:1" /> - <DiscreteDoubleKeyFrame Value="330" KeyTime="0:0:1.1" /> - <DiscreteDoubleKeyFrame Value="360" KeyTime="0:0:1.2" /> - </DoubleAnimationUsingKeyFrames> - </Storyboard> - </BeginStoryboard> - </EventTrigger> - </Canvas.Triggers> - <Path x:Name="BufferPath1" Width="2" Height="8" Canvas.Left="15" Canvas.Top="0" Stretch="Fill" Fill="#FFFFFFFF" Data="F1 M16,0 L16,0 C16.55,0 17,0.45 17,1 L17,7 C17,7.55 16.55,8 16,8 L16,8C 15.45,8 15,7.55 15,7 L15,1 C15,0.45 15.45,0 16,0 Z "/> - <Path x:Name="BufferPath2" Width="5" Height="7.2" Canvas.Left="7.5" Canvas.Top="2" Stretch="Fill" Fill="#EEFFFFFF" Data="F1 M8,2.14 L8,2.14 C8.48,1.87 9.09,2.03 9.37,2.51 L12.366,7.71 C12.64,8.18 12.48,8.80 12,9.07 L12,9.07 C11.52,9.35 10.91,9.18 10.63,8.71 L7.63,3.51 C7.36,3.03 7.52,2.42 8,2.14 Z "/> - <Path x:Name="BufferPath3" Width="7.2" Height="5" Canvas.Left="2" Canvas.Top="7.5" Stretch="Fill" Fill="#DDFFFFFF" Data="F1 M2.14,8. L2.14,8 C2.42,7.52 3.03,7.36 3.51,7.63 L8.71,10.63 C9.18,10.91 9.35,11.52 9.07,12 L9.07,12 C8.80,12.48 8.18,12.64 7.71,12.36 L2.51,9.37 C2.03,9.09 1.87,8.48 2.14,8 Z "/> - <Path x:Name="BufferPath4" Width="8" Height="2" Canvas.Left="0" Canvas.Top="15" Stretch="Fill" Fill="#BBFFFFFF" Data="F1 M0,16 L0,16 C0,15.45 0.45,15 1,15 L7,15 C7.55,15 8,15.45 8,16 L8,16 C8,16.55 7.55,17 7,17 L1,17 C0.45,17 0,16.55 0,16 Z "/> - <Path x:Name="BufferPath5" Width="7.2" Height="5" Canvas.Left="2" Canvas.Top="19.5" Stretch="Fill" Fill="#AAFFFFFF" Data="F1 M2.14,24 L2.14,24 C1.87,23.52 2.03,22.91 2.51,22.63 L7.71,19.63 C8.18,19.35 8.80,19.52 9.08,20 L9.07,20 C9.35,20.48 9.18,21.09 8.71,21.36 L3.51,24.37 C3.03,24.64 2.42,24.48 2.14,24 Z "/> - <Path x:Name="BufferPath6" Width="5" Height="7.2" Canvas.Left="7.5" Canvas.Top="22.8" Stretch="Fill" Fill="#99FFFFFF" Data="F1 M8,29.86 L8,29.86 C7.52,29.58 7.36,28.97 7.63,28.49 L10.63,23.29 C10.91,22.82 11.52,22.65 12,22.93 L12,22.93 C12.48,23.20 12.64,23.82 12.37,24.29 L9.37,29.49 C9.09,29.97 8.48,30.13 8,29.86 Z "/> - <Path x:Name="BufferPath7" Width="2" Height="8" Canvas.Left="15" Canvas.Top="24" Stretch="Fill" Fill="#77FFFFFF" Data="F1 M16,24 L16,24 C16.55,24 17,24.45 17,25 L17,31 C17,31.55 16.55,32 16,32 L16,32 C15.45,32 15,31.55 15,31 L15,25 C15,24.45 15.45,24 16,24 Z "/> - <Path x:Name="BufferPath8" Width="5" Height="7.2" Canvas.Left="19.5" Canvas.Top="22.8" Stretch="Fill" Fill="#66FFFFFF" Data="F1 M20,22.93 L20,22.93 C20.48,22.65 21.09,22.82 21.36,23.29 L24.37,28.49 C24.64,28.97 24.48,29.58 24,29.86 L24,29.86 C23.52,30.13 22.91,29.97 22.63,29.49 L19.63,24.29 C19.36,23.82 19.52,23.20 20,22.93 Z "/> - <Path x:Name="BufferPath9" Width="7.2" Height="5" Canvas.Left="22.8" Canvas.Top="19.5" Stretch="Fill" Fill="#55FFFFFF" Data="F1 M22.93,20 L22.93,20 C23.20,19.52 23.82,19.36 24.29,19.63 L29.49,22.63 C29.97,22.91 30.13,23.52 29.86,24 L29.86,24 C29.58,24.48 28.97,24.64 28.49,24.37 L23.29,21.37 C22.82,21.09 22.65,20.48 22.93,20 Z "/> - <Path x:Name="BufferPath10" Width="8" Height="2" Canvas.Left="24" Canvas.Top="15" Stretch="Fill" Fill="#33FFFFFF" Data="F1 M24,16 L24,16 C24,15.45 24.45,15 25,15 L31,15 C31.55,15 32,15.45 32,16 L32,16 C32,16.55 31.55,17 31,17 L25,17 C24.45,17 24,16.55 24,16 Z "/> - <Path x:Name="BufferPath11" Width="7.2" Height="5" Canvas.Left="22.8" Canvas.Top="7.5" Stretch="Fill" Fill="#22FFFFFF" Data="F1 M 22.93,12 L22.93,12 C22.65,11.52 22.82,10.91 23.29,10.63 L28.49,7.63 C28.97,7.36 29.58,7.52 29.86,8 L29.86,8 C30.13,8.48 29.97,9.09 29.49,9.37 L24.29,12.36 C23.82,12.64 23.20,12.48 22.93,12 Z "/> - <Path x:Name="BufferPath12" Width="5" Height="7.2" Canvas.Left="19.5" Canvas.Top="2" Stretch="Fill" Fill="#11FFFFFF" Data="F1 M 20,9.07 L20,9.07 C19.52,8.80 19.36,8.18 19.63,7.71 L22.63,2.51 C22.91,2.03 23.52,1.87 24,2.14 L24,2.14 C24.48,2.42 24.64,3.03 24.37,3.51 L21.37,8.71 C21.09,9.18 20.48,9.35 20,9.07 Z "/> - </Canvas> - <TextBlock x:Name="BufferText" Canvas.Left="158" Canvas.Top="108" FontFamily="Verdana" FontSize="9" FontWeight="Bold" Foreground="#FFFFFFFF" Width="12" Height="10"/> - <Canvas x:Name="OverlayCanvas" Width="300" Height="200" Canvas.Left="220" Canvas.Top="10" Visibility="Collapsed"> - <Canvas.Background> - <ImageBrush x:Name="OverlayLogo" AlignmentX="Right" AlignmentY="Top" Stretch="None" /> - </Canvas.Background> - </Canvas> - </Canvas> -</Canvas> diff --git a/ajax-broker/skins.xml b/ajax-broker/skins.xml deleted file mode 100644 index a4ccc83..0000000 --- a/ajax-broker/skins.xml +++ /dev/null @@ -1,10663 +0,0 @@ -<?xml version='1.0'?> -<j:skin xmlns:j="http://www.javeline.com/2005/jml" xmlns="http://www.w3.org/1999/xhtml"> -<j:modalwindow name="modalwindow"> - <j:alias>window</j:alias> - <j:style><![CDATA[ - .north{cursor: url(cursor/n-point.cur);} - .west{cursor: url(cursor/w-point.cur);} - .east{cursor: url(cursor/e-point.cur);} - .south{cursor: url(cursor/s-point.cur);} - .same{cursor: not-allowed;} - - .window { - font-family: Tahoma; - font-size: 11px; - padding : 26px 0 5px 0; - } - - .window .topLeft { - float: left; - background: url("images/window_lt.png") no-repeat top left; - width: 6px; - height: 27px; - margin: 0; - padding: 0; - border: 0; - margin-top : -26px; - _margin-right: -6px; /* IE6 bug fix */ - } - - .windowFocus{ - - } - - .window .topRight { - float: right; - background: url("images/window_rt.png") no-repeat top left; - width: 5px; - height: 27px; - margin: 0; - padding: 0; - border: 0; - margin-top : -26px; - _margin-left: -5px; /* IE6 bug fix */ - } - - .window .title { - background: url("images/window_mt.png") repeat-x top left; - height: 21px; - color: #eeeeee; - position: relative; - margin: 0 5px 0 6px; - padding: 6px 0 0 20px; - border: 0; - font-weight: bold; - margin-top : -26px; - cursor : default; - } - - .window .title img{ - margin: -1px 3px 0 -1px; - position : absolute; - left : 2px; - } - - .window .content { - background : #f5f5f5; - margin-left: 3px; - margin-right: 3px; - position : relative; - height : 100%; - background:#f5f5f5 url(images/page_bt.png) repeat-x top left; - border-right: 1px solid #dcd8d8; - border-top: 1px solid #dcd8d8; - border : 0; /* changed by ruben */ - } - - .windowMin .content{ - overflow : hidden; - } - - .window .borderRight{ - background: url("images/window_border.png") repeat-y top right; - overflow : hidden; - width : 3px; - float : right; - height : 100%; - _margin-left: -3px; /* IE6 bug fix */ - } - - .window .borderLeft { - background: url("images/window_border.png") repeat-y top left; - overflow: hidden; - height : 100%; - float : left; - width : 3px; - _margin-right: -3px; /* IE6 bug fix */ - } - - .window .bottomLeft { - float: left; - background: url("images/window_lb_small.png") no-repeat top left; - width: 3px; - height: 4px; - _margin-right: -3px; /* IE6 bug fix */ - margin-top: -1px; - } - - .window .bottomRight { - float: right; - background: url("images/window_rb_small.png") no-repeat top left; - width: 3px; - height: 4px; - _margin-left: -3px; /* IE6 bug fix */ - margin-top: -1px; - } - - .window .bottomBar { - background: url("images/window_mb_small.png") repeat-x top left; - height: 4px; - color: #FFFFFF; - position: relative; - margin: -2px 3px 0 3px; - border-top: 1px solid #dcd8d8; - } - - .window .bottom{ - position : absolute; - bottom : 0; - width : 100%; - } - - .cover{ - /*background: url(images/spacer.gif);*/ - background: white; - opacity: 0.3; - filter:progid:DXImageTransform.Microsoft.Alpha(opacity=30); - - position: absolute; - left: 0; - top: 0; - width: 100%; - height: 100%; - height: expression(document.documentElement.offsetHeight); - z-index: 10000; - } - - .window .title blockquote{ - margin: 0; - width: 56px; - height: 21px; - position: absolute; - padding: 4px 4px 2px 2px; - top: 0; - right: 0; - /*background: url(images/title.gif) repeat-x;*/ - } - - .window .title blockquote div{ - width: 10px; - height: 9px; - float: right; - padding: 3px; - background: no-repeat 3px 3px; - cursor: default; - _overflow: hidden; /* IE6 bug fix */ - } - - .window .title blockquote div.hover{ - border : 1px solid white; - padding : 2px; - background-position : 2px -10px; - height : 10px; - background-color : transparent; - } - .window .title blockquote div.down{ - background-color : black; - } - - .window .title .max{ - background-image: url(images/win_max.gif); - } - .windowMax .title .max{ - background-image: url(images/win_restore.gif); - } - .window .title .min{ - background-image: url(images/win_min.gif); - } - .windowMin .title .min{ - background-image: url(images/win_restore.gif); - } - .window .title .close{ - width: 11px; - background-image: url(images/win_x.gif); - } - .window .title span{ - width: 16px; - height: 16px; - display: block; - } - - #jpf_outline{ - - } - - #jpf_outline.drag{ - border: 1px solid black; - background: #CCC; - opacity: 0.4; - filter:progid:DXImageTransform.Microsoft.Alpha(opacity=40); - } - - #jpf_outline.resize{ - border: 3px solid black; - background: #CCC; - opacity: 0.3; - filter:progid:DXImageTransform.Microsoft.Alpha(opacity=30); - } - ]]></j:style> - - <j:presentation> - <j:main collapsed-height="30" - min-width="150" min-height="80" - container="div[6]" drag="div[3]" title="div[3]/text()" - icon="div[3]/img" buttons="div[3]/blockquote"> - <div class="window"> - <div class="topLeft"> </div> - <div class="topRight"> </div> - <div class="title"><img src="" />-<blockquote> </blockquote></div> - - <div class="borderLeft"> </div> - <div class="borderRight"> </div> - <div class="content"> </div> - - <div class="bottomLeft"> </div> - <div class="bottomRight"> </div> - <div class="bottomBar"> </div> - </div> - </j:main> - <j:button> - <div> </div> - </j:button> - <j:cover> - <div class='cover'> </div> - </j:cover> - </j:presentation> -</j:modalwindow> -<j:modalwindow name="roundedged"> - <j:alias>window</j:alias> - <j:style><![CDATA[ - .north{cursor: url(cursor/n-point.cur);} - .west{cursor: url(cursor/w-point.cur);} - .east{cursor: url(cursor/e-point.cur);} - .south{cursor: url(cursor/s-point.cur);} - .same{cursor: not-allowed;} - - .winround { - font-family: Tahoma; - font-size: 11px; - padding : 26px 0 23px 0; - } - - .winround .topLeft { - float: left; - background: url("images/window_lt.png") no-repeat top left; - width: 6px; - height: 27px; - margin: 0; - padding: 0; - border: 0; - margin-top : -26px; - _margin-right: -6px; /* IE6 bug fix */ - } - - .winroundFocus{ - - } - - .winround .topRight { - float: right; - background: url("images/window_rt.png") no-repeat top left; - width: 5px; - height: 27px; - margin: 0; - padding: 0; - border: 0; - margin-top : -26px; - _margin-left: -5px; /* IE6 bug fix */ - } - - .winround .title { - background: url("images/window_mt.png") repeat-x top left; - height: 21px; - color: #eeeeee; - position: relative; - margin: 0 5px 0 6px; - padding: 6px 0 0 20px; - border: 0; - font-weight: bold; - margin-top : -26px; - cursor : default; - } - - .winround .title img{ - margin: -1px 3px 0 -1px; - position : absolute; - left : 2px; - } - - .winround .content { - background : #f5f5f5; - margin-left: 1px; - margin-right: 1px; - position : relative; - height : 100%; - background-color:#f5f5f5; - background-image: none; - border: 0; - } - - .winroundMin .content{ - overflow : hidden; - } - - .winround .borderRight{ - background-image: none; - background-color: #b2b2b2; - overflow : hidden; - width : 1px; - float : right; - height : 100%; - _margin-left: -1px; /* IE6 bug fix */ - border: 0; - } - - .winround .borderLeft { - background-image: none; - background-color: #b2b2b2; - overflow: hidden; - height : 100%; - float : left; - width : 1px; - _margin-right: -1px; /* IE6 bug fix */ - border: 0; - } - - .winround .bottomLeft { - float: left; - background: url("images/window_lb_rounded.png") no-repeat top left; - width: 9px; - height: 9px; - margin: 0; - _margin-right: -9px; /* IE6 bug fix */ - overflow: hidden; - } - - .winround .bottomRight { - float: right; - background: url("images/window_rb_rounded.png") no-repeat top left; - width: 9px; - height: 9px; - margin: 0; - _margin-left: -9px; /* IE6 bug fix */ - overflow: hidden; - } - - .winround .bottomBar { - background-image: none; - background-color: #f5f5f5; - height: 8px; - color: #FFFFFF; - position: relative; - margin: 0 9px 0 9px; - border: 0; - border-bottom: 1px solid #b2b2b2; - overflow: hidden; - } - - .winround .bottom{ - position : absolute; - bottom : 0; - width : 100%; - } - - .cover{ - /*background: url(images/spacer.gif);*/ - background: white; - opacity: 0.3; - filter:progid:DXImageTransform.Microsoft.Alpha(opacity=30); - - position: absolute; - left: 0; - top: 0; - width: 100%; - height: 100%; - height: expression(document.documentElement.offsetHeight); - z-index: 10000; - } - - .winround .title blockquote{ - margin: 0; - width: 56px; - height: 21px; - position: absolute; - padding: 4px 4px 2px 2px; - top: 0; - right: 0; - background: url(images/title.gif) repeat-x; - } - - .winround .title blockquote div{ - width: 10px; - height: 9px; - float: right; - padding: 3px; - background: no-repeat 3px 3px; - cursor: default; - _overflow: hidden; /* IE6 bug fix */ - } - - .winround .title blockquote div.hover{ - border : 1px solid white; - padding : 2px; - background-position : 2px -10px; - height : 10px; - background-color : transparent; - } - .winround .title blockquote div.down{ - background-color : black; - } - - .winround .title .max{ - background-image: url(images/win_max.gif); - width: 11px; - } - .winroundMax .title .max{ - background-image: url(images/win_restore.gif); - } - .winround .title .min{ - background-image: url(images/win_min.gif); - } - .winroundMin .title .min{ - background-image: url(images/win_restore.gif); - } - .winround .title .close{ - width: 10px; - background-image: url(images/win_x.gif); - } - .winround .title span{ - width: 16px; - height: 16px; - display: block; - } - - #jpf_outline{ - - } - - #jpf_outline.drag{ - border: 1px solid black; - background: #CCC; - opacity: 0.4; - filter:progid:DXImageTransform.Microsoft.Alpha(opacity=40); - } - - #jpf_outline.resize{ - border: 3px solid black; - background: #CCC; - opacity: 0.3; - filter:progid:DXImageTransform.Microsoft.Alpha(opacity=30); - } - ]]></j:style> - <j:presentation> - <j:main collapsed-height="30" - min-width="150" min-height="80" - container="div[6]" drag="div[3]" title="div[3]/text()" - icon="div[3]/img" buttons="div[3]/blockquote"> - <div class="winround"> - <div class="topLeft"> </div> - <div class="topRight"> </div> - <div class="title"><img src="" />-<blockquote> </blockquote></div> - - <div class="borderLeft"> </div> - <div class="borderRight"> </div> - <div class="content"> </div> - - <div class="bottomLeft"> </div> - <div class="bottomRight"> </div> - <div class="bottomBar"> </div> - </div> - </j:main> - <j:button> - <div> </div> - </j:button> - <j:cover> - <div class='cover'> </div> - </j:cover> - </j:presentation> -</j:modalwindow> -<j:modalwindow name="bigedge"> - <j:style><![CDATA[ - .north{cursor: url(cursor/n-point.cur);} - .west{cursor: url(cursor/w-point.cur);} - .east{cursor: url(cursor/e-point.cur);} - .south{cursor: url(cursor/s-point.cur);} - .same{cursor: not-allowed;} - - .winbigedge { - font-family: Tahoma; - font-size: 11px; - padding : 26px 0 23px 0; - } - - .winbigedge .topLeft { - float: left; - background: url("images/window_lt.png") no-repeat top left; - width: 6px; - height: 27px; - margin: 0; - padding: 0; - border: 0; - margin-top : -26px; - _margin-right: -6px; /* IE6 bug fix */ - } - - .winbigedgeFocus{ - - } - - .winbigedge .topRight { - float: right; - background: url("images/window_rt.png") no-repeat top left; - width: 5px; - height: 27px; - margin: 0; - padding: 0; - border: 0; - margin-top : -26px; - _margin-left: -5px; /* IE6 bug fix */ - } - - .winbigedge .title { - background: url("images/window_mt.png") repeat-x top left; - height: 21px; - color: #eeeeee; - position: relative; - margin: 0 5px 0 6px; - padding: 6px 0 0 20px; - border: 0; - font-weight: bold; - margin-top : -26px; - cursor : default; - } - - .winbigedge .title img{ - margin: -1px 3px 0 -1px; - position : absolute; - left : 2px; - } - - .winbigedge .content { - background : #f5f5f5; - margin-left: 3px; - margin-right: 3px; - position : relative; - height : 100%; - background:#f5f5f5 url(images/page_bt.png) repeat-x top left; - } - - .winbigedgeMin .content{ - overflow : hidden; - } - - .winbigedge .borderRight{ - background: url("images/window_border.png") repeat-y top right; - overflow : hidden; - width : 3px; - float : right; - height : 100%; - _margin-left: -3px; /* IE6 bug fix */ - } - - .winbigedge .borderLeft { - background: url("images/window_border.png") repeat-y top left; - overflow: hidden; - height : 100%; - float : left; - width : 3px; - _margin-right: -3px; /* IE6 bug fix */ - } - - .winbigedge .bottomLeft { - float: left; - background: url("images/window_lb.png") no-repeat top left; - width: 6px; - height: 22px; - _margin-right: -6px; /* IE6 bug fix */ - } - - .winbigedge .bottomRight { - float: right; - background: url("images/window_rb.png") no-repeat top left; - width: 5px; - height: 22px; - _margin-left: -5px; /* IE6 bug fix */ - } - - .winbigedge .bottomBar { - background: url("images/window_mb.png") repeat-x top left; - height: 22px; - color: #FFFFFF; - position: relative; - margin: 0 5px 0 6px; - } - - .winbigedge .bottom{ - position : absolute; - bottom : 0; - width : 100%; - } - - .cover{ - /*background: url(images/spacer.gif);*/ - background: white; - opacity: 0.3; - filter:progid:DXImageTransform.Microsoft.Alpha(opacity=30); - - position: absolute; - left: 0; - top: 0; - width: 100%; - height: 100%; - height: expression(document.documentElement.offsetHeight); - z-index: 10000; - } - - .winbigedge .title blockquote{ - margin: 0; - width: 56px; - height: 21px; - position: absolute; - padding: 4px 4px 2px 2px; - top: 0; - right: 0; - background: url(images/title.gif) repeat-x; - } - - .winbigedge .title blockquote div{ - width: 10px; - height: 9px; - float: right; - padding: 3px; - background: no-repeat 3px 3px; - cursor: default; - _overflow: hidden; /* IE6 bug fix */ - } - - .winbigedge .title blockquote div.hover{ - border : 1px solid white; - padding : 2px; - background-position : 2px -10px; - height : 10px; - background-color : transparent; - } - .winbigedge .title blockquote div.down{ - background-color : black; - } - - .winbigedge .title .max{ - background-image: url(images/win_max.gif); - } - .winbigedgeMax .title .max{ - background-image: url(images/win_restore.gif); - } - .winbigedge .title .min{ - background-image: url(images/win_min.gif); - } - .winbigedgeMin .title .min{ - background-image: url(images/win_restore.gif); - } - .winbigedge .title .close{ - width: 11px; - background-image: url(images/win_x.gif); - } - .winbigedge .title span{ - width: 16px; - height: 16px; - display: block; - } - - #jpf_outline{ - - } - - #jpf_outline.drag{ - border: 1px solid black; - background: #CCC; - opacity: 0.4; - filter:progid:DXImageTransform.Microsoft.Alpha(opacity=40); - } - - #jpf_outline.resize{ - border: 3px solid black; - background: #CCC; - opacity: 0.3; - filter:progid:DXImageTransform.Microsoft.Alpha(opacity=30); - } - ]]></j:style> - - <j:presentation> - <j:main collapsed-height="30" - min-width="150" min-height="80" - container="div[6]" drag="div[3]" title="div[3]/text()" - icon="div[3]/img" buttons="div[3]/blockquote"> - <div class="winbigedge"> - <div class="topLeft"> </div> - <div class="topRight"> </div> - <div class="title"><img src="" />-<blockquote> </blockquote></div> - - <div class="borderLeft"> </div> - <div class="borderRight"> </div> - <div class="content"> </div> - - <div class="bottomLeft"> </div> - <div class="bottomRight"> </div> - <div class="bottomBar"> </div> - </div> - </j:main> - <j:button> - <div> </div> - </j:button> - <j:cover> - <div class='cover'> </div> - </j:cover> - </j:presentation> -</j:modalwindow> -<!-- - * Please optimize this one removing elements where possible (using border and such) - it is already optimized ---> -<j:modalwindow name="alert"> - <j:style><![CDATA[ - .alert{ - font-family: Tahoma; - font-size: 11px; - padding : 27px 0 10px 0; - text-align : left; - } - - .alert .topLeft{ - background: url("images/error_box_lt.png") no-repeat top left; - width: 8px; - height: 27px; - float:left; - margin: -27px 0 0 0; - _margin: -27px -8px 0 0; /* IE6 bug fix */ - padding: 0; - border: 0; - } - .alert .topRight{ - background: url("images/error_box_rt.png") no-repeat top left; - width: 14px; - height: 27px; - float: right; - margin: -27px 0 0 0; - _margin: -27px 0 0 -14px; - padding: 0; - border: 0; - } - - .alert .title{ - border-top:1px solid #c3c3c3; - height: 18px; - margin: -27px 14px 0 8px; - padding : 8px 0 0 3px; - - font-weight: bold; - color : #0e9717; - cursor : default; - background : white; - } - - .error .title{ - color: #327fbd; - } - - .alert .content{ - border-left: 1px solid #c3c3c3; - padding: 0 0 0 10px; - margin : 0 9px 0 0; - /*overflow: hidden;*/ - height : 100%; - position : relative; - background : white; - } - - .alert .borderRight{ - background: url("images/error_box_r.png") repeat-y top right; - overflow: hidden; - height : 100%; - float : right; - width : 9px; - } - - .selectSupplier .borderRight{ - bottom:26px; - position:absolute; - right:0; - top:27px; - z-index:1; - height: auto; - } - .alert .bottomLeft{ - background: url("images/error_box_lb.png") no-repeat top left; - width: 8px; - height: 16px; - float: left; - margin: 0; - _margin: 0 -8px 0 0; /* IE6 bug fix */ - padding: 0; - border: 0; - } - - .alert .bottomRight{ - background: url("images/error_box_rb.png") no-repeat top right; - width: 14px; - height: 16px; - float: right; - margin: 0; - _margin: 0 0 0 -14px; /* IE6 bug fix */ - padding: 0; - border: 0; - } - - .alert .bottomBar{ - background: url("images/error_box_b.png") repeat-x bottom left; - height: 16px; - margin: 0 14px 0 8px; - padding: 0; - border: 0; - } - - .alert .close{ - width: 13px; - height: 13px; - background: url("images/close.png") no-repeat top left; - margin : -2px 1px 0 0; - overflow: hidden; - position : absolute; - right : 14px; - top : 9px; - } - - .alert .title .hover{ - background-position : 0 -13px; - } - ]]></j:style> - - <j:presentation> - <!-- min-width="50" min-height="50" --> - <j:main collapsed-height="30" - container="div[5]" drag="div[3]" title="div[3]/text()" - buttons="div[3]"> - <div class="alert"> - <div class="topLeft"> </div> - <div class="topRight"> </div> - <div class="title">-</div> - - <div class="borderRight"> </div> - <div class="content"> - </div> - - <div class="bottomLeft"> </div> - <div class="bottomRight"> </div> - <div class="bottomBar"> </div> - - </div> - </j:main> - <j:button> - <div> </div> - </j:button> - <j:cover> - <div class='cover'> </div> - </j:cover> - </j:presentation> -</j:modalwindow> -<j:bar name="bardown"> - <j:style><![CDATA[ - .bardown{ - font-family: Tahoma; - font-size: 11px; - padding : 0 0 10px 0; - text-align : left; - z-index: 1; - } - - .bardown .content{ - border-left: 1px solid #c3c3c3; - padding: 3px 5px 0 5px; - height : 100%; - position : relative; - background : white; - overflow: visible; - margin : 0 8px 0 0; - } - - .hidden .content, .noscrollbar .content{ - overflow: hidden; - } - - .bardown .borderRight{ - background: url("images/error_box_r.png") repeat-y top right; - overflow: hidden; - height : 100%; - float : right; - width : 9px; - padding-top : 3px; - } - - .bardown .bottomLeft{ - background: url("images/error_box_lb.png") no-repeat top left; - width: 8px; - height: 16px; - float: left; - margin: 0; - _margin: 0 -8px 0 0; /* IE6 bug fix */ - padding: 0; - border: 0; - } - - .bardown .bottomRight{ - background: url("images/error_box_rb.png") no-repeat top right; - width: 14px; - height: 16px; - float: right; - margin: 0; - _margin: 0 0 0 -14px; /* IE6 bug fix */ - padding: 0; - border: 0; - } - - .bardown .bottomBar{ - background: url("images/error_box_b.png") repeat-x bottom left; - height: 16px; - margin: 0 14px 0 8px; - padding: 0; - border: 0; - } - - .bardown .close{ - width: 13px; - height: 13px; - background: url("images/close.png") no-repeat top left; - margin : -2px 1px 0 0; - overflow: hidden; - position : absolute; - right : 14px; - top : 9px; - } - - .bardown .title .hover{ - background-position : 0 -13px; - } - ]]></j:style> - - <j:presentation> - <!-- min-width="50" min-height="50" --> - <j:main collapsed-height="30" container="div[2]"> - <div class="bardown"> - <div class="borderRight"> </div> - <div class="content"> - </div> - - <div class="bottomLeft"> </div> - <div class="bottomRight"> </div> - <div class="bottomBar"> </div> - - </div> - </j:main> - <j:button> - <div> </div> - </j:button> - <j:cover> - <div class='cover'> </div> - </j:cover> - </j:presentation> -</j:bar> -<j:bar name="searchbar"> - <j:style><![CDATA[ - .searchbar{ - font-family: Tahoma; - font-size: 11px; - padding : 0 0 10px 0; - text-align : left; - z-index: 200; - } - - .hidden .content{ - overflow: hidden; - } - - .searchbar .content{ - border-left: 1px solid #c3c3c3; - height : 100%; - position : relative; - overflow: hidden; - } - - .searchbar .borderRight{ - background: url("images/error_box_r.png") repeat-y top right; - border-top: 1px solid #C3C3C3; - overflow: hidden; - height : 100%; - width : 8px; - padding-top : 3px; - position: absolute; - top: 0; - right: 0; - z-index: 1; - } - .searchbar .footer{ - overflow: auto; - clear: both - } - .searchbar .bottomLeft{ - background: url("images/error_box_lb.png") no-repeat top left; - width: 8px; - height: 16px; - float: left; - margin: 0; - _margin: 0 -8px 0 0; /* IE6 bug fix */ - padding: 0; - border: 0; - } - - .searchbar .bottomRight{ - background: url("images/error_box_rb.png") no-repeat top right; - width: 14px; - height: 16px; - float: right; - margin: 0; - _margin: 0 0 0 -14px; /* IE6 bug fix */ - padding: 0; - border: 0; - } - - .searchbar .bottomBar{ - background: url("images/error_box_b.png") repeat-x bottom left; - height: 16px; - margin: 0 14px 0 8px; - padding: 0; - border: 0; - } - - .searchbar .close{ - width: 13px; - height: 13px; - background: url("images/close.png") no-repeat top left; - margin : -2px 1px 0 0; - overflow: hidden; - position : absolute; - right : 14px; - top : 9px; - } - - .searchbar .title .hover{ - background-position : 0 -13px; - } - ]]></j:style> - - <j:presentation> - <!-- min-width="50" min-height="50" --> - <j:main collapsed-height="30" container="div[1]"> - <div class="searchbar"> - <div class="content"> - <div class="borderRight"> </div> - </div> - - <div class="footer"> - <div class="bottomLeft"> </div> - <div class="bottomRight"> </div> - <div class="bottomBar"> </div> - </div> - - </div> - </j:main> - <j:button> - <div> </div> - </j:button> - <j:cover> - <div class='cover'> </div> - </j:cover> - </j:presentation> -</j:bar> -<j:button name="button"> - <j:alias>submit</j:alias> - <j:alias>reset</j:alias> - <j:style><![CDATA[ - .jpf_btn{ - color: #4b4b4b; - font-family: Tahoma; - font-size: 8pt; - height: 25px; - width : 100px; - overflow: hidden; - cursor : default; -/* margin : 0 -5px -2px 0; */ - } - - .jpf_btn .left{ - float: left; - width: 8px; - height: 25px; - _margin-right: -3px; /* IE6 bug fix */ - } - - .jpf_btn .lbl{ - height: 20px; - padding-top: 5px; - text-align: center; -/* margin : 0 9px 0 8px; */ - margin: 0; - _margin: 0; /* IE6 fix */ - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - } - - .jpf_btn .right{ - float: right; - width: 9px; - height: 25px; - _margin-left: -3px; /* IE6 bug fix */ - } - - .jpf_btn .left{ - background: url("images/button_left.png") no-repeat 0 -25px; - } - - .jpf_btn .lbl{ - background: url("images/button_middle.png") repeat-x 0 -25px; - } - - .jpf_btn .right{ - background: url("images/button_right.png") no-repeat 0 -25px; - } - - .jpf_btnDefault .left { - background: url("images/button_left.png") no-repeat top left; - } - - .jpf_btnDefault .lbl { - background: url("images/button_middle.png") repeat-x top left; - } - - .jpf_btnDefault .right { - background: url("images/button_right.png") no-repeat top left; - } - - .jpf_btn span{ - padding : 1px 3px 1px 3px; - border: 1px solid transparent; - position : relative; - _border: 0; - _padding: 2px 4px 2px 4px; - _margin: 0; - } - - .jpf_btnDisabled { - color: #bebebe; - } - - .jpf_btnDisabled .left { - background: url("images/button_left.png") no-repeat 0 -50px; - } - - .jpf_btnDisabled .lbl { - background: url("images/button_middle.png") repeat-x 0 -50px; - } - - .jpf_btnDisabled .right { - background: url("images/button_right.png") no-repeat 0 -50px; - } - .jpf_btnFocus { - } - - .jpf_btnFocus span{ - border: 1px dotted #BBB; - padding : 1px 3px 1px 3px; - } - - .jpf_btnDown .left { - background: url("images/button_left.png") no-repeat 0 -75px; - } - - .jpf_btnDown .lbl { - background: url("images/button_middle.png") repeat-x 0 -75px; - } - - .jpf_btnDown .right { - background: url("images/button_right.png") no-repeat 0 -75px; - } - - .jpf_btnOver { - } - ]]></j:style> - <j:style condition="jpf.isIE7"> - .jpf_btn .right { - margin: 0; - } - - .jpf_btn .left { - margin: 0; - } - </j:style> - - <j:presentation> - <j:main caption="div[3]/span/text()" background="."> - <div class="jpf_btn"> - <div class="left"> </div> - <div class="right"> </div> - <div class="lbl"><span>-</span></div> - </div> - </j:main> - </j:presentation> -</j:button> -<j:label name="label"> - <j:style><![CDATA[ - .label{ - font-size: 8pt; - font-family: Tahoma; - overflow: hidden; - cursor: default; - line-height : 1.5em; - } - - .labelDisabled{ - color: #bebebe; - } - - .tiny { - font-size : 9px; - } - - .error .label{ - background : url(images/alert.png) no-repeat 0 0; - min-height : 37px; - padding : 3px 0 0 45px; - } - ]]></j:style> - - <j:presentation> - <j:main caption="." for="@for"> - <div class="label"> </div> - </j:main> - </j:presentation> -</j:label> -<!-- - * Textbox isn't scalable - done ---> -<j:textbox name="textbox"> - <j:alias>input</j:alias> - <j:style><![CDATA[ - .tb { - background: white url("images/textarea_background2.png") no-repeat 0 0; - /*background-attachment: fixed !important; background-attachment: scroll; */ - width: 161px; - height: 15px; - color: #4b4b4b; - border: 1px solid #c3c3c3; - margin: 0; - padding: 2px 0 0 2px; - outline: none; - font-family: Tahoma; - font-size: 11px; - text-overflow: ellipsis; - } - - .tbFocus { - border: 1px solid #327fbd; - } - - .tbDisabled { - border: 1px solid #c3c3c3; - color: #bebebe; - } - - .tbError { - border: 2px solid #ffb500; - margin : -1px 0 0 -1px; - } - - .tbInitial{ - color : gray; - } - - .tbautoc{ - border: 1px solid gray; - width: 250px; - overflow-y: auto; - z-index: 10000000; - - position: absolute; - background-color: white; - margin: 23px 0 0 0; - left: 136px; - - white-space: nowrap; - display: none; - } - - .tbautoc div{ - padding: 1px 5px 1px 3px; - cursor: default; - margin: 0px; - color: black; - font-family: Arial; - font-size: 9pt; - } - - .tbautoc div.hover{ - background-color: #0B2B7A; - color: white; - } - ]]></j:style> - - <j:presentation> - <j:main input="."> - <input type='text' class="tb" /> - </j:main> - <j:container> - <div class="tbautoc"> </div> - </j:container> - <j:item caption="."> - <div>-</div> - </j:item> - </j:presentation> -</j:textbox> -<!-- - * Textarea doesn't scroll well -done - * Textarea doesn't have a Focus state, should be similar to the textbox - done ---> -<j:textbox name="textarea"> - <j:style><![CDATA[ - .ta{ - border: 1px solid #c3c3c3; - background: white url("images/textarea_background2.png") no-repeat top left; - /*background-attachment: fixed !important; background-attachment: scroll; */ - color: #4b4b4b; - padding: 6px; - font-family: Tahoma; - font-size: 8pt; - overflow: auto; - outline: none; - resize: none; - } - - .taFocus{ - border-color : #327fbd; - } - - .taDisabled{ - border: 1px solid #c3c3c3; - color: #bebebe; - } - - .taInitial{ - color : gray; - } - - .taError{ - border: 2px solid #ffb500; - padding : 5px; - } - ]]></j:style> - - <j:presentation> - <j:main input="."> - <textarea type='text' class="ta" /> - </j:main> - </j:presentation> -</j:textbox> -<!-- - * Strange discoloring at left line of button - pb solved ---> -<j:tab name="tab"> - <j:style><![CDATA[ - .tab { - color: #4b4b4b; - font-family : Tahoma; - font-size : 8pt; - padding : 23px 0 26px 0; - } - - .tab .btncontainer{ - padding-left: 0; - margin-top : -19px; - position : absolute; - z-index : 100; - } - - .tab .btncontainer div { - cursor: default; - display: block; - float: left; - margin: 0 3px 0 0; - padding: 0; - } - - .tab .btncontainer div { - background: url(images/tab_but_topleft.png) no-repeat 0 0; - height: 20px; - } - - .tab .btncontainer div.curbtn { - _position: relative; - margin-top: -4px; - margin-bottom: -1px; - background-position: 0 -19px; - height: 24px; - color: #327fbd; - } - - .tabFocus .curbtn{ - } - - .tabFocus .curbtn span{ - border: 1px dotted gray; - padding: 0px 3px 2px 3px; - margin : -1px -4px 0 -4px; - display: block; - } - - .tab .btncontainer div div { - height: 16px; - margin: 0 -4px 0 0; - padding : 4px 8px 0 8px; - } - - .tab .btncontainer div div { - background: url(images/tab_but_topright.png) no-repeat right 0; - } - - .tab .btncontainer div.curbtn div { - background-position: right -19px; - height: 24px; - padding-top: 5px; - } - - .tab .page { - clear: both; - border-top: 1px solid #d7d7df; - border-left: 1px solid #c3c3c3; - border-right: 1px solid #c3c3c3; - background: #fafbfc; - padding: 7px; - overflow: hidden; - display : none; - height : 100%; - position : relative; - } - - .tab .page.curpage{ - display : block; - } - - .tab .tabFooter{ - clear: both; - height: 15px; - background: url(images/tab_pag_lb.png) no-repeat bottom left; - position : absolute; - bottom : 0; - width : 100%; - } - - .tab .tabFooter div{ - background: url(images/tab_pag_rb.png) no-repeat bottom right; - } - - .tab .tabFooter div div{ - border-bottom: 1px solid #c3c3c3; - background-color: #fafbfc; - background-image: none; - height: 14px; - margin: 0 14px; - } - ]]></j:style> - <j:style condition="jpf.isIE6"> - .tab .btncontainer div, .tab .btncontainer div div { - margin: 0 0 0 0; - } - .tab .tabFooter { - bottom: 11px; - } - </j:style> - <j:presentation> - <j:main pages="." buttons="div"> - <div class="tab"> - <div class="btncontainer"> - - </div> - - <div class="tabFooter"><div><div> </div></div></div> - </div> - </j:main> - <j:button caption="div/span/text()"> - <div class="btn"><div><span>-</span></div></div> - </j:button> - <j:page container="."> - <div class="page"> </div> - </j:page> - </j:presentation> -</j:tab> -<!-- - * Missing down state when selected - done ---> -<j:checkbox name="checkbox"> - <j:style><![CDATA[ - .cbcontainer{ - padding: 2px 2px 2px 18px; - _padding: 2px; /* IE6 fix */ - position: relative; - min-height: 13px; - color: #4b4b4b; - background: url(images/spacer.gif); - _clear: both; /* IE6 fix */ - } - - .cbcontainer span{ - font-family: Tahoma; - font-size: 11px; - cursor: default; - padding: 1px 3px 2px 3px; - margin : -1px 0 0 0; - overflow: hidden; - display: block; - float: left; - line-height: 13px; - } - - .cbcontainerFocus span{ - padding: 0px 2px 1px 2px; - border: 1px dotted #BBB; - } - - .cbcontainerChecked.cbcontainerDown.cbcontainerFocus .checkbox { - background-position: 0 -48px; - } - - .cbcontainer .checkbox{ - width: 12px; - height: 12px; - overflow: hidden; - position: absolute; - left: 2px; - top: 2px; - _position: relative; /* IE6 fix */ - _float: left; /* IE6 fix */ - _margin: -2px 4px 0 0; /* IE6 fix */ - background: url("images/checkbox.png") no-repeat 0 -12px; - } - - .cbcontainerDown .checkbox{ - background-position: 0 -36px; - } - - .cbcontainerChecked .checkbox{ - background-position: 0 -24px; - } - - .cbcontainerError span{ - background-color : #ffb500; - color: #fbfbfb; - } - - .cbcontainerDisabled .checkbox{ - background-position: 0 -0px; - } - - .cbcontainerDisabled span{ - color: #bebebe; - } - - .cbcontainer br{ - display: none; - } - ]]></j:style> - <j:style condition="!jpf.isIE"><![CDATA[ - .cbcontainer br{ - line-height: 0; - display: block; - } - ]]></j:style> - - <j:presentation> - <j:main label="span/text()"> - <div class='cbcontainer'> - <div class='checkbox'> </div> - <span>-</span> - <br clear="left" /> - </div> - </j:main> - </j:presentation> -</j:checkbox> -<j:radiobutton name="radiobutton"> - <j:style><![CDATA[ - .rbcontainer { - padding: 2px 2px 2px 2px; - _padding: 2px 2px 2px 0; /* IE6 fix */ - position: relative; - min-height: 13px; - color: #4b4b4b; - cursor : default; - _clear: both; /* IE6 fix */ - } - - .rbcontainer span{ - font-family: Tahoma; - font-size: 11px; - padding: 1px 3px 2px 3px; - margin : -1px 0 0 0; - overflow: hidden; - display: block; - float: left; - line-height: 13px; - } - - .rbcontainerFocus span{ - padding: 0 2px 1px 2px; - border: 1px dotted #BBB; - } - - .rbcontainer .radio{ - width: 12px; - height: 12px; - overflow: hidden; - podition: relative; - float: left; - margin: 1px 2px 0 0; - _padding: 0; - background: url("images/radio.png") no-repeat 0 -12px; - } - - .rbcontainerDown .radio{ - background-position: 0 -36px; - } - - .rbcontainerChecked .radio{ - background-position: 0 -24px; - } - - .rbcontainerDisabled .radio{ - background-position: 0 -0px; - } - - .rbcontainerDisabled span{ - color: #bebebe; - } - - .rbcontainerError span{ - background-color : #ffb500; - color: #fbfbfb; - } - - .rbcontainer br{ - display: none; - } - ]]></j:style> - - <j:presentation> - <j:main label="span"> - <div class="rbcontainer"> - <div class="radio"> </div> - <span>-</span> - </div> - </j:main> - </j:presentation> -</j:radiobutton> -<j:radiobutton name="toolbarradio"> - <j:style><![CDATA[ - .toolbar .subbar .tbradio { - display: block; - height: 22px; - float: left; - cursor: default; - margin: 2px 1px 0 1px; - text-decoration: none; - color: #000000; - text-align: center; - padding: 0 4px 0 0; - line-height: 13px; - } - - .toolbar .subbar .tbradio div { - float: left; - margin: 0; - height: 17px; - padding: 4px 0 0 7px; - border: 0; - } - - .toolbar .subbar .tbradioOver { - background: url("images/toolbar_a_hover_right.png") no-repeat top right; - } - - .toolbar .subbar .tbradioOver div { - background: url("images/toolbar_a_hover.png") no-repeat top left; - } - - .toolbar .subbar .tbradioDown, .toolbar .subbar .tbradioChecked{ - background: url("images/toolbar_a_down_right.png") no-repeat top right; - } - - .toolbar .subbar .tbradioDown div, .toolbar .subbar .tbradioChecked div { - background: url("images/toolbar_a_down.png") no-repeat top left; - } - - .toolbar .subbar .tbradioDisabled, .toolbar .subbar .tbradioDisabled div { - background: none; - color: #bebebe; - } - - .toolbar .subbar .tbradio span{ - display: block; - float:left; - width: 16px; - height: 16px; - margin: -1px 3px 0 0; - } - - ]]></j:style> - - <j:presentation> - <j:main background="div/span" icon="div/span"> - <div class='tbradio'><div><span> </span></div></div> - </j:main> - </j:presentation> -</j:radiobutton> -<!-- - * This menu needs shadow as in the design - done, except IE6 ---> -<j:menu name="menu"> - <j:style><![CDATA[ - .menu { - background: #FFFFFF url("images/menu_context_left.gif") repeat-y top left; - margin: -1px 0 0 0; - _margin: 0 0 0 0; - padding: 0; - z-index: 10000; - position: absolute; - font-family: Tahoma; - font-size: 11px; - color : #4b4b4b; - border : 1px solid #c3c3c3; - display : none; - } - - .menu blockquote { - list-style-type: none; - margin: 0; - padding: 0; - border: 0; - background: url("images/menu_context_right.gif") repeat-y top right; - } - - .menu div{ - padding: 4px 31px 4px 23px; - white-space: nowrap; - cursor : default; - } - .menu>div{ - height: 13px; - } - .menu div.hover{ - background: #25a8e7 url(images/menu_context_left_over.gif) repeat-y top left; - color : white; - } - - .menu div.menu_divider{ - border-style: solid; - border-width: 1px 0 0 0; - border-color: #c3c3c3; - overflow: visible; - margin: 1px 3px 1px 3px; - padding: 0; - font-size: 1px; - } - - .menu>div.menu_divider{ - height: 0; - } - - .menu div span{ - right: 5px; - margin-top: 0px; - z-index: 10; - text-align: right; - padding-left: 15px; - margin-right: -15px; - } - - .menu div.submenu span{ - background: url(images/submenu_arrow.gif) no-repeat right top; - width: 4px; - height: 7px; - display: block; - position: absolute; - right: 8px; - margin: 3px 0 0 0; - z-index: 10; - } - - .menu div.hover span{ - background-position : right -15px; - } - - .menu div.submenu>span{ - margin-top: -10px; - } - - .menu div.disabled{ - color: gray; - } - - .menu u{ - width: 16px; - height: 16px; - position: absolute; - left: 3px; - margin-top : -1px; - } - - .menu div.selected u{ - background-image: url(images/radio.gif); - background-repeat: no-repeat; - background-position: 0 0; - } - - .menu div.checked u{ - background-image: url(images/check.gif); - background-repeat: no-repeat; - background-position: 0 0; - } - - .menu div.hover u{ - background-position : 0 -16px; - } - - .menu div.menuShadowTop { - position: absolute; - left: 0; - top: -2px; - margin: 0; - padding: 0 4px 0 0; - width: 100%; - height: 2px; - overflow: hidden; - z-index: -10; - background: url("images/menu_context_shtb.png") no-repeat top right; - } - - .menu div.menuShadowRight { - position: absolute; - right: -4px; - bottom: -4px; - margin: 0; - padding: 0 0 4px 0; - width: 4px; - height: 100%; - overflow: hidden; - z-index: -10; - background: url("images/menu_context_shlr.png") no-repeat bottom right; - } - - .menu div.menuShadowBottom { - position: absolute; - bottom: -4px; - right: 0; - margin: 0; - padding: 0 0 0 3px; - width: 100%; - height: 4px; - overflow: hidden; - z-index: -10; - background: url("images/menu_context_shtb.png") no-repeat bottom left; - } - - .menu div.menuShadowLeft { - position: absolute; - left: -3px; - bottom: 0; - margin: 0; - padding: 2px 0 0 0; - width: 3px; - height: 100%; - overflow: hidden; - z-index: -10; - background: url("images/menu_context_shlr.png") no-repeat top left; - } - - ]]></j:style> - <j:style condition="jpf.isIE6"> - .menu div.menuShadowTop, .menu div.menuShadowRight, .menu div.menuShadowLeft, .menu div.menuShadowBottom { - display: none; - } - </j:style> - <j:presentation> - <j:main container="blockquote" overlay="strong"> - <blockquote class='menu'> - <blockquote> - - </blockquote> - <div class="menuShadowTop"> </div> - <div class="menuShadowRight"> </div> - <div class="menuShadowBottom"> </div> - <div class="menuShadowLeft"> </div> - </blockquote> - </j:main> - <j:item caption="text()" icon="u" hotkey="span"> - <div><u> </u>-<span> </span></div> - </j:item> - <j:divider> - <div class='menu_divider'></div> - </j:divider> - </j:presentation> -</j:menu> -<j:toolbar name="toolbar"> - <j:style><![CDATA[ - .toolbar .menubar { - background: url(images/menubar_row.png) repeat-x top left; - height: 21px; - font-family: Verdana; - font-size: 11px; - border-bottom: 1px solid #c3c3c3; - position: relative; - } - - .toolbar .subbar { - background: url(images/toolbar_row.png) repeat-x top left; - height: 25px; - font-family: Verdana; - font-size: 11px; - border-bottom: 1px solid #c3c3c3; - position: relative; - padding: 0; - width : 100%; - } - - .toolbar .divider { - border-left: 1px solid #c3c3c3; - border-right: 1px solid #FFFFFF; - height: 17px; - float: left; - margin: 4px 0 0 0; - } - ]]></j:style> - - <j:presentation> - <j:main container="." button-skin="toolbarbutton"> - <div class="toolbar"> </div> - </j:main> - <j:bar container="."> - <div class="subbar"> </div> - </j:bar> - <j:divider> - <div class='divider'> </div> - </j:divider> - </j:presentation> -</j:toolbar> - -<!-- - * These buttons don't scale, please make them scalable. - * Please implement the missing classes: - .toolbarbuttonIcon - done - .toolbarbuttonDisabled - done - .toolbarbuttonDown - done ---> -<j:button name="toolbarbutton"> - <j:style><![CDATA[ - .menubar .toolbarbutton { - display: block; - height: 18px; - float: left; - cursor: default; - padding: 4px 8px 0 8px; - line-height: 13px; - text-decoration: none; - color: #000000; - } - - .menubar .toolbarbuttonOver, .menubar .toolbarbuttonDown { - background : #45b3e8 url(images/menu_over.gif); - color : #ffffff; - } - - .menubar .toolbarbuttonDown, .menubar .toolbarbuttonDown { - background : #45b3e8 url(images/menu_down.gif); - color : #ffffff; - } - - .menubar .toolbarbuttonDisabled, .menubar .toolbarbuttonDisabled { - background : none; - color : #bebebe; - } - - .toolbar .subbar .toolbarbutton { - display: block; - height: 22px; - float: left; - cursor: default; - margin: 2px 1px 0 1px; - text-decoration: none; - color: #000000; - text-align: center; - padding: 0 4px 0 0; - line-height: 13px; - } - - .toolbar .subbar .toolbarbutton div { - float: left; - margin: 0; - height: 17px; - padding: 4px 4px 0 8px; - border: 0; - } - - .toolbar .subbar .toolbarbuttonOver { - background: url("images/toolbar_a_hover_right.png") no-repeat top right; - } - - .toolbar .subbar .toolbarbuttonOver div { - background: url("images/toolbar_a_hover.png") no-repeat top left; - } - - .toolbar .subbar .toolbarbuttonDown { - background: url("images/toolbar_a_down_right.png") no-repeat top right; - } - - .toolbar .subbar .toolbarbuttonDown div { - background: url("images/toolbar_a_down.png") no-repeat top left; - } - - .toolbar .subbar .toolbarbuttonDisabled, .toolbar .subbar .toolbarbuttonDisabled div { - background: none; - color: #bebebe; - } - - .toolbar .subbar .toolbarbuttonIcon div{ - padding-left : 4px; - } - - .toolbar .subbar .toolbarbuttonEmpty div{ - padding: 4px 0 0 7px; - } - - .toolbar .subbar .toolbarbuttonIcon span{ - display: block; - float:left; - width: 16px; - height: 16px; - margin: -2px 4px 0 0; - } - - .toolbar .subbar .toolbarbuttonEmpty span{ - margin: -1px 3px 0 0; - } - ]]></j:style> - - <j:presentation> - <j:main caption="div/text()" background="div/span" icon="div/span"> - <div class='toolbarbutton'><div><span> </span>-</div></div> - </j:main> - </j:presentation> -</j:button> -<j:list name="list"> - <j:style><![CDATA[ - .list{ - overflow: auto; - position: relative; - border: 1px solid #c3c3c3; - background-color: #fafbfc; - cursor: default; - } - - .white{ - background : white; - } - - .list, .draglist{ - font-family: Tahoma; - font-size: 8pt; - } - - .list DIV, .draglist{ - padding: 0; - height: 18px; - } - - .list SPAN, .draglist SPAN{ - padding: 0 0 0 20px; - background: no-repeat 1px center; - height: 16px; - float: left; - } - - .list U, .draglist U{ - text-decoration: none; - color: black; - cursor: default; - display: block; - padding: 2px 4px 2px 2px; - text-decoration: none; - white-space: nowrap; - } - - .listFocus .indicate U{ - border: 1px dotted #BBB;/*#25a8e7;*/ - color : black; - /*background-color : #e4f4fc;*/ - padding: 1px 3px 1px 1px; - } - - .list .selected U{ - background-color: #f0f0f0; - color: black; - } - .listFocus .selected U, .draglist U{ - color: white; - background-color: #25a8e7; - } - - .list #txt_rename{ - border: 1px solid #bbb; - padding: 1px 15px 1px 1px; - font-family: Tahoma; - font-size: 8pt; - color: black; - word-break: keep-all; - overflow: visible; - margin-top : 0px; - cursor: text; - height: 13px; - display: block; - outline : none; - } - - .list .empty, .list .offline, .list .loading{ - text-align: center; - padding: 8px 0 0 5px; - color: #AAA; - font-weight : normal; - } - - .shortlist{ - border : 0; - overflow-y : auto; - overflow-x : hidden; - max-height : 90px; - width : auto; - } - ]]></j:style> - - <j:presentation> - <j:main container="."> - <div class='list'> - </div> - </j:main> - <j:item - class = "." - caption = "span/u" - icon = "span" - select = "span" - > - <div><span><u>-</u></span></div> - </j:item> - <j:dragindicator> - <div class='draglist'><span><u>-</u></span></div> - </j:dragindicator> - <j:loading> - <div class="loading">Loading...</div> - </j:loading> - <j:empty caption="."> - <div class="message">-</div> - </j:empty> - </j:presentation> -</j:list> -<j:list name="thumbnail"> - <j:style><![CDATA[ - .thumbs{ - background-color: white; - border: 1px solid #c3c3c3; - overflow: auto; - cursor: default; - padding : 3px; - height : 200px; - position : relative; - } - - .dragthumb{ - opacity : 0.7; - filter:progid:DXImageTransform.Microsoft.Alpha(opacity=70); - } - - .thumbs, .dragthumb{ - font-family: Tahoma; - font-size: 11px; - text-align: center; - line-height : 11px; - } - - .thumbs .thumb, .dragthumb{ - padding: 0; - float: left; - display: inline; - margin: 5px 5px 2px 5px; - padding: 0 0 1px 0; - border: 1px solid #dcdcdc; - } - - .thumbs blockquote, .dragthumb blockquote{ - width: 90px; - height: 90px; - margin : 1px; - border : 1px solid white; - - background: white no-repeat 50% 50%; - float : left; - } - - .thumbs .primary blockquote{ - border : 1px solid gray; - margin : 1px; - } - - .thumbs .selected, .dragthumb{ - border: 3px solid #dcdcdc; - margin : 3px 3px 0 3px; - } - .thumbs.thumbsFocus .selected, .dragthumb{ - border-color: #25a8e7; - } - - .thumbs label, .dragthumb label{ - padding: 3px 0 0 0; - margin: 0 2px 0 2px; - height: 16px; - width: 92px; - - overflow: hidden; - display: block; - text-align: center; - } - - .thumbs span, .dragthumb span{ - text-decoration: none; - color: black; - cursor: default; - padding: 1px 3px 2px 3px; - margin: 1px auto 0 auto; - white-space: nowrap; - /*float : left;*/ - position : relative; - border-color : gray; - border-width : 0; - } - - .thumbsFocus .indicate span{ - border-style : dotted; - border-width : 1px; - padding: 0px 2px 1px 2px; - } - - .thumbs .selected span{ - background-color: #dcdcdc; - color: black; - border-color : white; - border-style : dotted; - } - - .thumbs.thumbsFocus .selected span, .dragthumb span{ - color: white; - background-color: #25a8e7; - } - - .thumbs #txt_rename{ - border: 1px solid #25a8e7; - border-width : 1px 1px 1px 1px; - float: none; - margin-top : -2px; - padding: 2px 2px 2px 3px; - font-family: Tahoma; - font-size: 11px; - color: #4b4b4b; - word-break: keep-all; - overflow: visible; - cursor: text; - } - - .thumbs input#txt_rename{ - padding : 1px; - outline: none; - text-align : center; - width : 88px; - } - - .thumbs .empty, .thumbs .loading{ - font-weight : normal; - color : #aaa; - padding : 5px; - } - - .thumbs .dragInsert{ - margin-left : 4px; - border-left : 2px solid gray; - } - - .thumb_attach blockquote{ - background-color : #fafafa; - } - ]]></j:style> - - <j:presentation> - <j:main container="."> - <div class='thumbs'> - </div> - </j:main> - <j:item - class = "." - image = "blockquote" - select = "." - > - <div class="thumb"><blockquote> </blockquote></div> - </j:item> - <j:dragindicator> - <div class='dragthumb'><blockquote> </blockquote></div> - </j:dragindicator> - <j:loading> - <div class="loading">Loading...</div> - </j:loading> - <j:empty caption="."> - <div class="empty">-</div> - </j:empty> - </j:presentation> -</j:list> -<j:list name="radiolist"> - <j:style><![CDATA[ - .radiolist{ - overflow : auto; - position : relative; - cursor : default; - } - - .radiolist, .draglist{ - font-family : Tahoma; - font-size : 8pt; - } - - .radiolist DIV, .draglist{ - padding : 0; - height : 18px; - width : 80px; - margin-right : 4px; - float : left; - overflow : hidden; - white-space : nowrap; - padding : 0 0 0 16px; - position : relative; - } - - .radiolist U, .draglist U{ - text-decoration : none; - color : black; - cursor : default; - display : block; - padding : 2px 4px 2px 2px; - text-decoration : none; - float : left; - overflow : hidden; - max-width : 100%; - _width: 70px; - white-space : nowrap; - text-overflow : ellipsis; - } - - .radiolist .selected U{ - color : black; - } - .radiolist .indicate U, .radiolistFocus .indicate U{ - border: 1px dotted #BBB; - padding : 1px 3px 1px 1px; - } - - .radiolist .more u{ - border : 1px solid #a5a5a5; - border-left : 0; - margin-left : -2px; - padding : 0 3px 1px 3px; - font-size : 11px; - line-height: 13px; - } - - .radiolist .more b{ - background : url(images/plusplain.gif) no-repeat 3px 3px; - border : 1px solid #a5a5a5; - border-right : 0; - width : 14px; - height : 14px; - margin : 0 0 0 2px; - line-height: 13px; - } - - .radiolist .more_down u, .radiolist .more_down b{ - background-color : #EFEFEF; - } - - .radiolist #txt_rename{ - border : 1px solid #bbb; - padding : 1px 1px 1px 1px; - font-family : Tahoma; - font-size : 8pt; - color : black; - word-break : keep-all; - overflow : visible; - margin-top : 0px; - cursor : text; - height : 13px; - width : auto; - float : left; - } - .radiolist input#txt_rename{ - outline : none; - width : 75px; - } - - .radiolist .empty{ - text-align : center; - padding : 3px 0 0 0; - } - - .radiolist b{ - overflow : hidden; - margin : 2px; - - width: 12px; - height: 12px; - background: url("images/radio.png") no-repeat 0 -12px; - position : absolute; - left : 0; - top : 0; - } - - .radiolist .selected b { - background-position: 0 -24px; - } - - .radiolistDisabled .selected b { - background-position: 0 -0px; - } - ]]></j:style> - <!--j:style condition="!IS_IE"><![CDATA[ - .radiolist #txt_rename{ - display : block; - width : 100px; - } - ]]></j:style--> - - <j:presentation> - <j:main container="." type="2"> - <div class='radiolist'> - </div> - </j:main> - <j:item - class = "." - caption = "u" - select = "." - > - <div><b> </b><u>-</u></div> - </j:item> - <j:dragIndicator> - <div class='draglist'><span><u>-</u></span></div> - </j:dragIndicator> - <j:loading> - <div class="loading">Loading...</div> - </j:loading> - <j:empty caption="."> - <div class="empty">-</div> - </j:empty> - </j:presentation> -</j:list> -<j:list name="checklist"> - <j:style><![CDATA[ - .checklist{ - overflow : auto; - position : relative; - cursor : default; - } - - .checklist, .draglist{ - font-family : Tahoma; - font-size : 8pt; - } - - .checklist DIV, .draglist{ - padding : 0; - height : 18px; - width : 80px; - margin-right : 4px; - float : left; - overflow : hidden; - white-space : nowrap; - padding : 0 0 0 16px; - position : relative; - } - - .checklist U, .draglist U{ - text-decoration : none; - color : black; - cursor : default; - display : block; - padding : 2px 4px 2px 2px; - text-decoration : none; - white-space : nowrap; - float : left; - overflow : hidden; - max-width : 100%; - text-overflow : ellipsis; - } - - .checklist .selected U{ - color : black; - } - .checklistFocus .indicate U{ - border: 1px dotted #BBB; - padding : 1px 3px 1px 1px; - } - - .checklist .more u{ - border : 1px solid #a5a5a5; - border-left : 0; - margin-left : -2px; - padding : 0px 3px 1px 3px; - font-size : 11px; - line-height: 13px; - } - - .checklist .more b{ - background : url(images/plusplain.gif) no-repeat 3px 3px; - border : 1px solid #a5a5a5; - border-right : 0; - width : 14px; - height : 14px; - margin : 0 0 0 2px; - line-height: 13px; - } - - .checklist .more_down u, .checklist .more_down b{ - background-color : #EFEFEF; - } - - .checklist #txt_rename{ - border : 1px solid #bbb; - padding : 1px 1px 1px 1px; - font-family : Tahoma; - font-size : 8pt; - color : black; - word-break : keep-all; - overflow : visible; - margin-top : 0px; - cursor : text; - height : 13px; - width : auto; - float : left; - } - - .checklist input#txt_rename{ - outline : none; - width : 75px; - padding-left : 0; - } - - .checklist .empty{ - text-align : center; - padding : 3px 0 0 0; - } - - .checklist b{ - overflow : hidden; - margin : 2px; - - width: 12px; - height: 12px; - background: url("images/checkbox.png") no-repeat 0 -12px; - position : absolute; - left : 0; - top : 0; - } - - .checklist .selected b { - background-position: 0 -24px; - } - - .checklistDisabled .selected b { - background-position: 0 -0px; - } - ]]></j:style> - <!--j:style condition="!IS_IE"><![CDATA[ - .checklist #txt_rename{ - display : block; - width : 100px; - } - ]]></j:style--> - - <j:presentation> - <j:main container="." type="2"> - <div class='checklist'> - </div> - </j:main> - <j:item - class = "." - caption = "u" - select = "." - > - <div><b> </b><u>-</u></div> - </j:item> - <j:dragIndicator> - <div class='draglist'><span><u>-</u></span></div> - </j:dragIndicator> - <j:loading> - <div class="loading">Loading...</div> - </j:loading> - <j:empty caption="."> - <div class="empty">-</div> - </j:empty> - </j:presentation> -</j:list> -<j:list name="mnulist"> - <j:style><![CDATA[ - .mnulist{ - position: relative; - background-color: white; - cursor: default; - border: 0; - overflow: hidden; - } - - .mnulist, .draglist{ - font-family: Tahoma; - font-size: 8pt; - } - - .mnulist DIV, .draglist{ - padding: 0; - height: 14px; - background : no-repeat 2px 2px; - padding : 3px 0 3px 22px; - white-space : nowrap; - text-overflow : ellipsis; - } - - .mnulist .hover{ - background-color : #25a8e7; - color : white; - } - - /* , .mnulist .indicate */ - .mnulist .selected{ - color: white; - background-color: #25a8e7; - } - - .mnulist #txt_rename{ - border: 1px solid #bbb; - padding: 1px 15px 1px 1px; - font-family: Tahoma; - font-size: 8pt; - color: black; - word-break: keep-all; - overflow: visible; - margin-top : 0px; - cursor: text; - height: 13px; - display: block; - outline : none; - } - - .mnulist .loading, .mnulist .empty, .mnulist .offline{ - font-weight : normal; - color : #aaa; - padding : 5px 5px 0 5px; - text-align : center; - } - - .mnulist .stdel, .mnulistFocus .stdel{ - color : #ccc; - } - ]]></j:style> - - <j:presentation> - <j:main container="."> - <div class='mnulist'> - </div> - </j:main> - <j:item - class = "." - caption = "." - icon = "." - select = "." - > - <div>-</div> - </j:item> - <j:dragindicator> - <div class='draglist'><span><u>-</u></span></div> - </j:dragindicator> - <j:loading> - <div class="loading">Loading...</div> - </j:loading> - <j:empty caption="."> - <div class="message">-</div> - </j:empty> - </j:presentation> -</j:list> -<j:statusbar name="statusbar"> - <j:style><![CDATA[ - .statusbar { - border-top: 1px solid #b2b2b2; - overflow: hidden; - color: #4b4b4b; - background : url(images/statusbar.gif); - height: 21px; - width: 100%; - overflow: hidden; - position: absolute; - bottom: 0; - padding: 0 0 0 0; - } - - .statusbar .panel{ - padding: 1px 5px 0 5px; - - font-size: 11px; - font-family: Tahoma; - background: no-repeat 3px 1px; - height: 15px; - float: left; - margin : 2px 2px 0 0; - - border-right: 1px solid #c3c3c3; - border-left: 1px solid #FFFFFF; - } - - .statusbar .panelLast{ - float: none; - margin: 0 0 0 0; - border-right: 0; - } - - .statusbar .panelIcon{ - padding-left: 23px - } - - .windowMax .statusbar .corner { - display: none; - } - - .statusbar .corner{ - width: 13px; - height: 13px; - position: absolute; - right: 0; - top: 7px; - display: block; - } - ]]></j:style> - - <j:presentation> - <j:main container="." corner="span"> - <div class='statusbar'><span class='corner'></span></div> - </j:main> - <j:panel icon="." caption="text()" container="."> - <div class='panel'> </div> - </j:panel> - </j:presentation> -</j:statusbar> -<j:tree name="checktree"> - <j:style><![CDATA[ - .checktree{ - overflow: auto; - position: relative; - background-color: white; - cursor: default; - } - - .checktree SPAN, .dragchecktree SPAN{ - width: 15px; - height: 18px; - background: no-repeat 3px 5px; - display: block; - margin-left: -29px; - } - - .dragchecktree SPAN{ - background : transparent; - } - - .checktree DIV.pluslast SPAN, - .checktree DIV.plus SPAN{background-image:url(images/plus.png)} - - .checktree DIV.minlast SPAN, - .checktree DIV.min SPAN{background-image:url(images/min.png)} - - .checktree DIV, .dragchecktree{ - padding: 0; - height: 18px; - padding-left:29px; - - font-family: Tahoma, Arial; - font-size: 8.5pt; - position : relative; - } - - .dragchecktree{ - opacity : 0.5; - background : none; - } - - - .checktree LABEL, .dragchecktree LABEL{ - padding: 1px 0 0 18px; - background: no-repeat 1px center; - height: 16px; - white-space: nowrap; - margin-left: 0px; - display: block; - float: left; - margin-top: -18px; - } - - .checktree DIV.loading LABEL{ - background: url(icons/icoConnect.gif) no-repeat 1px center; - } - .checktree DIV.loading SPAN{ - background: no-repeat 0px 0px; - } - - .checktree U, .dragchecktree U{ - text-decoration: none; - color : black; - cursor: default; - display: inline !important; display: block; - padding: 2px 4px 2px 2px; - } - - - .checktreeFocus .indicate U{ - border: 1px dotted #BBB;/*#25a8e7;*/ - padding: 1px 3px 1px 1px; - color : black; - } - - .checktree BLOCKQUOTE{ - margin: 0; - padding: 0 0 0 20px; - display: none; - height: 0; - overflow: hidden; - background: repeat-y 0px center; - } - - .checktree #txt_rename{ - border: 1px solid black; - padding: 1px 15px 1px 1px; - font-family: Tahoma; - font-size: 8pt; - color: black; - word-break: keep-all; - overflow: visible; - margin-top : -2px; - *margin-top: 0; - cursor: text; - height: 13px; - outline : none; - } - - .checktree DIV.dragInsert label{ - border-top: 2px solid black; - height: 14px; - overflow: hidden; - } - - .checktree DIV.dragInsert U, .checktree DIV.dragDenied U{ - padding-top: 0; - } - - /*.checktree DIV.dragDenied label{ - border-top: 2px solid red; - height: 14px; - overflow: hidden; - padding-top : 2px; - margin-top : -20px; - background-position : 1px 0; - }*/ - - .checktree .message{ - text-align: center; - padding: 8px 10px 0 0; - color: #AAA; - } - - .checktree b{ - overflow : hidden; - margin : 2px; - - width: 12px; - height: 12px; - background: url("images/checkbox.png") no-repeat 0 -12px; - float : left; - margin-left : -31px; - } - - .checktree .selected b { - background-position: 0 -24px; - } - - .checktree .partial b { - background-position: 0 -48px; - } - - .checktreeDisabled .selected b { - background-position: 0 -0px; - } - ]]></j:style> - - <j:presentation> - <j:main container="." startclosed="false"> - <div class="checktree"> - - </div> - </j:main> - <j:item - class = "." - caption = "label/u/text()" - icon = "label" - openclose = "span" - select = "label" - container = "following-sibling::blockquote" - > - <div><span> </span><label><b> </b><u>-</u></label></div> - <blockquote> </blockquote> - </j:item> - <j:dragindicator> - <div class='dragchecktree'><span> </span><label><u>-</u></label></div> - </j:dragindicator> - <j:loading> - <div class="loading"><span> </span><label>Loading...</label></div> - </j:loading> - <j:empty caption="."> - <div class="message"></div> - </j:empty> - </j:presentation> -</j:tree> -<j:tree name="tree"> - <j:style><![CDATA[ - .tree{ - border: 1px solid #c3c3c3; - - background-color: white; - width: 200px; - height: 500px; - overflow: hidden; - cursor : default; - - overflow: auto; - } - - .tree SPAN, .dragtree SPAN{ - width: 15px; - height: 18px; - background: no-repeat 3px 5px; - display: block; - margin-left: -15px; - } - - .dragtree SPAN{ - background : transparent; - } - - .tree DIV.pluslast SPAN, - .tree DIV.plus SPAN{background-image:url(images/plus.png)} - - .tree DIV.minlast SPAN, - .tree DIV.min SPAN{background-image:url(images/min.png)} - - .tree DIV, .dragtree{ - padding: 0; - height: 18px; - padding-left: 15px; - - font-family: Tahoma, Arial; - font-size: 8.5pt; - } - - .dragtree{ - opacity : 0.5; - filter:progid:DXImageTransform.Microsoft.Alpha(opacity=50); - background : none; - } - - /*.tree DIV.root{ - padding: 0; - }*/ - - .tree LABEL, .dragtree LABEL{ - padding: 1px 0 0 20px; - background: no-repeat 1px 1px; - height: 16px; - white-space: nowrap; - margin-left: 0px; - display: block; - float: left; - margin-top: -18px; - } - - .tree DIV.loading LABEL{ - - } - .tree DIV.loading SPAN{ - background: no-repeat 0px 0px; - } - - .tree U, .dragtree U{ - text-decoration: none; - color: black; - cursor: default; - display: inline !important; display: block; - padding: 2px 4px 2px 2px; - } - - - .treeFocus .indicate U{ - border: 1px dotted #BBB;/*#25a8e7;*/ - padding: 1px 3px 1px 1px; - color : black; - } - - .tree .selected U, .tree .dragAppend U{ - background-color: #f0f0f0; - color: black; - } - - .treeFocus .selected U, .treeFocus .dragAppend U, .dragtree U{ - color: white; - background-color: #25a8e7; - } - - .tree BLOCKQUOTE{ - margin: 0; - padding: 0 0 0 20px; - display: none; - height: 0; - overflow: hidden; - background: repeat-y 0px center; - } - /*.tree BLOCKQUOTE.root{padding:0}*/ - - .tree #txt_rename{ - border: 1px solid black; - padding: 1px 15px 1px 1px; - font-family: Tahoma; - font-size: 8pt; - color: black; - word-break: keep-all; - overflow: visible; - margin-top : -2px; - *margin-top: 0; - cursor: text; - height: 13px; - outline : none; - } - - .tree DIV.dragInsert label{ - border-top: 1px solid gray; - padding-top : 2px; - background-position : 1px 0; - height: 15px; - overflow: hidden; - } - - .tree DIV.dragInsert U{ - padding-top: 0; - } - - /*.tree DIV.dragDenied label{ - border-top: 2px solid red; - height: 14px; - overflow: hidden; - padding-top : 2px; - margin-top : -20px; - background-position : 1px 0; - }*/ - - .tree .empty, .tree .offline, .tree .loading{ - text-align: center; - padding: 4px 0 2px 0; - color: #AAA; - font-weight : normal; - } - - .tree .loading{ - text-align : left; - } - ]]></j:style> - - <j:presentation> - <j:main container="." startclosed="false"> - <div class="tree"> - - </div> - </j:main> - <j:item - class = "." - caption = "label/u" - icon = "label" - openclose = "span" - select = "label" - container = "following-sibling::blockquote" - > - <div><span> </span><label><u>-</u></label></div> - <blockquote> </blockquote> - </j:item> - <j:dragindicator> - <div class='dragtree'><span> </span><label><u>-</u></label></div> - </j:dragindicator> - <j:loading> - <div class="loading"><span> </span><label>Loading...</label></div> - </j:loading> - <j:empty caption="."> - <div class="message"></div> - </j:empty> - </j:presentation> -</j:tree> -<j:splitter name="splitter"> - <j:style><![CDATA[ - .splitter{ - position: absolute; - zIndex: 100; - overflow: hidden; - background: url(images/spacer.gif); - padding: 1px; - background : #f1f1f1; - } - - .splitterFocus{ - border: 1px dotted black; - padding: 0; - } - - .w-resize{ - cursor: w-resize; - } - - .n-resize{ - cursor: n-resize; - } - - .moving{ - background-color: gray; - } - - .horizontal div{ - height: 2px; - width: 18px; - background : url(images/splitter_handle_horizontal.gif); - margin: -1px auto 0 auto; - } - - .vertical div{ - height: 18px; - width: 2px; - background : url(images/splitter_handle_vertical.gif); - position: relative; - top: 50%; - margin: -9px 0 0 0; - } - - ]]></j:style> - - <j:presentation> - <j:main handle="."> - <div class='splitter'><div></div></div> - </j:main> - </j:presentation> -</j:splitter> -<!-- - * Please add an Error state - done - * Please make this component sizable horizontally - done ---> -<j:dropdown name="dropdown"> - <j:style><![CDATA[ - .dropdown{ - position: relative; - background: url("images/dropdown.png") no-repeat top right; - width: 134px; - height: 17px; - margin: 0; - padding : 2px 18px 0 0; - - color: #4b4b4b; - font-family : Tahoma; - font-size : 11px; - } - - .dropdownError { - background-position: right -57px; - } - - .dropdownDisabled { - color: #bebebe; - } - - .dropdownFocus { - background-position: right -19px; - } - - .dropdownOver { - - } - - .dropdownDown { - position: relative; - background-position: right -38px; - } - - .dropdown .dropdownLeftBorder { - background: url("images/dropdown.png") no-repeat top left; - float: left; - margin: -2px 0 0 0; - width: 2px; - _margin: -2px -1px 0 0; - height: 19px; - } - - .dropdown .dropdownlabel{ - padding: 0 0 0 4px; - cursor : default; - height: 15px; - margin : 0 0 0 2px; - overflow : hidden; - white-space : nowrap; - text-overflow : ellipsis; - } - - .dropdownError .dropdownLeftBorder { - background-position: 0 -57px; - } - - .dropdownError .dropdownlabel{ - background-color: #ffb500; - color: #fbfbfb; - } - - - .dropdownInitial .dropdownLeftBorder { - } - - .dropdownInitial .dropdownlabel{ - color : #999; - } - - .dropdownInitial.dropdownFocus .dropdownLeftBorder{ - background-position: 0 -19px; - } - - .dropdownInitial.dropdownFocus .dropdownlabel{ - background-color: transparent; - color : #ffffff; - } - - .dropdownFocus .dropdownLeftBorder{ - background-position: 0 -19px; - } - - .dropdownFocus .dropdownlabel{ - background-color: #25a8e7; - color: #ffffff; - } - - .dropdownDown .dropdownLeftBorder { - background-position: 0 -38px; - } - - .dropdownDown .dropdownlabel{ - color : #4b4b4b; - background-color : white; - } - - .optionList{ - position: absolute; - top: 0; - left: 0; - width: 120px; - margin-top : -1px; - border: 1px solid #327fbd; - background: #ffffff url("images/dropdown_background.png") repeat-y top left; - z-index: 1000; - color: #0d5381; - font-family : Tahoma; - font-size : 11px; - display : none; - overflow : auto; - } - - .optionList .top{ - background: url("images/dropdown_background_top.png") no-repeat top left; - width: 136px; - height: 5px; - } - - .optionList span{ - display: block; - height: 15px; - padding: 2px 3px 2px 6px; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - background-color: white; - color: black; - cursor: default; - } - - .optionList span.hover { - background-color: #25a8e7; - color: #ffffff; - } - - .optionList .selected{ - background-color: #f0f0f0; - } - ]]></j:style> - - <j:presentation> - <j:main label="div[2]/text()" button="." width-diff="-1" item-height="21.1"> - <div class='dropdown'> - <div class='dropdownLeftBorder'> </div> - <div class='dropdownlabel'>-</div> - </div> - </j:main> - <j:container contents="."> - <div class='optionList'> - </div> - </j:container> - <j:item - class = "." - caption = "text()" - select = "." - > - <span>-</span> - </j:item> - <j:empty caption="."> - <div class="empty">-</div> - </j:empty> - </j:presentation> -</j:dropdown> -<!-- - * A couple of errors when set to 100% -still there are problems; I added .progressbarComplete ---> -<j:progressbar name="progressbar"> - <j:style><![CDATA[ - .progressbar { - position: relative; - width: 147px; - height : 8px; - cursor : default; - } - - .progressbar .lbl { - position: relative; - background: url("images/bar_right.png") no-repeat top left; - font-family : Tahoma; - font-size : 9px; - float : right; - height : 8px; - width: 30px; - padding: 0; - _margin: 0 0 0 -4px; - } - - .progressbar .lbl span { - display: block; - position: absolute; - top: -2px; - left: 6px; - } - - .progressbar .left{ - background: url("images/bar_left.png") no-repeat top left; - height: 8px; - margin: 0 30px 0 0; - _margin: 0; - } - - .lowlabel{ - } - - .lowlabel .lbl{ - position: static; - width: 4px; - } - - .lowlabel .lbl span { - display: block; - positiom: absolute; - top: 10px; - left: 0; - } - - .lowlabel .left { - margin: 0 4px 0 0; - } - - .progressbarDisabled { - color: #bebebe; - } - - .progressbarDisabled .left { - background-position: left -8px; - } - - .progressbarDisabled .lbl{ - background-position: left -8px; - } - - .progressbar .filledbar { - background: url("images/progressbar.png") no-repeat top left; - height: 8px; - overflow: hidden; - padding : 0 0 0 3px; - border-right : 1px solid #327fbd; - display : none; - width : 0%; - margin-right: -1px; - _margin-right: -4px; - z-index: 1000; - } - - .progressbarDisabled .filledbar { - background-position: 0 -8px; - border-right : 1px solid #cfd0d0; - } - - .progressbarDisabled .left{ - background-position: left -8px; - } - - .progressbarRunning .filledbar{ - display: block; - } - - .progressbarComplete .left { - background: url("images/progressbar.png") no-repeat top left; - - } - - .progressbarComplete .lbl { - background: url("images/progressbar.png") no-repeat -496px 0; - } - - ]]></j:style> - <j:style condition="jpf.isIE7"> - .progressbar .lbl { - margin: 0; - } - </j:style> - - <j:presentation> - <j:main progress="div[2]/div" caption="div[1]/span/text()"> - <div class="progressbar"> - <div class="lbl"><span>0%</span></div> - <div class="left"> - <div class="filledbar"> </div> - </div> - </div> - </j:main> - </j:presentation> -</j:progressbar> -<j:slider name="slider"> - <j:alias>range</j:alias> - <j:alias>horizontal</j:alias> - - <j:style><![CDATA[ - .slider { - background: url("images/bar_right.png") no-repeat top right; - width: 150px; - height: 8px; - position: relative; - - font-family : Tahoma; - font-size : 9px; - text-align : center; - } - - .sliderDisabled { - background-position: right -8px; - } - - .slider .left{ - background: url("images/bar_left.png") no-repeat top left; - height: 8px; - overflow: hidden; - margin-right : 4px; - } - - .sliderDisabled .left{ - background-position: left -8px; - } - - .sliderDisabled .filledbar { - background-position: 0 -8px; - } - - .slider .grabber { - background: url("images/slider.png") no-repeat top left; - width: 20px; - height: 8px; - overflow: hidden; - position: absolute; - } - - .sliderDisabled .grabber { - background-position: left -8px; - } - ]]></j:style> - - <j:presentation> - <j:main slider="div[1]" container="." status2="div[2]/text()" - markers="." direction="horizontal"> - <div class="slider"> - <div class="grabber"> </div> - <div class="left"> </div> - </div> - </j:main> - <marker> - <u> </u> - </marker> - </j:presentation> -</j:slider> -<j:slider name="sliderHigh"> - <j:style><![CDATA[ - .sliderHigh { - background: url("images/bar_right.png") no-repeat top right; - width: 150px; - height: 8px; - margin-top : 8px; - margin-bottom : 8px; - position: relative; - - font-family : Tahoma; - font-size : 9px; - text-align : center; - } - - .sliderHighDisabled { - background-position: right -8px; - } - - .sliderHigh .left{ - background: url("images/bar_left.png") no-repeat top left; - height: 8px; - overflow: hidden; - margin-right : 4px; - } - - .sliderHighDisabled .left{ - background-position: left -8px; - } - - .sliderHighDisabled .filledbar { - background-position: 0 -8px; - } - - .sliderHigh .grabber { - background: url("images/slider2.png") no-repeat top left; - width: 7px; - height: 16px; - overflow: hidden; - position: absolute; - top : -4px; - } - - .sliderHighDisabled .grabber { - background-position: left -16px; - } - ]]></j:style> - - <j:presentation> - <j:main slider="div[1]" container="." status2="div[2]/text()" - markers="." direction="horizontal"> - <div class="sliderHigh"> - <div class="grabber"> </div> - <div class="left"> </div> - </div> - </j:main> - <marker> - <u> </u> - </marker> - </j:presentation> -</j:slider> -<j:slider name="slider16"> - <j:style><![CDATA[ - .slider16 { - background: url("images/bar16x_right.png") no-repeat top right; - width: 300px; - height: 16px; - position: relative; - padding-right: 7px; - - font-family : Tahoma; - font-size : 9px; - text-align : center; - } - - .slider16Disabled { - background-position: right -16px; - } - - .slider16 .left{ - background: url("images/bar16x_left.png") no-repeat top left; - height: 16px; - overflow: hidden; - } - - .slider16Disabled .left{ - background-position: left -16px; - } - - - .slider16 .grabber { - background: url("images/slider16x.png") no-repeat top right; - width: 40px; - height: 16px; - overflow: hidden; - position: absolute; - } - - .slider16Disabled .grabber { - background-position: left -48px; - } - - .slider16Down .grabber { - background-position: right -16px; - } - - .slider16Focus .grabber { - background-position: right -32px; - } - ]]></j:style> - - <j:presentation> - <j:main slider="div[1]" container="." status2="div[2]/text()" - markers="." direction="horizontal"> - <div class="slider16"> - <div class="grabber"> </div> - <div class="left"> </div> - </div> - </j:main> - <marker> - <u> </u> - </marker> - </j:presentation> -</j:slider> -<j:slider name="slider11"> - <j:style><![CDATA[ - .slider11 { - background: url("images/bar11x_right.png") no-repeat top right; - width: 300px; - height: 11px; - position: relative; - padding-right: 5px; - - font-family : Tahoma; - font-size : 9px; - text-align : center; - } - - .slider11Disabled { - background-position: right -11px; - } - - .slider11 .left{ - background: url("images/bar11x_left.png") no-repeat top left; - height: 11px; - overflow: hidden; - } - - .slider11Disabled .left{ - background-position: left -11px; - } - - - .slider11 .grabber { - background: url("images/slider11x.png") no-repeat top right; - width: 29px; - height: 11px; - overflow: hidden; - position: absolute; - } - - .slider11Disabled .grabber { - background-position: left -11px; - } - ]]></j:style> - - <j:presentation> - <j:main slider="div[1]" container="." status2="div[2]/text()" - markers="." direction="horizontal"> - <div class="slider11"> - <div class="grabber"> </div> - <div class="left"> </div> - </div> - </j:main> - <marker> - <u> </u> - </marker> - </j:presentation> -</j:slider> -<!-- - * This skin can be optimized by making it fixed width. - ---> -<j:errorbox name="errorbox"> - <j:style><![CDATA[ - .errorbox{ - font-family: Tahoma; - font-size: 8pt; - cursor : default; - - z-index: 100000; - position: absolute; - margin : 22px 0 0 16px; - width : 250px; - } - - .errorbox .errorboxContent { - background: url(images/errorbox_backg.png) repeat-y top left; - width: 250px; - } - - .errorbox .errorboxContent span{ - background : transparent; - } - - .errorbox .errorboxTop { - background: url("images/errorbox_top.png") no-repeat top left; - width: 250px; - height: 9px; - } - - .errorbox .errorboxBottom { - background: url("images/errorbox_bottom.png") no-repeat top left; - width: 250px; - height: 16px; - } - - .errorbox .errorboxTop div { - background: url("images/tooltip_arrow.png") no-repeat top left; - width: 19px; - height: 11px; - position: absolute; - top: -10px; - left: 15px; - padding: 0; - margin: 0; - border: 0; - z-index: 10000000; - } - - .errorbox .close { - width: 13px; - height: 13px; - background: url("images/close.png") no-repeat top left; - overflow: hidden; - cursor : default; - position : absolute; - right : 13px; - top : 6px; - } - - .errorbox .close:hover{ - background-position : 0 -13px; - } - - .errorbox span{ - display: block; - padding: 0 10px 4px 10px; - - } - - .errorbox strong{ - display : block; - line-height: 13px; - margin-top: 0; - padding-top: 0; - padding-bottom: 3px; - border: 0; - } - - .rightbox{ - margin-left : -205px; - } - - .rightbox .errorboxTop div { - right : 20px; - left : auto; - } - ]]></j:style> - - <j:presentation> - <j:main container="div[2]/span" close="div[1]/a"> - <div class="errorbox"> - <div class="errorboxTop"><div> </div><a class="close" href="javascript:void(0)" onclick="return false"> </a></div> - <div class="errorboxContent"><span> </span></div> - <div class="errorboxBottom"> </div> - </div> - </j:main> - </j:presentation> -</j:errorbox> - - -<!--j:errorbox name="errorbox"> - <j:style><![CDATA[ - .errorbox{ - font-family: Tahoma; - font-size: 8pt; - - z-index: 1000000000; - position: absolute; - margin : 22px 0 0 7px; - width : 250px; - cursor : default; - } - - .errorbox .tLeft{ - background: url("images/error_box_lt.png") no-repeat top left; - width: 8px; - height: 9px; - float:left; - margin: 0; - _margin: 0 -8px 0 0; /* IE6 bug fix */ - padding: 0; - border: 0; - } - - .errorbox .tRight { - background: url("images/error_box_rt.png") no-repeat top left; - width: 14px; - height: 9px; - float: right; - margin: 0; - _margin: 0 0 0 -14px; /* IE6 bug fix */ - padding: 0; - border: 0; - } - - .errorbox .tBorder { - border-top:1px solid #c3c3c3; - height: 8px; - margin: 0 14px 0 8px; - padding: 0; - background-color : white; - } - - .errorbox .tBorder { - position: relative; - } - - .errorbox .tBorder div { - background: url("images/tooltip_arrow.png") no-repeat top left; - width: 19px; - height: 11px; - position: absolute; - top: -11px; - left: 8px; - padding: 0; -/* _padding: 9px; *//* IE6 bug fix */ - margin: 0; - border: 0; - } - - .errorbox .ebcontent{ - border-left: 1px solid #c3c3c3; - padding: 0 14px 0 10px; - overflow: hidden; - background-color : white; - margin : 0 8px 0 0; - } - - .errorbox .mRight { - background: url("images/error_box_r.png") repeat-y top right; - overflow: hidden; - _margin: -9px 0 0 0; /* IE6 bug fix */ - } - - .errorbox .bLeft{ - background: url("images/error_box_lb.png") no-repeat top left; - width: 8px; - height: 16px; - float: left; - margin: 0; - _margin: 0 -8px 0 0; /* IE6 bug fix */ - padding: 0; - border: 0; - } - - .errorbox .bRight{ - background: url("images/error_box_rb.png") no-repeat top right; - width: 14px; - height: 16px; - float: right; - margin: 0; - _margin: 0 0 0 -14px; /* IE6 bug fix */ - padding: 0; - border: 0; - } - - .errorbox .bBar{ - background: url("images/error_box_b.png") repeat-x bottom left; - height: 16px; - margin: 0 14px 0 8px; - padding: 0; - border: 0; - } - - .errorbox .ebcontent .titleBar { - margin-bottom: 8px; - font-weight: bold; - color: #327fbd; - } - - .errorbox .close { - width: 13px; - height: 13px; - background: url("images/close.png") no-repeat top left; - overflow: hidden; - cursor : default; - position : absolute; - right : 13px; - top : 6px; - } - - .errorbox .close:hover{ - background-position : 0 -13px; - } - - .errorbox .ebcontent span{ - display: block; - padding: 4px 0; - - } - - .errorbox strong{ - display : block; - margin : -5px 0 3px 0; - } - - ]]></j:style> - - <j:presentation> - <j:main container="div[4]/div/span" close="div[4]/div/div/a"> - <div class="errorbox"> - <div class="tLeft"> </div> - <div class="tRight"> </div> - <div class="tBorder"><div> </div></div> - - <div class="mRight"> - <div class="ebcontent"> - <div class="titleBar"><a class="close" href="javascript:void(0)" onclick="return false"> </a></div> - <span> </span> - </div> - </div> - - <div class="bLeft"> </div> - <div class="bRight"> </div> - <div class="bBar"> </div> - </div> - </j:main> - </j:presentation> -</j:errorbox--> - - - -<!-- - * Please optimize this skin (at least 2 elements less) - big problems with ie6 if I optimize ---> -<j:bar name="bar"> - <j:style><![CDATA[ - .bar{ - color: #4b4b4b; - font-family : Tahoma; - font-size : 8pt; - padding : 20px 0 26px 0; - _padding: 20px 0 26px 0; - } - - .bar .contents { - clear: both; - border-top: 1px solid #c3c3c3; - border-left: 1px solid #c3c3c3; - border-right: 1px solid #c3c3c3; - background: #fafbfc; - padding: 7px; - /*overflow: hidden; */ - height : 100%; - padding : 15px; - margin-top : -20px; - } - - .bar .barFooter{ - clear: both; - height: 15px; - background: url(images/tab_pag_lb.png) no-repeat bottom left; - position : absolute; - bottom : 0; - width : 100%; - } - - .bar .barFooter div{ - background: url(images/tab_pag_rb.png) no-repeat bottom right; - } - - .bar .barFooter div div { - border-bottom: 1px solid #c3c3c3; - background-color: #fafbfc; - background-image: none; - height: 14px; - margin: 0 14px; - } - - - ]]></j:style> - <j:style condition="jpf.isIE6"> - .bar { - padding: 20px 0 0 0; - } - .bar .contents { - padding-bottom: 0; - } - </j:style> - <j:presentation> - <j:main container="div"> - <div class="bar"> - <div class="contents"> </div> - <div class="barFooter"><div><div> </div></div></div> - </div> - </j:main> - </j:presentation> -</j:bar> -<j:bar name="previewBar"> - <j:style><![CDATA[ - .previewBar{ - color: #4b4b4b; - font-family : Arial,Helvetica,Sans-serif; - font-size : 12px; - border: 1px solid #c3c3c3; - background: white none repeat scroll 0 0; - overflow : hidden; - padding-top : 46px; - } - - .previewBar .toolbar{ - margin-top : -46px; - } - - .previewBar .preview{ - overflow: auto; - padding: 10px; - height : 100%; - } - - ]]></j:style> - <j:presentation> - <j:main container="."> - <div class="previewBar"> - </div> - </j:main> - </j:presentation> -</j:bar> -<j:frame name="frame"> - <j:alias>fieldset</j:alias> - <j:style><![CDATA[ - .frame{ - padding: 0 7px 7px 7px; - border: 1px solid #dcd8d8; - color: #4b4b4b; - font-family: Tahoma; - font-size: 8pt; - /*position: relative; - display: block; - margin : 13px 0 0 0;*/ - margin : 0 0 5px 0; - cursor : default; - } - - .frame .legend{ - /*margin-top: 0px; - position: absolute; - background : #fafbfc; - left: 5px; - top: -8px; - padding: 0 2px 0 2px; - margin: 0px;*/ - margin : 0 0 7px -7px; - cursor : default; - } - ]]></j:style> - <j:style condition="jpf.isIE6"> - .frame { - height: 1%; - } - </j:style> - <j:style condition="!jpf.isIE"> - .frame .legend{ - margin : 5px 0 7px -3px; - } - </j:style> - - <j:presentation> - <j:main container="." caption="legend/text()"> - <fieldset class='frame'><legend class="legend">-</legend></fieldset> - </j:main> - </j:presentation> -</j:frame> -<j:modalwindow name="section"> - <j:style><![CDATA[ - .section{ - position: relative; - padding : 20px 0 0 0; - } - - .sectionhead span{ - width : 16px; - height : 16px; - display : block; - float : left; - margin : -1px 4px 1px 2px; - background : no-repeat 0 0; - } - - .section .sectionhead{ - height: 14px; - margin : -20px 0 -1px 0; - background : #25a8e7 url(images/sectionhead.gif); - color : #666; - padding : 3px 2px 3px 2px; - border : 1px solid #c3c3c3; - font-family : Tahoma; - font-size : 8pt; - font-weight : bold; - } - - .sectionActive .sectionhead{ - background : #25a8e7 url(images/sectionheadactive.gif); - color : white; - } - - .section .sectioncontainer{ - position : relative; - width : 100%; - height : 100%; - } - - .sectionCurrent .sectionhead{ - /*border-bottom : 2px solid #c3c3c3; - padding-bottom : 2px; - z-index : 10; - position : relative;*/ - } - - .section .sectionhead div{ - float : right; - width : 14px; - height : 14px; - margin : -1px 3px 0 0; - border : 1px solid transparent; - background : no-repeat 2px 2px; - } - - .section .sectionhead div.hover{ - border : 1px solid white; - } - .section .sectionhead .max{ - background-image: url(images/cmswin_max.gif); - } - .sectionMax .sectionhead .max{ - background-image: url(images/cmswin_restore.gif); - } - .section .sectionhead div.down{ - background-color : white; - } - ]]></j:style> - <j:presentation> - <j:main collapsed-height="20" - min-width="150" min-height="80" - container="div[2]" drag="div[1]" title="div[1]/text()" - icon="div[1]/span" buttons="div[1]"> - <div class='section'> - <div class="sectionhead"><span> </span>-</div> - <div class="sectioncontainer"></div> - </div> - </j:main> - <j:button> - <div> </div> - </j:button> - </j:presentation> -</j:modalwindow> -<j:upload name="upload"> - <j:style><![CDATA[ - .upload{ - /*border : 1px solid #dcdcdc; - padding : 2px; - font-family : Tahoma; - font-size : 11px; - color: #4b4b4b; - height : 13px;*/ - } - - .upload form{ - float: left; - } - - .upload .fileinput{ - -moz-user-focus: ignore; - opacity: 0; - filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0); - - height: 22px; - margin: -5px 0pt 0pt -200px; - z-index: 1; - position: relative; - } - - .upload iframe{ - visibility: hidden; - width: 0; - height: 0; - } - ]]></j:style> - - <j:presentation> - <j:main label="."> - <div class="upload"> - - </div> - </j:main> - <j:form inp_file="input[1]" inp_uid="input[2]"> - <form frameborder='0' method='post' action='' enctype='multipart/form-data'> - <input class="fileinput" type='file' name='userfile'/> - <input type='hidden' name='uniqueid' value='' /> - <input type="hidden" name="AUTH" value="PA20080587%3Aefdb43212c72c2d140827876781c5489" /> - </form> - </j:form> - </j:presentation> -</j:upload> -<!-- ********** END ********** --> - -<j:img name="img"> - <j:style><![CDATA[ - .img{ - padding : 10px; - border : 1px solid #c3c3c3; - background : #fafbfc no-repeat 50% 50%; - overflow : hidden; - position : relative; - text-align : center; - } - - .img img{ - margin : auto; - position : relative; - } - ]]></j:style> - - <j:presentation> - <j:main image="img/@src"> - <div class="img"> - <img src="" /> - </div> - </j:main> - </j:presentation> -</j:img> -<j:markupedit name="markupedit"> - <j:style><![CDATA[ - .markupedit { - border: 1px solid gray; - - background-color: #FFF; - width: 200px; - height: 500px; - overflow: auto; - - font-family: Courier New; - font-size: 11px; - cursor: default; - } - - .markupedit dl, .markupedit dt, .markupedit dd{ - margin: 0; - } - - .markupedit dt, .markupedit span{ - color: #0000FF; - } - - .markupedit dt{ - cursor: hand; - cursor: pointer; - } - - .markupedit .attribute dl, .markupedit .attribute dt, .markupedit .attribute dd{ - display: inline; - } - - #override .markupedit .textedit{ - background-color: white; - color: black; - border: 1px solid black; - padding: 1px 2px 1px 2px; - margin: -2px -4px -5px -3px; - } - #override strong.textedit{ - position: relative; - } - - #override .markupedit DIV .attribute DT, #override .markupedit DIV .attribute DD{ - cursor: text; - } - - .markupedit .attribute dt{ - color: #191970; - } - - .markupedit .attribute dd{ - color: #FF0000; - } - - .markupedit dt, .markupedit .attribute, .markupedit .selected span{ - float: left; - } - - .markupedit dl.attribute{ - padding: 0 0 0 5px; - } - - .markupedit dl{ - height: 14px; - white-space: nowrap; - } - - .markupedit span{ - display: block; - } - - .markupedit u{ - float: left; - text-decoration: none; - } - - .markupedit strong{ - font-weight: normal; - float: left; - } - - .markupedit .textnode strong{ - cursor: text; - } - - .markupedit DIV{ - cursor: default; - padding: 0 0 0 14px; - background-repeat: no-repeat; - background-position: 2px 3px; - } - - .markupedit .selected dl, .markupedit .selected dd, .markupedit .selected dt, .markupedit .selected span, .markupedit .selected strong{ - background-color: #191970; - color: #FFFFFF; - } - - #override .markupedit .highlight{ - background-color: #FFFF00; - color: #000000; - } - - .markupedit DIV.pluslast {background-image:url(images/splus.gif)} - .markupedit DIV.minlast {background-image:url(images/smin.gif)} - .markupedit DIV.plus {background-image:url(images/splus.gif)} - .markupedit DIV.min {background-image:url(images/smin.gif)} - - .markupedit BLOCKQUOTE{ - margin: 0; - padding: 0 0 0 10px; - display: none; - height: 0; - overflow: hidden; - } - ]]></j:style> - - <j:presentation> - <j:main container="." startclosed="false"> - <div class="markupedit"> - - </div> - </j:main> - <j:item - class = "dl" - begintag = "dl/dt" - begintail = "dl/span" - endtag = "span" - attributes = "dl" - openclose = "." - select = "dl" - container = "blockquote" - > - <div> - <dl><dt>-</dt><span> </span></dl> - <blockquote> </blockquote> - <span>-</span> - </div> - </j:item> - <j:attribute name="dt" value="dd"> - <dl class="attribute"><dt> </dt>="<dd> </dd>"</dl> - </j:attribute> - <j:textnode text="strong" tag="u"> - <strong class="textnode"><u> </u><strong>-</strong></strong> - </j:textnode> - <j:loading> - <div class="loading"><span> </span><label>Loading...</label></div> - </j:loading> - <j:empty caption="."> - <div class="empty"></div> - </j:empty> - </j:presentation> -</j:markupedit> -<j:testobject name="testobject"> - <j:alias>aliasofobject</j:alias> - - <j:style><![CDATA[ - .testobject{ - border: 1px solid red; - padding: 0 0 5px 0; - overflow: hidden; - height: 1%; - } - - .testobject div{ - border: 1px solid red; - width: 50px; - height: 50px; - margin: 5px; - float: left; - background: no-repeat 5px 5px; - } - - .testobjectFocus{ - border: 2px solid black; - } - - .testobjectDisabled{ - background-color: black; - } - ]]></j:style> - <j:presentation> - <j:main content="."> - <div class='testobject'> - - </div> - </j:main> - <j:item caption="." icon="."> - <div> </div> - </j:item> - </j:presentation> -</j:testobject> -<j:chart name="chart"> - <j:style><![CDATA[ - .chart { - top: 0px; - left: 0px; - width: 550px; - height: 370px; - padding: 0px 0px 0px 0px; - background-color:white; - } - ]]></j:style> - - <j:presentation> - <j:main container="."> - <div class='chart' style="position:relative; overflow:hidden;"></div> - </j:main> - </j:presentation> -</j:chart> - - -<j:bar name="barmedia"> - <j:style><![CDATA[ - .barmedia { - position: relative; - color: #4b4b4b; - font-family: Tahoma; - font-size: 10px; - padding: 10px; - border : 1px solid #c3c3c3; - border-width : 0 1px 1px 1px; - cursor: default; - margin: 0; - /* url(images/resizehandle.gif) */ - background: white no-repeat right bottom; - z-index: 10000; - } - - .barmedia img { - position: absolute; - bottom: 13px; - left: 216px; - } - - .barmedia .counter { - position: absolute; - bottom: 5px; - left: 40px; - } - - .barmedia .countdown { - position: absolute; - bottom: 5px; - right: 142px; - } - - .barmedia .volume { - position: absolute; - bottom: 5px; - right: 119px; - left: auto; - background: none; - width: 16px; - height: 16px; - margin: 0; - padding: 0; - cursor: pointer; - cursor: hand; - } - - .barmedia .volume span { - margin: 0; - padding: 0; - width: 16px; - height: 16px; - } - - .barmedia .fullscreen { - position: absolute; - bottom: 2px; - right: 28px; - left: auto; - width: 14px; - background: transparent; - cursor: pointer; - cursor: hand; - } - - .barmedia .fullscreen span { - height:14px; - width:14px; - margin:3px auto 0 0; - } - ]]></j:style> - <j:presentation> - <j:main container="." resize-corner="17"> - <div class="barmedia"> </div> - </j:main> - </j:presentation> -</j:bar> -<j:label name="labelmedia"> - <j:style><![CDATA[ - .labelmedia{ - font-size: 8pt; - font-family: Tahoma; - overflow: hidden; - cursor: default; - line-height : 1.5em; - margin : 0; - } - - .labelmediaDisabled{ - color: #bebebe; - } - - .tiny { - font-size : 9px; - } - - .error .labelmedia{ - background : url(images/alert.png) no-repeat 0 0; - min-height : 37px; - padding : 3px 0 0 45px; - } - ]]></j:style> - <j:presentation> - <j:main caption="." for="@for"> - <div class="labelmedia"> </div> - </j:main> - </j:presentation> -</j:label> -<j:slider name="slidermedia"> - <j:style><![CDATA[ - .slidermedia { - background: url("images/bar_right.png") no-repeat top right; - height: 8px; - position: relative; - font-family: Tahoma; - font-size: 9px; - text-align: center; - position: absolute; - bottom: 9px; - right: 53px; - margin: 0; - } - - .slidermediaDisabled { - background-position: right -8px; - } - - .slidermedia .left { - background: url("images/bar_left.png") no-repeat top left; - height: 8px; - overflow: hidden; - margin: 0; - margin-right: 4px; - } - - .slidermediaDisabled .left { - background-position: left -8px; - } - - .slidermediaDisabled .filledbar { - background-position: 0 -8px; - } - - .slidermedia .grabber { - background: url("images/slider3.png") no-repeat top left; - width: 12px; - height: 8px; - overflow: hidden; - position: absolute; - margin: 0; - } - - .slidermediaDisabled .grabber { - background-position: left -8px; - } - ]]></j:style> - <j:presentation> - <j:main slider="div[1]" container="." status2="div[2]/text()" markers="." direction="horizontal"> - <div class="slidermedia"> - <div class="grabber"> </div> - <div class="left"> </div> - </div> - </j:main> - <marker> - <u> </u> - </marker> - </j:presentation> -</j:slider> -<j:slider name="slider16media"> - <j:style><![CDATA[ - .slider16media { - background: url("images/bar16x_right.png") no-repeat top right; - width: 300px; - height: 16px; - position: relative; - padding-right: 7px; - font-family: Tahoma; - font-size: 9px; - text-align: center; - position: absolute; - bottom: 6px; - left: 82px; - margin: 0; - } - - .slider16mediaDisabled { - background-position: right -16px; - } - - .slider16media .left { - background: url("images/bar16x_left.png") no-repeat top left; - height: 16px; - overflow: hidden; - margin: 0; - } - - .slider16mediaDisabled .left { - background-position: left -16px; - } - - .slider16media .grabber { - background: url("images/rslider16x.png") no-repeat top right; - width: 20px; - height: 16px; - overflow: hidden; - position: absolute; - margin: 0; - } - - .slider16mediaDisabled .grabber { - background-position: left -16px; - margin-left: 7px; - cursor: normal; - } - - .slider16media .sldprogress { - background: #ddd; - display: block; - overflow: hidden; - height: 4px; - margin-left: 6px; - margin-top: 6px; - z-index: 0; - } - ]]></j:style> - <j:presentation> - <j:main slider="div[1]" container="." progress="div[2]" status2="div[2]/text()" markers="." direction="horizontal"> - <div class="slider16media"> - <div class="grabber"> </div> - <div class="left"> </div> - </div> - </j:main> - <progress> - <span class="sldprogress"> </span> - </progress> - <marker> - <u> </u> - </marker> - </j:presentation> -</j:slider> -<j:button name="buttonmedia"> - <j:style><![CDATA[ - .buttonmedia { - color: #4b4b4b; - font-family: Tahoma; - font-size: 8pt; - height: 21px; - width: 34px; - overflow: hidden; - cursor: default; - background: url(images/mediabtn2.png) no-repeat 0 -42px; - position: absolute; - bottom: 3px; - left: 3px; - margin: 0; - } - - .buttonmediaOver { - background-position: 0 -21px; - } - - .buttonmediaDisabled { - background-position: 0 -42px; - } - - .buttonmediaDown { - background-position: 0 0px; - } - - .buttonmedia span { - display: block; - background: no-repeat 0 0; - width: 11px; - height: 10px; - margin: 4px auto 0 11px; - } - ]]></j:style> - <j:presentation> - <j:main background="span" icon="span"> - <div class="buttonmedia"> - <span> </span> - </div> - </j:main> - </j:presentation> -</j:button> -<j:video name="video"> - <j:style><![CDATA[ - .video { - line-height:300px; - margin:0; - padding:0; - text-align:center; - vertical-align:middle; - overflow : hidden; - background : #FAFBFC; - color : white; - font-size : 8pt; - font-family : Tahoma; - } - - .video #qt_event_source{ - position : absolute; - left : 0; - top : 0; - } - ]]></j:style> - - <j:presentation> - <j:main container="."> - <div class="video"> </div> - </j:main> - </j:presentation> -</j:video> - - -<j:statusbar name="status"> - <j:style><![CDATA[ - .statuscontainer{ - margin: 8px 4px 0 0; - padding: 4px 0 0 8px; - width: 50px; - height: 50px; - float: left; - } - - .statuscontainer span{ - font-family: MS Sans Serif; - font-size: 8pt; - float: left; - margin-left: 4px; - cursor: default; - padding-right: 2px; - text-align: center; - width: 50px; - margin-top: 5px; - } - - .statuscontainerFocus span{ - margin: 4px 0 0 3px; - padding-right: 1px; - border: 1px dotted gray; - } - - .scheckbox{ - width: 32px; - height: 32px; - overflow: hidden; - margin: 0 3px 0 13px; - - background: url(icons/icoOff.gif) no-repeat 50% 50%; - } - - .statuscontainerDown .scheckbox{ - } - - .statuscontainerChecked .scheckbox{ - background: url(icons/icoOn.gif) no-repeat 50% 50%; - } - ]]></j:style> - - <j:presentation> - <j:main label="span/text()"> - <div class='statuscontainer'> - <div class='scheckbox'> </div> - <span>-</span> - </div> - </j:main> - </j:presentation> -</j:statusbar> -<j:palette name="colorpicker"> - <j:style><![CDATA[ - ]]></j:style> - - <j:presentation> - <j:main viewer="blockquote" standard="div[1]" custom="div[2]"> - <div class='palette'> - <blockquote></blockquote> - <div class='standard'></div> - <div class='custom'></div> - </div> - </j:main> - <j:item background="."> - <span></span> - </j:item> - </j:presentation> -</j:palette> -<j:datagrid name="datagrid"> - <j:style><![CDATA[ - .datagrid{ - position: relative; - border: 1px solid #c3c3c3; - background-color: white; - cursor: default; - - font-family: Tahoma; - font-size: 8pt; - - padding: 21px 0 0 0; - } - - .datagrid .headings{ - position : relative; - top : 0; - left : 0; - height : 17px; - z-index : 10; - padding-left : 5px; - background-color : #e6e6e6; - margin : -21px 17px 0 0; - border : 1px solid white; - border-left : 0; - border-right : 0px solid white; - white-space : nowrap; - } - .noscrollbar .headings { - margin : -21px 1px 0 0; - } - .noscrollbar .datagrid{ - background : transparant; - } - - .datagrid .headings div{ - display : inline-block; - height : 15px; - - border-left : 1px solid white; - margin-right : -3px; - margin-left : -5px; - padding : 1px 3px 1px 3px; - - background : #e6e6e6 no-repeat 0 50%; - overflow : hidden; - text-overflow : ellipsis; - } - - .datagrid .headings div.hover{ - background-color: #DDD; - } - - .datagrid .headings div.down, .datagrid .headings div.drag{ - color: white; - background-color: #25a8e7; - } - - .datagrid .headings div.drag{ - border : 1px solid white; - } - - .datagrid .headings div.ascending{ - background-image : url(images/sort_asc.gif); - background-repeat : no-repeat; - background-position : right 6px; - } - - .datagrid .headings div.descending{ - background-image : url(images/sort_desc.gif); - background-repeat : no-repeat; - background-position : right 6px; - } - - .datagrid .records{ - overflow-x: hidden; - overflow-y: scroll; - height : 100%; - padding : 18px 0 0 0; - position : relative; - top : -19px; - border : 1px solid white; - border-width : 1px 1px 0 0; - white-space : nowrap; - } - - .noscrollbar .records{ - overflow-y : hidden; - } - - .datagrid .records div span{ - display : inline-block; - - margin-right : -3px; - margin-left : -5px; - padding : 2px 3px 2px 4px; - height : 15px; - overflow : hidden; - background : white no-repeat 0 50%; - text-overflow : ellipsis; - white-space : nowrap; - } - - .noscrollbar .datagrid .records div span{ - background-color : transparent; - } - - .datagrid .records div{ - height : 19px; - padding-left : 5px; - } - - .datagridFocus .records .indicate span{ - border: 1px dotted #BBB; - border-width : 1px 0 1px 0; - padding : 1px 3px 1px 4px; - color : #4b4b4b; - height : 15px; - } - - .datagridFocus .records div span{ - } - - .datagrid .records .selected, .datagrid .records .selected span{ - background-color: #f0f0f0; - } - .datagridFocus .records .selected, .datagridFocus .records .selected span{ - color: white; - background-color: #25a8e7; - } - - .datagrid .move_pointer{ - height : 100px; - width : 2px; - position : absolute; - top : 0; - margin : -10px 0 0 -4px; - width : 9px; - height : 38px; - background : url(images/column_picker.gif) no-repeat 0 0; - overflow : hidden; - z-index : 1000; - } - - .datagrid .size_pointer{ - border : 1px dotted gray; - border-width : 0 1px 0 1px; - height : 100%; - position : absolute; - top : 0px; - z-index : 1000; - cursor : w-resize; - } - - .datagrid .loading, .datagrid .empty, .datagrid .offline{ - font-weight : normal; - color : #aaa; - width : 200px; - position : absolute; - left : 50%; - padding : 5px; - margin-left : -100px; - text-align : center; - } - - .pointer{ - display : none; - } - - .dginfo{ - display : none; - overflow : hidden; - white-space : normal; - padding : 5px; - background-color : #f3f3f3; - margin-top : 3px; - margin-left : 6px; - position : relative; - left : -3px; - margin-bottom : 3px; - } - - .dginfo h3{ - margin : 0 0 5px 0; - } - - .dginfo p{ - margin : 0; - } - - .datagrid .records .stdel, .datagridFocus .records .stdel, - .datagrid .records .stdel span, .datagridFocus .records .stdel span{ - color : #ccc; - } - - .dragdg{ - border : 2px solid black; - width : 10px; - height : 5px; - } - - .datagrid .records .dragInsert{ - border-top : 2px solid gray; - height : 17px; - } - - .datagrid .records .dragInsert span{ - padding-top : 0px; - margin-bottom : 0; - background-position : 0 0; - } - ]]></j:style> - <j:style condition="jpf.isIE"><![CDATA[ - .datagrid .headings div{ - float : left; - } - - .datagrid .records div span{ - float : left; - } - ]]></j:style> - <j:style condition="jpf.isGecko && !jpf.isGecko3"><![CDATA[ - .datagrid .headings{ - padding-top : 2px; - height : 15px; - } - - .datagrid .headings div{ - display : -moz-inline-box; - overflow : visible; - position : relative; - } - - .datagrid .records{ - } - - .datagrid .records div span{ - display : -moz-inline-box; - overflow : visible; - position : relative; - } - ]]></j:style> - - <j:presentation> - <j:main - head = "div[1]" - body = "div[3]" - pointer = "div[2]" - - widthdiff = "9" - iframe2 = "true" - > - <div class="datagrid"> - <div class='headings'> - - </div> - <div class='pointer'> </div> - <div class='records'> </div> - </div> - </j:main> - - <j:headitem class="." caption="text()"> - <div>-<span></span></div> - </j:headitem> - - <j:rowheaditem class="." caption="text()"> - <span>-</span> - </j:rowheaditem> - - <j:row class="." container="."> - <div /> - </j:row> - - <j:dragindicator> - <div class='dragdg'> </div> - </j:dragindicator> - - <j:cell caption="."><span>-</span></j:cell> - - <j:container container="."> - <div class="dginfo">-</div> - </j:container> - - <j:loading> - <div class="loading"><span></span><label>Loading...</label></div> - </j:loading> - - <j:empty caption="."> - <div class="empty"> </div> - </j:empty> - </j:presentation> -</j:datagrid> -<j:datagrid name="spreadsheet"> - <j:style><![CDATA[ - .spreadsheet{ - border: 1px solid #c3c3c3; - background-color: white; - cursor: default; - - font-family: Tahoma; - font-size: 11px; - - padding: 0 0 0 0; - } - div.spreadsheet{ - position : relative; - } - - /*IE6 if all else fails .fixed { - overflow : auto; - }*/ - - .spreadsheet .headings{ - position : relative; - top : 0; - left : 0; - height : 18px; - z-index : 10; - background-color : #e6e6e6; - margin : 0 16px 0 0; - white-space : nowrap; - } - - .fixed .headings{ - overflow : hidden; - z-index : 100; - } - - .spreadsheet .headings span{ - display : inline-block; - height : 15px; - } - - .spreadsheet .headings span b{ - font-weight : normal; - padding : 1px 0 1px 0; - border : 1px solid #c3c3c3; - border-width : 0 1px 1px 1px; - - background : #e6e6e6 no-repeat 0 50%; - overflow : hidden; - text-overflow : ellipsis; - - padding : 1px 1px 1px 3px; - display : block; - height : 15px; - margin-left : -1px; - text-align : center; - } - - .spreadsheet .headings span.hover{ - } - - .spreadsheet .headings span.down b, .spreadsheet .headings span.drag b{ - color: white; - background-color: #25a8e7; - } - - .spreadsheet .headings span.ascending b{ - background-image : url(images/sort_asc_n.gif); - background-repeat : no-repeat; - background-position : right 6px; - } - - .spreadsheet .headings span.descending b{ - background-image : url(images/sort_desc_n.gif); - background-repeat : no-repeat; - background-position : right 6px; - } - - .spreadsheet .headings span.drag{ - border : 1px solid white; - } - - /* Disabled this one when using an iframe - .spreadsheet .records{ - overflow-x: hidden; - overflow-y: scroll; - height : 100%; - position : relative; - padding : 0; - white-space : nowrap; - }*/ - - .virtual .records{ - overflow : hidden; - } - - .fixed .records{ - overflow-x: auto; - } - - .spreadsheet body.records{ - overflow : visible; - margin : 0; - border : 0; - padding : 17px 0 0 0; - white-space : nowrap; - cursor : url(images/excel.cur); - } - - .spreadsheet iframe{ - position : absolute; - left : 0; - top : 0; - width : 100%; - height : 100%; - } - - html.spreadsheet{ - overflow-x: hidden; - overflow-y: scroll; - border : 0; - margin : 0; - } - - html.fixed{ - overflow-x : auto; - } - - .spreadsheet .records div b{ - font-weight : normal; - padding : 2px 1px 2px 3px; - display : block; - border : 1px solid #e6e6e6; - overflow : hidden; - height : 13px; - margin-left : -1px; - } - - .spreadsheet .records div span{ - display : inline-block; - - height : 17px; - background : white no-repeat 0 50%; - text-overflow : ellipsis; - white-space : nowrap; - } - - .spreadsheet .records div{ - height : 18px; - } - - .spreadsheet .records .cellselected b{ - border : 3px solid #f3f3f3; - margin : -1px -1px 0 -2px; - padding : 1px 0px 1px 2px; - position : relative; - z-index : 10; - /*background : #f3f3f3;*/ - } - - .spreadsheetFocus .records .cellselected b{ - border : 3px solid black;/*#25a8e7;*/ - background : white; - } - - /*.spreadsheet .records .cellselected{ - background-color: #f0f0f0; - color: #4b4b4b; - } - .spreadsheetFocus .records .cellselected{ - color: white; - background-color: #25a8e7; - }*/ - - .spreadsheet .move_pointer{ - height : 100px; - width : 2px; - position : absolute; - top : 0; - margin : -10px 0 0 -4px; - width : 9px; - height : 38px; - background : url(images/column_picker.gif) no-repeat 0 0; - overflow : hidden; - z-index : 1000; - } - - .spreadsheet .size_pointer{ - border : 1px dotted gray; - border-width : 0 1px 0 1px; - height : 100%; - position : absolute; - top : 0px; - z-index : 1000; - cursor : w-resize; - } - - .pointer{ - display : none; - } - - .spreadsheet #txt_rename{ - font-family: Tahoma; - font-size: 8pt; - word-break: keep-all; - overflow: hidden; - cursor: text; - background-color: white; - - height : 14px; - border : 2px solid black; - margin : -1px -1px 0 -2px; - padding : 2px 1px 1px 3px; - position : relative; - z-index : 10; - } - - .spreadsheet input#txt_rename{ - outline : none; - padding : 2px 0 1px 2px; - } - ]]></j:style> - <j:style condition="jpf.isIE"><![CDATA[ - .spreadsheet .headings div{ - } - - .spreadsheet .records div span{ - } - ]]></j:style> - <j:style condition="jpf.isIE6"><![CDATA[ - .spreadsheet{ - overflow-x : hidden; - padding-right : 16px; - } - - .fixed .headings{ - width : 100%; - } - - .fixed .records{ - width : 100%; - padding-left : -16px; - text-index : expression(this.style.paddingLeft='16px'); - } - - .fixed .records div{ - margin-left : -16px; - } - - .fixed .records div span{ - overflow : hidden; - height : 19px; - margin-top : -1px; - } - - .spreadsheet body.records{ - padding : 18px 0 0 0; - } - - .fixed .records div span b{ - width : expression(this.parentNode.offsetWidth - 5); - } - - .spreadsheet iframe{ - height : expression(this.parentNode.parentNode.offsetHeight - 2); - width : expression(this.parentNode.parentNode.offsetWidth - 2); - } - - html.spreadsheet body.records { - margin-right : -20px; - } - - .spreadsheet .size_pointer{ - height : expression(this.parentNode.offsetHeight - 2); - } - ]]></j:style> - <j:style condition="jpf.isGecko && !jpf.isGecko3"><![CDATA[ - .spreadsheet .headings{ - height : 18px; - } - - .spreadsheet .headings span{ - height : 18px; - } - - .spreadsheet .records div span{ - height : 18px; - } - - .spreadsheet .records div{ - height : 18px; - } - - .spreadsheet .records div span b{ - border-width : 0 1px 1px 0; - } - - .spreadsheet .headings span{ - display : -moz-inline-grid; - overflow : visible; - position : relative; - } - - .spreadsheet .records{ - } - - .spreadsheet .records div span{ - display : -moz-inline-grid; - overflow : visible; - position : relative; - } - - .spreadsheet .records .cellselected b{ - margin : -1px -1px 0 -2px; - padding : 0px 0px 1px 1px; - } - - .spreadsheet input#txt_rename{ - position : absolute; - padding : 1px 1px 0 2px; - } - ]]></j:style> - <j:style condition="jpf.isGecko3"> - .spreadsheet .records .cellselected b{ - margin : -1px -1px 0 -2px; - padding : 0 0 1px 2px; - } - - .spreadsheet input#txt_rename{ - position : relative; - top : -6px; - padding-top : 1px; - } - </j:style> - - <j:presentation> - <j:main - interaction = "p" - head = "div[1]" - rowhead = "div[3]" - body = "div[4]" - pointer = "div[2]" - - widthdiff = "2" - defaultwidth = "70" - scalerename = "true" - iframe = "true" - > - <div class="spreadsheet"> - <div class='headings'> - - </div> - <div class='pointer'> </div> - <div class='row_headers'> </div> - <div class='records'> </div> - </div> - </j:main> - - <j:headitem class="." caption="b/text()"> - <span><b>-</b></span> - </j:headitem> - - <j:rowheaditem class="." caption="text()"> - <span>-</span> - </j:rowheaditem> - - <j:row class="." container="."> - <div /> - </j:row> - - <j:dragindicator> - <div class='dragdg'> </div> - </j:dragindicator> - - <j:cell caption="b"><span><b> </b></span></j:cell> - - <j:container container="."> - <div class="dginfo">-</div> - </j:container> - - <j:loading> - <div class="loading"><span></span><label>Loading...</label></div> - </j:loading> - - <j:empty caption="."> - <div class="empty"> </div> - </j:empty> - </j:presentation> -</j:datagrid> -<j:dropdown name="dropdowneditor"> - <j:style><![CDATA[ - .ddedit{ - background-color: white; - height: 100px; - font-size: 1px; - width: 148px; - border: 2px inset; - border: 1px solid midnightblue; - } - - #override .ddedit .ddeditbtn{ - background: #D4D0C8 url(images/arrow_down.gif) no-repeat 50% 50%; - width: 13px; - height: 12px; - position: absolute; - right: 0; - left: expression(this.parentNode.offsetWidth - 18); - border: 2px outset; - overflow: hidden; - - -moz-border-top-colors: #D4D0C8 #FFFFFF; - -moz-border-left-colors: #D4D0C8 #FFFFFF; - -moz-border-bottom-colors: black gray; - -moz-border-right-colors: black gray; - } - - .ddeditDisabled .ddeditbtn{ - background-image: url(images/dddisabled.gif); - } - - #override .ddeditdown .ddeditbtn{ - border: 2px inset; - - -moz-border-bottom-colors: #FFFFFF #D4D0C8; - -moz-border-right-colors: #FFFFFF #D4D0C8; - -moz-border-top-colors: gray black; - -moz-border-left-colors: gray black; - } - - #override .ddedit .ddeditlabel{ - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - padding: 1px 1px 0 3px; - width: 98%; - height: 14px; - font-size: 8pt; - font-family: Tahoma; - cursor: default; - color: black; - } - - #override .ddeditFocus .ddeditlabel{ - background-color: #EEEEEE; - } - - .ddeditcontainer{ - border: 1px solid black; - background: white; - height: 50px; - overflow: hidden; - font-size: 8pt; - display: none; - } - - .ddeditcontainer span{ - display: block; - height: 15px; - padding: 2px 3px 2px 6px; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - background-color: white; - - font-size: 8pt; - font-family: Tahoma; - color: black; - cursor: default; - } - - .ddeditcontainer span.hover{ - background-color: #003265; - color: white; - } - - .ddeditcontainer .selected{ - color: black; - background-color: #CFCFCF; - } - - .ddeditError{ - border: 2px inset red; - } - - .ddedit.loading{ - /*border: 2px inset gray;*/ - } - - .ddedit.loaded{ - /*border: 2px inset green;*/ - } - - .ddedit.loading .ddeditbtn{ - border: 0; - width: 15px; - height: 16px; - background: white url(images/loadingspin.gif) no-repeat 0px 1px; - } - - ]]></j:style> - - <j:presentation> - <j:main label="div[2]/text()" button="."> - <div class='ddedit'> - <div class='ddeditbtn'> </div> - <div class='ddeditlabel'>-</div> - </div> - </j:main> - <j:container contents="."> - <div class='ddeditcontainer'> </div> - </j:container> - <j:item - class = "." - caption = "text()" - select = "." - > - <span>-</span> - </j:item> - <j:empty caption="."> - <div class="empty">-</div> - </j:empty> - </j:presentation> -</j:dropdown> -<j:picture name="picture"> - <j:style><![CDATA[ - .image{ - margin-bottom: 10px; - background: white no-repeat 50% 50%; - border: 1px solid gray; - } - - .imageDisabled{ - background-position: 1000px 1000px; - } - - ]]></j:style> - - <j:presentation> - <j:main image="."> - <div class="image"> - </div> - </j:main> - </j:presentation> -</j:picture> -<j:picture name="logo"> - <j:style><![CDATA[ - .image{ - margin-bottom: 10px; - } - - .imageDisabled{ - } - - ]]></j:style> - - <j:presentation> - <j:main image="@src"> - <img src="" /> - </j:main> - </j:presentation> -</j:picture> -<j:label name="errorlabel"> - <j:style><![CDATA[ - .errorLabel { - color:#F00; - width:400px; - height:auto; - white-space:normal; - overflow:hidden; - text-transform:uppercase; - font:bold 10pt/21px Arial; - letter-spacing:-1px; - } - .errorLabel.disabled{ - } - - .alert{ - font-size: 8pt; - font-family: MS Sans Serif; - text-align: center; - } - ]]></j:style> - - <j:presentation> - <j:main caption="text()" for="@for"> - <div class="errorLabel">-</div> - </j:main> - </j:presentation> -</j:label> -<j:label name="labelnormal"> - <j:style><![CDATA[ - .lbln{ - font-size: 8pt; - font-family: Tahoma, Arial; - height: 12px; - padding: 4px; - overflow: hidden; - margin: 0 0 0 6px; - } - ]]></j:style> - - <j:presentation> - <j:main caption="." for="@for"> - <div class="lbln"> </div> - </j:main> - </j:presentation> -</j:label> -<j:label name="labeldesc"> - <!-- - Classes: - - disabled - --> - - <!-- why does renaming style2 to style cause IE to crash? --> - <j:style><![CDATA[ - .labeldesc{ - font-size: 8pt; - font-family: MS Sans Serif; - height: 50px; - padding: 4px; - overflow: hidden; - width: 90%; - text-align: center; - - position: absolute; - top: 50%; - margin-top: -20px; - margin-left: 2%; - } - - .label.disabled{ - } - - ]]></j:style> - - <j:presentation> - <j:main caption="." for="@for"> - <div class="labeldesc">-</div> - </j:main> - </j:presentation> -</j:label> -<j:list name="listmenu"> - <j:style><![CDATA[ - .listmenu{ - width: 200px; - height: 500px; - overflow: auto; - position: relative; - border: 1px solid gray; - background-color: white; - cursor: default; - } - - .listmenu{ - font-family: Tahoma; - font-size: 8pt; - font-weight: bold; - } - - .listmenu DIV{ - padding: 0; - height: 15px; - padding: 8px; - border-bottom: 1px solid gray; - background: url(images/listbg.gif) repeat-x; - } - - BODY .listmenu .norights{ - background: #CCCCCC; - color: gray; - } - - .listmenu .selected{ - background: #d4d5d8; - } - - .listmenu .empty{ - text-align: center; - padding: 3px 0 0 0; - } - ]]></j:style> - - <j:presentation> - <j:main container="."> - <div class='listmenu'> - </div> - </j:main> - <j:item - class = "." - caption = "." - select = "." - > - <div>-</div> - </j:item> - <j:dragindicator> - <div class='draglist'><span><u>-</u></span></div> - </j:dragindicator> - <j:loading> - <div class="loading">Loading...</div> - </j:loading> - <j:empty caption="."> - <div class="empty">-</div> - </j:empty> - </j:presentation> -</j:list> -<j:list name="layoutlist"> - <j:style><![CDATA[ - .layoutlist{ - width: 200px; - height: 500px; - overflow: auto; - position: relative; - border: 1px solid white; - border-color: gray white white gray; - background-color: white; - cursor: default; - } - - #override .layoutlistFocus blockquote.selected{ - border: 1px solid #CCC; - background-color: #EEE; - } - - .layoutlist blockquote.selected{ - border: 1px solid #DDD; - background-color: #F2F2F2; - } - - .layoutlist, .draglayoutlist{ - font-family: Tahoma; - font-size: 8pt; - } - - .layoutlist blockquote, .draglayoutlist{ - padding: 0; - height: 18px; - width: 50px; - height: 50px; - border: 1px solid #EEE; - margin: 5px; - background: white no-repeat 50% 30%; - position: relative; - color: black; - text-align: center; - float: left; - } - - .layoutlist SPAN, .draglayoutlist SPAN{ - position: absolute; - bottom: 1px; - left: 1px; - width: 50px; - height: 16px; - padding-top: 32px; - overflow: hidden; - } - - .layoutlist U, .draglayoutlist U{ - text-decoration: none; - cursor: default; - display: block; - padding: 2px 4px 2px 2px; - text-decoration: none; - white-space: nowrap; - } - - - /*.layoutlist .selected U{ - background-color: #CCCCCC; - color: black; - } - .layoutlistFocus .selected U, .draglayoutlist U{ - color: white; - background-color: midnightblue; - } - .layoutlist .indicate U{ - border: 1px dotted gray; - padding: 1px 3px 1px 1px; - }*/ - - .layoutlist #txt_rename{ - border: 0; - padding: 0 0 0 1px; - font-family: Tahoma; - font-size: 8pt; - color: black; - word-break: keep-all; - overflow: hidden; - margin : 1px 0 0 -1px; - cursor: text; - height: 14px; - width: 49px; - background-color: white; - border-top: 1px solid #DDD; - } - - .layoutlist .empty{ - text-align: center; - padding: 3px 0 0 0; - } - ]]></j:style> - - <j:presentation> - <j:main container="."> - <div class='layoutlist'> - </div> - </j:main> - <j:item - class = "." - caption = "span/u/node()" - icon = "." - select = "span" - > - <blockquote><span><u>-</u></span></blockquote> - </j:item> - <j:dragindicator> - <div class='draglayoutlist'><span><u>-</u></span></div> - </j:dragindicator> - <j:loading> - <div class="loading">Loading...</div> - </j:loading> - <j:empty caption="."> - <div class="empty">-</div> - </j:empty> - </j:presentation> -</j:list> -<j:list name="joinlist"> - <j:style><![CDATA[ - .joinlist{ - border: 0; - border-top: 1px solid #c2dff5; - background-color: white; - width: 200px; - height: 500px; - overflow: auto; - - font-family: Tahoma; - font-size: 8pt; - position: relative; - padding: 2px 0 0 2px; - } - - .joinlist INPUT{ - float: left; - margin: -1px 0 0 0; - display: none; - } - - .joinlist DIV{ - padding: 0; - height: 18px; - width: 175px; - overflow: hidden; - float: left; - } - - .joinlist SPAN{ - padding: 0 0 0 20px; - background: no-repeat 1px center; - height: 16px; - float: left; - } - - .joinlist A{ - text-decoration: none; - color: black; - cursor: default; - display: block; - padding: 2px 4px 2px 2px; - white-space: nowrap; - text-overflow: ellipsis; - } - - .joinlist .selected A{ - background-color: #CCCCCC; - color: black; - } - .joinlist.joinlistFocus .selected A{ - color: white; - background-color: midnightblue; - } - .joinlist.joinlistFocus .selected A:hover{color: white;} - - .joinlist #txt_rename{ - border: 1px solid black; - padding: 1px 15px 1px 1px; - font-family: Tahoma; - font-size: 8pt; - color: black; - word-break: keep-all; - overflow: visible; - margin-top : 0px; - cursor: text; - } - ]]></j:style> - - <j:presentation> - <j:main container="."> - <div class='joinlist'> - </div> - </j:main> - <j:item - class = "." - caption = "span/a/text()" - icon = "span" - select = "span/a" - > - <div><span><a href='#' onclick='return false'>-</a></span></div> - </j:item> - <j:loading> - <div class="loading">Loading...</div> - </j:loading> - </j:presentation> -</j:list> -<j:list name="listicons"> - <j:style><![CDATA[ - .listicons{ - border: 1px solid white; - border-color: gray white white gray; - background-color: white; - width: 450px; - height: 500px; - overflow: auto; - } - .listicons, .draglisticon{ - font-family: Tahoma; - font-size: 8pt; - } - - .listicons DIV, .draglisticon{ - padding: 0; - float: left; - display: inline; - margin-bottom: 10px; - } - - .listicons BLOCKQUOTE, .draglisticon BLOCKQUOTE{ - width: 70px; - height: 32px; - margin: 2px 2px 4px 2px; - - background: url(icons/icoMailFolder.gif) no-repeat 50% 50%; - } - .listicons .selected BLOCKQUOTE, .draglisticon BLOCKQUOTE{ - } - .listicons.listiconsfocus .selected BLOCKQUOTE{ - } - - .listicons INPUT{ - float: left; - margin: -1px 0 0 0; - display: none; - } - - .listicons LABEL, .draglisticon LABEL{ - padding: 0 0 0 0; - margin: 0 2px 0 0px; - width: 76px; - height: 29px; - overflow: hidden; - - display: block; - text-align: center; - position: relative; - } - - .listicons SPAN, .draglisticon SPAN{ - text-decoration: none; - color: black; - cursor: default; - padding: 0px 3px 2px 3px; - margin: 1px auto 0 auto; - text-align: center; - } - .listicons LABEL>SPAN, .draglisticon LABEL>SPAN{ - float: left; - } - * html .listicons SPAN, .draglisticon SPAN{ - display: block; - position: absolute; - left: 50%; - margin-left: expression(-0.5 * this.offsetWidth); - } - - .listicons .selected SPAN{ - background-color: #CCCCCC; - color: black; - /*margin: 0 auto 0 auto; FF? */ - } - .listicons.listiconsfocus .selected SPAN, .draglisticon SPAN{ - color: white; - background-color: midnightblue; - } - - .listicons #txt_rename{ - border: 1px solid black; - float: none; - padding: 1px 5px 1px 1px; - font-family: Tahoma; - font-size: 8pt; - color: black; - word-break: keep-all; - overflow: visible; - margin : 0px; - cursor: text; - } - ]]></j:style> - - <j:presentation> - <j:main container="."> - <div class='listicons'> - </div> - </j:main> - <j:item - class = "." - caption = "label/span/text()" - image = "blockquote" - select = "." - > - <div><blockquote></blockquote><label><span>-</span></label></div> - </j:item> - <j:dragindicator> - <div class='draglisticon'><blockquote></blockquote><label><span>-</span></label></div> - </j:dragindicator> - <j:loading> - <div class="loading">Loading...</div> - </j:loading> - <j:empty caption="."> - <div class="empty">-</div> - </j:empty> - </j:presentation> -</j:list> -<j:list name="listshop"> - <j:style><![CDATA[ - .iconlist{ - border: 2px inset white !important; border: 2px inset; - background-color: white; - width: 492px; - height: 494px; - overflow: auto; - - padding: 3px 4px 3px 4px; - } - - .iconlist, .dragshop{ - font-family: Verdana; - font-size: 7.5pt; - } - - .iconlist DIV, .dragshop{ - padding: 0; - width: 116px; - height: 110px; - - float: left; - display: inline; - text-align: center; - padding: 3px 2px 3px 2px; - } - .iconlist DIV.hover{ - border: 1px solid #FFEFD1; - border-width: 3px 2px 3px 2px; - padding: 0; - } - .iconlist DIV.selected, .dragshop{ - border: 1px solid orange; - border-width: 3px 2px 3px 2px; - padding: 0; - } - - .iconlist BLOCKQUOTE, .dragshop BLOCKQUOTE{ - width: 80px; - height: 80px; - - margin: 0 auto 3px auto; - background: url(icons/icoMailFolder.gif) no-repeat 50% 50%; - } - .iconlist INPUT{ - float: left; - margin: -1px 0 0 0; - display: none; - } - - .iconlist LABEL, .dragshop LABEL{ - padding: 0 0 0 0; - margin: 0 2px 0 2px; - height: 16px; - width: 110px; - - display: block; - border: 1px solid red; - } - - .iconlist SPAN, .dragshop SPAN{ - text-decoration: none; - color: black; - cursor: default; - padding: 2px 4px 2px 2px; - display: block; - } - ]]></j:style> - - <j:presentation> - <j:main container="."> - <div class='iconlist'> - </div> - </j:main> - <j:item - class = "." - caption = "span/text()" - image = "blockquote" - select = "." - > - <div><blockquote></blockquote><span>-</span></div> - </j:item> - <j:dragindicator> - <div class='dragshop'><blockquote></blockquote><span>-</span></div> - </j:dragindicator> - <j:loading> - <div class="loading">Loading...</div> - </j:loading> - </j:presentation> -</j:list> -<j:list name="listsmileys"> - <j:style><![CDATA[ - .listsmileys{ - background: #d5e9f8 url(images/ddgradient.gif) repeat-x; - border: 1px solid white; - overflow: auto; - - font-family: Tahoma; - font-size: 8pt; - } - - .listsmileys a img{ - border: 0; - } - - .listsmileys A{ - padding: 0; - float: left; - display: inline; - - width: 23px; - height: 23px; - margin: 3px; - - border: 1px solid #c5d3ed; - cursor: default; - } - .listsmileys A:hover{ - border: 1px solid #778bb0; - } - - /*.listsmileys .selected, .listsmileys A:hover.selected{ - border: 1px solid midnightblue; - }*/ - ]]></j:style> - - <j:presentation> - <j:main container="."> - <div class='listsmileys'> - </div> - </j:main> - <j:item - class = "." - image = "img/@src" - select = "." - > - <a href='javascript:void(0);' onclick='return false'><img src='' /></a> - </j:item> - <j:loading> - <div class="loading">Loading...</div> - </j:loading> - </j:presentation> -</j:list> -<j:list name="listtab"> - <j:style><![CDATA[ - .listtab{ - width: 300px; - height: 100px; - padding-top: 21px; - padding-bottom: 4px; - overflow: hidden; - position: relative; - } - - .listtab .btncontainer{ - position: absolute; - top: 0; - z-index: 100; - padding-left: 2px; - } - - .listtab .btn{ - border-width: 2px 2px 0 2px; - border-style: outset; - border-color: white !important; border-color:; - display: block; - float: left; - padding: 3px 6px 2px 6px; - - font-family: MS Sans Serif; - font-size: 8pt; - background-color: #D4D0C8; - - margin: 2px 0 0 0; - - cursor: default; - position: relative; - z-index: 90; - } - - .listtab .selected{ - padding: 3px 8px 5px 8px; - margin: 0 -2px 0 -2px; - display: inline; - left: 0px; - z-index: 100; - } - - .listtab .firstcurbtn{ - margin: 0 -2px 0 0; - padding: 3px 8px 5px 6px; - } - - .listtab .tabpage{ - border-width: 2px; - border-style: outset; - border-color: white !important; border-color:; - display: block; - height: 100%; - position: relative; - } - - ]]></j:style> - - <j:presentation> - <j:main container="div"> - <div class='listtab'> - <div class='btncontainer'> - </div> - <div class='tabpage'> </div> - </div> - </j:main> - <j:item - class = "." - caption = "text()" - select = "." - > - <span class='btn'>-</span> - </j:item> - <j:loading> - <div class="loading">Loading...</div> - </j:loading> - <j:empty caption="."> - <div class="empty">-</div> - </j:empty> - </j:presentation> -</j:list> -<j:list name="listthin"> - <j:style><![CDATA[ - .listthin{ - border: 1px solid gray; - - background-color: white; - width: 200px; - height: 500px; - overflow: auto; - - font-family: Tahoma; - font-size: 8pt; - position: relative; - } - - .listthin INPUT{ - float: left; - margin: -1px 0 0 0; - display: none; - } - - .listthin DIV{ - padding: 0; - height: 18px; - } - - .listthin SPAN{ - padding: 0 0 0 20px; - background: url(icons/icoMailFolder.gif) no-repeat 1px center; - height: 16px; - float: left; - } - - .listthin A{ - text-decoration: none; - color: black; - cursor: default; - display: block; - padding: 2px 4px 2px 2px; - } - - .listthin .selected A{ - background-color: #CCCCCC; - color: black; - } - .listthin.listthinfocus .selected A{ - color: white; - background-color: midnightblue; - } - .listthin.listthinfocus .selected A:hover{color: white;} - - .listthin #txt_rename{ - border: 1px solid black; - padding: 1px 15px 1px 1px; - font-family: Tahoma; - font-size: 8pt; - color: black; - word-break: keep-all; - overflow: visible; - margin-top : 0px; - cursor: text; - } - - .listthin .empty{ - text-align: center; - padding: 3px 0 0 0; - } - ]]></j:style> - - <j:presentation> - <j:main container="."> - <div class='listthin'> - </div> - </j:main> - <j:item - class = "." - caption = "span/a/text()" - checkbox = "input" - icon = "span" - select = "." - > - <div><input type='checkbox' /><span><a href='#' onclick='return false'>-</a></span></div> - </j:item> - <j:loading> - <div class="loading">Loading...</div> - </j:loading> - <j:empty caption="."> - <div class="empty">-</div> - </j:empty> - </j:presentation> -</j:list> -<j:button name="luxebutton"> - <!-- - Classes: - - disabled - - focus - - - btnup - - btndown - - btnover - --> - - <j:style><![CDATA[ - .luxebutton{ - border: 1px solid #D4D0C8; - background-color: #D4D0C8; - padding: 3px; - color: black; - font-family: MS Sans Serif; - font-size: 8pt; - cursor: default; - text-align: center; - } - - .luxebutton.luxebuttonDisabled{color: gray;} - .luxebutton.luxebuttonDown{ - border: 1px solid white; - border-color: gray white white gray; - padding: 4px 2px 2px 4px; - } - .luxebutton.luxebuttonOver{ - border: 1px solid white; - border-color: white gray gray white; - } - - .luxebutton.bool.btnover{ - - } - - .luxebutton.bool.btndown{ - - } - - .helper{ - } - - .helper.active{ - display: none; - } - ]]></j:style> - - <j:presentation> - <j:main caption="text()" icon="."> - <div class='luxebutton'>-</div> - </j:main> - - <j:helper> - <div class='helper'></div> - </j:helper> - </j:presentation> -</j:button> - -<j:text name="messengerchat"> - <j:style><![CDATA[ - .chattabs{ - overflow: auto; - - font-family: Tahoma; - font-size: 8pt; - width: 100px; - height: 100px; - padding-left: 1px; - } - - .chattabs img{ - border: 0; - margin: 4px 0 0 5px; - border: 1px solid white; - width: 30px; - height: 30px; - } - - .chattabs div{ - padding: 0; - float: left; - position: relative; - display: inline; - - width: 54px; - height: 52px; - margin: 0 0 0 -1px; - - cursor: default; - - background: #d5e9f8 url(images/chattab.gif) no-repeat; - } - .chattabs div.selected, - .chattabs div.hover{background-position: -54px 0;} - - .chattabs span{ - display: none; - position: absolute; - left: 28px; - top: 4px; - width: 7px; - height: 7px; - overflow: hidden; - border: 1px solid white; - background: red; - } - - .chattabs dl{ - display: block; - margin: 0px 0 0 5px; - color: 007ad1; - width: 32px; - /*text-overflow: ellipsis;*/ - overflow: hidden; - white-space: nowrap; - } - - .chattabs strong{ - position: absolute; - left: 38px; - top: 39px; - display: block; - - background: url(images/indicator.gif) no-repeat -13px 0; - width: 13px; - height: 12px; - } - .chattabs strong.active{background-position: 0 0;} - - .chattabs u{ - position: absolute; - left: 42px; - top: 23px; - - display: block; - width: 7px; - height: 8px; - background: url(images/expand.gif) no-repeat; - cursor: pointer; - } - .chattabs u.hover{background-position: -7px 0;} - - .chattabs i{ - position: absolute; - left: 42px; - top: 5px; - - display: block; - width: 7px; - height: 7px; - background: url(images/x.gif) no-repeat; - cursor: pointer; - } - .chattabs i.hover{background-position: -7px 0;} - - .chattabs .first *{ - display: none; - } - .chattabs .first{ - background: url(images/emesstab.gif) no-repeat; - } - ]]></j:style> - - <j:presentation> - <j:main container="."> - <div class='chattabs'> - </div> - </j:main> - <j:item - class = "." - image = "img/@src" - icon = "span" - caption = "dl/text()" - select = "." - indicator = "strong" - maxbtn = "u" - closebtn = "i" - > - <div> - <img src='' /> - <span></span> - <i></i> - <u></u> - <strong></strong> - <dl>-</dl> - </div> - </j:item> - <j:loading> - <div class="loading">Loading...</div> - </j:loading> - </j:presentation> -</j:text> -<j:pages name="pages"> - <j:style><![CDATA[ - .pages{ - width: 100px; - height: 100px; - } - - .pages .page{ - display: none; - - width: 100%; - height: 100%; - } - - .pages .curpage{ - display: block; - } - ]]></j:style> - - <j:presentation> - <j:main pages="."> - <div class='pages'> - </div> - </j:main> - <j:page container="."> - <div class='page'></div> - </j:page> - </j:presentation> -</j:pages> -<j:palette name="palette"> - <j:style><![CDATA[ - .palette{ - width: 143px; - height: 35px; - border: 1px solid black; - overflow: hidden; - background-color: white; - position: relative; - } - - .palette blockquote{ - border: 1px solid white; - background-color: red; - width: 33px; - height: 33px; - margin: 0; - } - - .palette .standard{ - width: 108px; - height: 22px; - border-left: 1px solid black; - position: absolute; - left: 35px; - top: 0; - } - - .palette .custom{ - border-left: 1px solid black; - height: 11px; - width: 108px; - padding-top: 2px; - position: absolute; - left: 35px; - top: 22px; - } - - .palette .custom span{ - border-width: 1px 1px 0 0; - } - - .palette span{ - border: 1px solid black; - border-width: 0 1px 1px 0; - width: 11px; - height: 10px; - background: white; - float: left; - overflow: hidden; - } - ]]></j:style> - - <j:presentation> - <j:main viewer="blockquote" standard="div[1]" custom="div[2]"> - <div class='palette'> - <blockquote></blockquote> - <div class='standard'></div> - <div class='custom'></div> - </div> - </j:main> - <j:item background="."> - <span></span> - </j:item> - </j:presentation> -</j:palette> -<j:statusbar name="statusbar2005"> - <!-- - Classes: - - disabled - - focus - - - btnup - - btndown - - btnover - - - next - - previous - - finish - --> - - <j:style><![CDATA[ - .sb2005{ - width: 100px; - height: 100px; - overflow: hidden; - padding: 1px 0 0 0; - background: #D4D0C8; - } - - .sb2005 .panel{ - border: 1px solid #e1ded9; - padding: 2px 0 0 23px; - - font-size: 8pt; - font-family: MS Sans Serif; - margin-right: 2px; - background: no-repeat 3px 1px; - float: right; - height: 16px; - } - - .sb2005 .first{ - float: none; - } - - .sb2005 .last{ - margin: 0; - } - - .sb2005 .rest{ - float: none; - } - - .sb2005 .corner{ - width: 13px; - height: 13px; - position: absolute; - right: -1px; - top: 9px; - display: block; - } - ]]></j:style> - - <j:presentation> - <j:main container="." corner="span"> - <div class='sb2005'><span class='corner'></span></div> - </j:main> - <j:panel icon="." caption="text()"> - <div class='panel'>-</div> - </j:panel> - </j:presentation> -</j:statusbar> - -<j:tab name="lowtab"> - <j:style><![CDATA[ - .lowtab{ - position: relative; - color: #4B4B4B; - font-family: Tahoma; - font-size: 8pt; - padding: 0 0 26px 0; - } - - .lowtab .btncontainer{ - position : absolute; - bottom: -14px; - /* _bottom: 1px;*/ - left: 10px; - cursor: default; - z-index : 1; - } - - .lowtab .btncontainer div{ - cursor: default; - display: block; - float: left; - margin: 0 3px 0 0; - /*_margin: 0 0 0 0;*/ - padding: 0; - background: url(images/tab_but_bottomleft.png) no-repeat 0 0; - height: 20px; - - } - - .lowtab .btncontainer .curbtn{ - background-position: 0 -20px; - height: 25px; - color: #327fbd; - position: relative; - } - - - .lowtab .btncontainer div div { - margin: 0 -4px 0 0; - /*_margin: 0 0 0 0;*/ - padding : 2px 8px 0 8px; - height: 17px; - border-top: 1px solid #c3c3c3; - background: url(images/tab_but_bottomright.png) no-repeat right -1px; - } - - .lowtab .btncontainer .curbtn div { - padding-top: 6px; - height: 19px; - border: 0; - background: url(images/tab_but_bottomright.png) no-repeat right -20px; - } - - .lowtab .page{ - background-color:#FAFBFC ; - border-left: 1px solid #C3C3C3; - border-right: 1px solid #C3C3C3; - border-top: 1px solid #D7D7DF; - border-bottom: 1px solid #D7D7DF; - clear:both; - display:none; - height:100%; - overflow:hidden; - padding:7px; - position : relative; - } - - .lowtab .page.curpage{ - display: block; - } - - ]]></j:style> - <j:style condition="jpf.isIE6"> - .lowtab .btncontainer{ - bottom: 1px; - } - .lowtab .btncontainer div{ - margin: 0 0 0 0; - } - .lowtab .btncontainer div div { - margin: 0 0 0 0; - } - </j:style> - <j:presentation> - <j:main pages="." buttons="div"> - <div class='lowtab'> - <div class='btncontainer'> - </div> - </div> - </j:main> - <j:button caption="div/span/text()"> - <div class="btn"><div><span>-</span></div></div> - </j:button> - <j:page container="."> - <div class='page'></div> - </j:page> - </j:presentation> -</j:tab> -<j:tab name="tablowms"> - <j:style><![CDATA[ - .lowtabms{ - width: 300px; - height: 100px; - padding-bottom: 24px; - overflow: hidden; - position: relative; - background: #808080; - } - - .lowtabms .btncontainer{ - position: absolute; - bottom: 0; - padding: 0 0 0 5px !important; padding: 0 0 3px 5px; - background: url(images/tabdiv.gif) no-repeat 5px 4px; - z-index: 100; - } - * html .lowtabms .btncontainer{ - bottom: expression(this.parentNode.offsetHeight%2==1 ? 0: 1); - } - - .lowtabms .btn{ - float: left; - display: inline; - padding: 4px 8px 4px 8px; - - font-family: MS Sans Serif; - font-size: 8pt; - color: white; - - cursor: default; - position: relative; - z-index: 90; - background: url(images/tabdiv.gif) no-repeat right 4px; - } - - .lowtabms .curbtn{ - border-width: 0 1px 1px 1px; - border-style: solid; - border-color: black black black white; - background: #D4D0C8; - color: black; - - margin: 2px 0 0 0; - - padding: 3px 8px 3px 10px; - margin: 0 -2px 3px -2px; - left: 0px; - z-index: 100; - - position: relative; - top: -1px; - } - - * html .lowtabms .curbtn{ - top: 0; - } - - .lowtabms .firstcurbtn{ - margin: 0 -2px 3px 0; - padding: 3px 8px 3px 8px; - } - - .lowtabms .tabpage{ - /*border-width: 1px 0 1px 1px; - border-style: solid; - border-color: white black black white;*/ - display: none; - background-color: white; - } - - .lowtabms .tabpage.curpage{ - display: block; - height: 100%; - overflow: hidden; - } - ]]></j:style> - - <j:presentation> - <j:main pages="." buttons="div"> - <div class='lowtabms'> - <div class='btncontainer'> - </div> - </div> - </j:main> - <j:button caption="text()"> - <span class='btn'>-</span> - </j:button> - <j:page container="."> - <div class='tabpage'></div> - </j:page> - </j:presentation> -</j:tab> - -<j:tab name="tabmsdev"> - <j:style><![CDATA[ - .tabmsdev{ - width: 300px; - height: 100px; - overflow: hidden; - position: relative; - - border: 1px solid gray; - border-width: 0 0 0 0; - padding-top: 28px; - } - - .tabmsdev .btncontainer{ - position: absolute; - top: 0; - z-index: 100; - width: 100%; - padding: 5px 0 0 5px; - - border-bottom: 1px solid white; - } - - .tabmsdev .tabmsdevbtn{ - border-width: 1px 1px 0 1px; - border-style: solid; - border-color: white black #d4d0c8 white; - display: block; - float: left; - padding: 4px 6px 1px 6px; - - font-family: MS Sans Serif; - font-size: 8pt; - background-color: #D4D0C8; - - margin: 0 0 0 0; - - cursor: default; - position: relative; - z-index: 90; - top: 3px; - } - - .tabmsdev .curbtn{ - padding: 4px 6px 4px 6px; - top: 1px; - margin-left: -1px; - } - - .tabmsdev .tabmsdevpage{ - display: none; - position: relative; - background: #d4d0c8; - } - - .tabmsdev .tabmsdevpage.curpage{ - display: block; - height: 100%; - overflow: auto; - } - ]]></j:style> - - <j:presentation> - <j:main pages="." buttons="div"> - <div class='tabmsdev'> - <div class='btncontainer'> - </div> - </div> - </j:main> - <j:button caption="text()"> - <span class='tabmsdevbtn'>-</span> - </j:button> - <j:page container="."> - <div class='tabmsdevpage'></div> - </j:page> - </j:presentation> -</j:tab> -<j:tab name="tabmsdev2005"> - <j:style><![CDATA[ - .tabmsdev2005{ - width: 300px; - height: 100px; - overflow: hidden; - position: relative; - - border: 1px solid gray; - padding: 18px 2px 2px 2px; - background: #d4d0c8; - } - - .tabmsdev2005 .btncontainer{ - position: absolute; - top: 0; - z-index: 100; - width: 100%; - - background-color: #d4d0c8; - border-bottom: 1px solid gray; - } - - .tabmsdev2005 .btn{ - border-right: 1px solid gray; - background: url(images/tabtop2005.gif) no-repeat; - - display: block; - float: left; - padding: 1px 6px 2px 20px; - - font-family: MS Sans Serif; - font-size: 8pt; - font-weight: bold; - background-color: #D4D0C8; - - margin: 1px 0 0 0; - - cursor: default; - position: relative; - z-index: 90; - } - - .tabmsdev2005 .curbtn{ - top: 1px; - background: url(images/tabtopcur2005.gif) no-repeat; - } - - .tabmsdev2005 .firstcurbtn{ - margin: 1px 0 0 5px; - } - - .tabmsdev2005 .tabmsdev2005page{ - display: none; - position: relative; - } - - .tabmsdev2005 .tabmsdev2005page.curpage{ - display: block; - height: 100%; - } - ]]></j:style> - - <j:presentation> - <j:main pages="." buttons="div"> - <div class='tabmsdev2005'> - <div class='btncontainer'> - </div> - </div> - </j:main> - <j:button caption="text()"> - <span class='btn'>-</span> - </j:button> - <j:page container="."> - <div class='tabmsdev2005page'></div> - </j:page> - </j:presentation> -</j:tab> -<j:tab name="tabmsdev2005low"> - <j:style><![CDATA[ - .lowmsdevtab2005{ - width: 300px; - height: 100px; - padding-bottom: 24px; - overflow: hidden; - position: relative; - } - - .lowmsdevtab2005 .btncontainer{ - position: absolute; - bottom: 0; - padding: 0 0 0 5px !important; padding: 0 0 1px 5px; - background: #f6f5f4 url(images/tabdiv.gif) no-repeat 5px 4px; - z-index: 100; - border-top: 1px solid gray; - width: 100%; - } - * html .lowmsdevtab2005 .btncontainer{ - bottom: expression(this.parentNode.offsetHeight%2==1 ? 0: 1); - } - - .lowmsdevtab2005 .btn{ - float: left; - display: inline; - padding: 2px 8px 4px 9px; - margin-top: 1px; - - font-family: MS Sans Serif; - font-size: 8pt; - color: gray; - - cursor: default; - position: relative; - z-index: 90; - background: url(images/tabdiv.gif) no-repeat right 4px; - } - - .lowmsdevtab2005 .curbtn{ - border-width: 0 1px 1px 1px; - border-style: solid; - border-color: gray; - background: #ffffff; - color: black; - - margin: 2px 0 0 0; - - padding: 4px 7px 3px 9px; - margin: 0 -2px 1px -2px; - left: 0px; - z-index: 100; - - position: relative; - top: -1px; - } - - .lowmsdevtab2005 .firstcurbtn{ - margin: 0 -2px 1px 0; - padding: 4px 8px 3px 8px; - } - - .lowmsdevtab2005 .tabpage{ - /*border-width: 1px 0 1px 1px; - border-style: solid; - border-color: white black black white;*/ - display: none; - } - - .lowmsdevtab2005 .tabpage.curpage{ - display: block; - height: 100%; - overflow: hidden; - position: relative; - } - ]]></j:style> - - <j:presentation> - <j:main pages="." buttons="div"> - <div class='lowmsdevtab2005'> - <div class='btncontainer'> - </div> - </div> - </j:main> - <j:button caption="text()"> - <span class='btn'>-</span> - </j:button> - <j:page container="."> - <div class='tabpage'></div> - </j:page> - </j:presentation> -</j:tab> - -<j:tab name="tabmsdevlow"> - <j:style><![CDATA[ - .lowmsdevtab{ - width: 300px; - height: 100px; - padding-bottom: 24px; - overflow: hidden; - position: relative; - background: #f7f3e9; - } - - .lowmsdevtab .btncontainer{ - position: absolute; - bottom: 0; - padding: 0 0 0 5px !important; padding: 0 0 1px 5px; - background: url(images/tabdiv.gif) no-repeat 5px 4px; - z-index: 100; - border-top: 1px solid black; - width: 100%; - } - * html .lowmsdevtab .btncontainer{ - bottom: expression(this.parentNode.offsetHeight%2==1 ? 0: 1); - } - - .lowmsdevtab .btn{ - float: left; - display: inline; - padding: 2px 8px 4px 9px; - margin-top: 1px; - - font-family: MS Sans Serif; - font-size: 8pt; - color: gray; - - cursor: default; - position: relative; - z-index: 90; - background: url(images/tabdiv.gif) no-repeat right 4px; - } - - .lowmsdevtab .curbtn{ - border-width: 0 1px 1px 1px; - border-style: solid; - border-color: black black black white; - background: #D4D0C8; - color: black; - - margin: 2px 0 0 0; - - padding: 4px 7px 3px 9px; - margin: 0 -2px 1px -2px; - left: 0px; - z-index: 100; - - position: relative; - top: -1px; - } - - .lowmsdevtab .firstcurbtn{ - margin: 0 -2px 1px 0; - padding: 4px 8px 3px 8px; - } - - .lowmsdevtab .tabpage{ - /*border-width: 1px 0 1px 1px; - border-style: solid; - border-color: white black black white;*/ - display: none; - background-color: #D4D0C8; - } - - .lowmsdevtab .tabpage.curpage{ - display: block; - height: 100%; - overflow: hidden; - } - ]]></j:style> - - <j:presentation> - <j:main pages="." buttons="div"> - <div class='lowmsdevtab'> - <div class='btncontainer'> - </div> - </div> - </j:main> - <j:button caption="text()"> - <span class='btn'>-</span> - </j:button> - <j:page container="."> - <div class='tabpage'></div> - </j:page> - </j:presentation> -</j:tab> - -<j:text name="text"> - <j:style><![CDATA[ - .text{ - font-family: Arial; - font-size: 9pt; - } - - .textEmpty{ - font-size : 8pt; - font-weight : bold; - color : #ccc; - text-align : center; - } - - .messages{ - border: 1px solid gray; - background: white; - padding: 10px; - overflow: auto; - } - - .textFocus{ - } - ]]></j:style> - - <j:presentation> - <j:main container="."> - <div class='text'></div> - </j:main> - </j:presentation> -</j:text> -<j:text name="textmail"> - <j:iframe_style><![CDATA[ - body{ - overflow: auto; - margin: 10px; - - font-family: MS Sans Serif; - font-size: 9pt; - line-height: 1.4em; - color: #002187; - - background-color: white; - } - - html{ - margin: 0; - overflow: hidden; - } - ]]></j:iframe_style> - - <j:style><![CDATA[ - .textmail{ - overflow: auto; - - font-family: MS Sans Serif; - font-size: 9pt; - line-height: 1.4em; - color: #002187; - - background-color: white; - - width: 100px; - height: 100px; - } - ]]></j:style> - - <j:presentation> - <j:main container="."> - <iframe class='textmail'> </iframe> - </j:main> - </j:presentation> -</j:text> -<j:text name="textmailpage"> - <j:iframe_style><![CDATA[ - body{ - background-color: gray; - - width: 100px; - height: 100px; - overflow: auto; - border: 1px solid gray; - overflow: hidden; - margin: 0; - } - - html{ - margin: 0; - overflow: hidden; - } - - .textmailpage_page{ - padding: 10px 10px 10px 10px; - margin: 5px; - - font-family: MS Sans Serif; - font-size: 9pt; - line-height: 1.4em; - color: #002187; - - background-color: white; - border: 1px solid black; - border-width: 1px 5px 5px 1px; - - height: 100%; - } - ]]></j:iframe_style> - - <j:style><![CDATA[ - .textmailpage{ - background-color: gray; - - width: 100px; - height: 100px; - overflow: auto; - border: 1px solid gray; - } - - .textmailpage .textmailpage_page{ - padding: 10px 10px 10px 10px; - margin: 10px; - - font-family: MS Sans Serif; - font-size: 9pt; - line-height: 1.4em; - color: #002187; - - background-color: white; - border: 1px solid black; - border-width: 1px 5px 5px 1px; - - height: 80%; - } - ]]></j:style> - - <j:presentation> - <j:main container="."> - <iframe class='textmailpage'> </iframe> - </j:main> - </j:presentation> -</j:text> -<j:text name="textmessenger"> - <j:style><![CDATA[ - .textmsgr{ - border: 1px solid #86bde6; - background-color: white; - padding: 4px; - overflow: auto; - - font-family: Arial; - font-size: 10pt; - color: #545454; - } - - .textmsgr div{ - color: #0a50a1; - padding-left: 8px; - } - - .textmsgr a{ - color: blue; - } - - .textmsgr span{ - display: block; - margin: 0 0 0 0; - } - - .textmsgr div.hr, .textmsgr div.hr_top{ - width: 30px; - height: 1px; - overflow: hidden; - background-color: gray; - padding: 0; - margin: 5px 0 5px 0; - } - .textmsgr div.hr_top{ - margin-top: 20px; - } - - .textmsg img.sysmsg_icon{ - margin: 0 10px 0 0; - position: relative; - top: 3px; - } - - .textmsg span.system_joined{ - color: green; - } - - .textmsg span.system_left{ - color: maroon; - } - ]]></j:style> - - <j:presentation> - <j:main container="."> - <div class='textmsgr'></div> - </j:main> - </j:presentation> -</j:text> -<j:button name="labelbutton"> - <j:style><![CDATA[ - .lblbtn{ - color: black; - font-family: MS Sans Serif, Tahoma, Arial; - font-size: 8pt; - cursor: default; - text-align: left; - overflow: hidden; - border: 1px solid black; - border-color: white gray gray white; - width: 17px; - height: 17px; - background: #D4D0C8 no-repeat 1px 1px; - } - - .lblbtn.lblbtnDisabled{color: gray;} - .lblbtn.lblbtnDown{ - border-color: gray white white gray; - background-position: 2px 2px; - } - .lblbtn.lblbtnOver{ - } - - .lblbtnDisabled span{ - background-position: 0 100%; - } - ]]></j:style> - - <j:presentation> - <j:main caption="text()" icon="." background="span"> - <div class='lblbtn'></div> - </j:main> - </j:presentation> -</j:button> - -<j:scrollbar name="scrollbar"> - <j:style><![CDATA[ - .scrollbar{ - height: 150px; - position: absolute; - background: #D4D0C8 url(images/raster.gif); - width: 16px; - margin: 2px 0 0 -18px; - overflow: hidden; - } - - .scrollbar .btnup, .scrollbar .btndown, .scrollbar .indicator{ - font-family: MS Sans Serif; - font-size: 8pt; - border: 2px outset; - width: 12px; - height: 12px; - overflow: hidden; - text-align: center; - font-weight: bold; - cursor: default; - - -moz-border-top-colors: #D4D0C8 #FFFFFF; - -moz-border-left-colors: #D4D0C8 #FFFFFF; - -moz-border-bottom-colors: black gray; - -moz-border-right-colors: black gray; - } - - body .scrollbar .btnup.btnupdown, body .scrollbar .btndown.btndowndown{ - border: 1px solid gray; - padding: 1px 1px 1px 1px; - background-position: 4px 6px; - } - - .scrollbar .btnup{ - background: #D4D0C8 url(images/scrollup.gif) no-repeat 2px 4px; - } - - .scrollbar .btndown{ - background: #D4D0C8 url(images/scrolldown.gif) no-repeat 2px 4px; - position: absolute; - bottom: 0px; - } - - .scrollbar .indicator{ - height: 10px; - position: absolute; - overflow: hidden; - background-color: #D4D0C8; - } - - .scrollbar .slidefast{ - position: absolute; - overflow: hidden; - background-color: #353535; - height: 10px; - width: 16px; - display: none; - overflow: hidden; - } - ]]></j:style> - - <j:presentation> - <j:main btnup="div[1]" indicator="div[2]" btndown="div[3]" slidefast="div[4]"> - <div class='scrollbar'> - <div class='btnup'> </div> - <div class='indicator'> </div> - <div class='btndown'> </div> - <div class='slidefast'> </div> - </div> - </j:main> - </j:presentation> -</j:scrollbar> -<j:fastlist name="fastlist"> - <j:style><![CDATA[ - .fastlist{ - width: 200px; - height: 500px; - position: relative; - border: 1px solid white; - border-color: gray white white gray; - background-color: white; - cursor: default; - overflow: hidden; - } - - .fastlist, .dragfastlist{ - font-family: Tahoma; - font-size: 8pt; - } - - .fastlist INPUT{ - float: left; - margin: -1px 0 0 0; - display: none; - } - - .fastlist DIV, .dragfastlist{ - padding: 0; - height: 18px; - } - - .fastlist SPAN, .dragfastlist SPAN{ - padding: 0 0 0 20px; - background: url(icons/icoMailFolder.gif) no-repeat 1px center; - height: 16px; - float: left; - } - - .fastlist U, .dragfastlist U{ - text-decoration: none; - color: black; - cursor: default; - display: block; - padding: 2px 4px 2px 2px; - text-decoration: none; - white-space: nowrap; - } - - .fastlist .selected U{ - background-color: #CCCCCC; - color: black; - } - .fastlist.fastlistFocus .selected U, .dragfastlist U{ - color: white; - background-color: midnightblue; - } - .fastlist .indicate U{ - border: 1px dotted gray; - padding: 1px 3px 1px 1px; - } - .fastlist.fastlistFocus .selected A:hover{color: white;} - - .fastlist #txt_rename{ - border: 1px solid black; - padding: 1px 15px 1px 1px; - font-family: Tahoma; - font-size: 8pt; - color: black; - word-break: keep-all; - overflow: visible; - margin-top : 0px; - cursor: text; - } - - .fastlist .empty{ - text-align: center; - padding: 3px 0 0 0; - } - ]]></j:style> - - <j:presentation> - <j:main container="."> - <div class='fastlist'> - </div> - </j:main> - <j:item - class = "." - caption = "span/u/node()" - icon = "span" - select = "span" - > - <div><span><u>-</u></span></div> - </j:item> - <j:dragindicator> - <div class='dragfastlist'><span><u>-</u></span></div> - </j:dragindicator> - <j:loading> - <div class="loading">Loading...</div> - </j:loading> - <j:empty caption="."> - <div class="empty">-</div> - </j:empty> - </j:presentation> -</j:fastlist> -<j:notifier name="notifier"> - <j:style><![CDATA[ - - .notifier { - width : 200px; - padding : 7px 0 7px 0; - cursor : default; - opacity : 0; - } - - .notifier .lt { - background-image : url(images/growl_lt.gif); - background-repeat : no-repeat; - width : 8px; - height : 8px; - float : left; - overflow : hidden; - margin-top : -7px; - } - - .notifier .rt { - background-image : url(images/growl_rt.gif); - background-repeat : no-repeat; - width : 8px; - height : 8px; - float : right; - overflow : hidden; - margin-top : -7px; - } - - .notifier .lb { - background-image : url(images/growl_lb.gif); - background-repeat : no-repeat; - width : 8px; - height : 7px; - float : left; - margin-bottom : -7px; - } - - .notifier .rb { - background-image : url(images/growl_rb.gif); - background-repeat : no-repeat; - width : 8px; - height : 7px; - float : right; - margin-bottom : -7px; - } - - .notifier .line_t { - background-color : #3f3f3f; - overflow : hidden; - height : 8px !important; - line-height : 8px; - margin : -7px 8px 0 8px; - } - - .notifier .line_b { - background-color : #3f3f3f; - height : 7px !important; - line-height : 7px; - margin : 0 8px -7px 8px; - } - - .notifier .body { - background-color : #3f3f3f; - width : auto; - min-height : 15px; - padding : 0 10px 0 12px; - font-family : Tahoma; - font-size : 11px; - text-align : left; - color : white; - } - - .notifier .body .icon { - width : 48px; - height : 48px; - margin : 0 8px 0 0; - float : left; - display : none; - } - - .notifierShowIcon .body .icon { - display : block; - } - - .notifierShowIcon .body { - min-height : 50px; - } - - .notifier .hasicon { - min-height : 50px; - } - - .notifier_hidden{ - opacity : 0; - } - - .notifier_shown{ - opacity : 0.8; - } - - .notifier_hover{ - opacity : 1; - } - - ]]></j:style> - - <j:presentation> - <j:notification message="." body="div[4]" icon="div[4]/div"> - <div class="notifier"> - <div class="lt"> </div> - <div class="rt"> </div> - <div class="line_t"> </div> - <div class="body"> - <div class="icon"> </div> - </div> - <div class="lb"> </div> - <div class="rb"> </div> - <div class="line_b"> </div> - </div> - </j:notification> - </j:presentation> -</j:notifier> - -<j:notifier name="bubble"> - <j:style><![CDATA[ - - .bubble { - width : 200px; - padding : 11px 0 14px 0; - cursor : default; - opacity : 0; - } - - .bubble .lt { - background-image : url(images/bubble_lt.gif); - background-repeat : no-repeat; - width : 13px; - height : 12px; - float : left; - overflow : hidden; - margin-top : -11px; - } - - .bubble .rt { - background-image : url(images/bubble_rt.gif); - background-repeat : no-repeat; - width : 14px; - height : 12px; - float : right; - overflow : hidden; - margin-top : -11px; - } - - .bubble .lb { - background-image : url(images/bubble_lb.gif); - background-repeat : no-repeat; - width : 13px; - height : 13px; - float : left; - margin-bottom : -13px; - } - - .bubble .rb { - background-image : url(images/bubble_rb.gif); - background-repeat : no-repeat; - width : 14px; - height : 13px; - float : right; - margin-bottom : -13px; - } - - .bubble .line_t { - background-image : url(images/bubble_line_t.gif); - background-repeat : repeat-x; - overflow : hidden; - height : 12px !important; - line-height : 12px; - margin : -11px 14px 0 13px; - } - - .bubble .line_b { - background-image : url(images/bubble_line_b.gif); - background-repeat : repeat-x; - height : 13px !important; - line-height : 13px; - margin : 0 13px -13px 13px; - } - - .bubble .body { - background-image : url(images/bubble_body_small.png); - background-position : top; - background-repeat : repeat-x; - background-color : #bad9f6; - width : auto; - border : 4px solid #757a7f; - border-width : 0 4px 0 4px; - min-height : 15px; - padding : 0 10px 0 12px; - font-family : Tahoma; - font-size : 11px; - text-align : left; - color : #252525; - } - - .bubble .body .icon { - width : 48px; - height : 48px; - margin : 0 8px 0 0; - float : left; - display : none; - } - - .bubbleShowIcon .body { - min-height : 50px; - background-color : #e5f0fb; - background-position : bottom; - background-image : url(images/bubble_body.png); - } - - .bubbleShowIcon .body .icon { - display : block; - } - - .notifier_hidden { - opacity : 0; - } - - .notifier_shown { - opacity : 0.8; - } - - .notifier_hover { - opacity : 1; - } - ]]></j:style> - - <j:presentation> - <j:notification message="." body="div[4]" icon="div[4]/div"> - <div class="bubble"> - <div class="lt"> </div> - <div class="rt"> </div> - <div class="line_t"> </div> - <div class="body"> - <div class="icon"> </div> - </div> - <div class="lb"> </div> - <div class="rb"> </div> - <div class="line_b"> </div> - </div> - </j:notification> - </j:presentation> -</j:notifier> - -<j:notifier name="smoke"> - <j:style><![CDATA[ - .smoke { - width : 200px; - padding : 7px 0 7px 0; - cursor : default; - opacity : 0; - } - - .smoke .lt { - background-image : url(images/smoke_lt.gif); - background-repeat : no-repeat; - width : 8px; - height : 8px; - float : left; - overflow : hidden; - margin-top : -7px; - } - - .smoke .rt { - background-image : url(images/smoke_rt.gif); - background-repeat : no-repeat; - width : 8px; - height : 8px; - float : right; - overflow : hidden; - margin-top : -7px; - } - - .smoke .lb { - background-image : url(images/smoke_lb.gif); - background-repeat : no-repeat; - width : 8px; - height : 7px; - float : left; - margin-bottom : -7px; - } - - .smoke .rb { - background-image : url(images/smoke_rb.gif); - background-repeat : no-repeat; - width : 8px; - height : 7px; - float : right; - margin-bottom : -7px; - } - - .smoke .line_t { - background-color : #868c91; - overflow : hidden; - height : 8px !important; - line-height : 8px; - margin : -7px 8px 0 8px; - } - - .smoke .line_b { - background-color : #868c91; - height : 7px !important; - line-height : 7px; - margin : 0 8px -7px 8px; - } - - .smoke .body { - background-color : #868c91; - width : auto; - min-height : 15px; - padding : 0 10px 0 12px; - font-family : Tahoma; - font-size : 11px; - text-align : left; - color : white; - } - - .smoke .body .icon { - width : 48px; - height : 48px; - margin : 0 8px 0 0; - float : left; - display : none; - } - - .smokeShowIcon .body .icon { - display : block; - } - - .smokeShowIcon .body { - min-height : 50px; - } - - .smoke_message .hasicon { - min-height : 50px; - } - - .notifier_hidden{ - opacity : 0; - } - - .notifier_shown{ - opacity : 0.8; - } - - .notifier_hover{ - opacity : 1; - } - ]]></j:style> - - <j:presentation> - <j:notification message="." body="div[4]" icon="div[4]/div"> - <div class="smoke"> - <div class="lt"> </div> - <div class="rt"> </div> - <div class="line_t"> </div> - <div class="body"> - <div class="icon"> </div> - </div> - <div class="lb"> </div> - <div class="rb"> </div> - <div class="line_b"> </div> - </div> - </j:notification> - </j:presentation> -</j:notifier> -<j:editor name="editor"> - <j:style><![CDATA[ - .editor { - padding: 0; - margin: 0; - background-color: #fff; - word-wrap: break-word; - overflow: auto; - display: block; - z-index: 2; - overflow: visible; - border: 1px solid #c3c3c3; - } - - .editor .editor_Area{ - width: auto; - height: 100%; - word-wrap: break-word; - /*margin: 20px;*/ - background: white; - } - - .editor .editor_Area iframe{ - border: 0; - margin: 0; - padding: 0; - width: 100%; - height: 100%; - } - - .editor .toolbar_container{ - background-color:#F0F0EE; - margin: 0; - padding: 0; - width: 100%; - height: auto; - position: relative; - display: block; - } - - .editor .toolbar_container br{ - line-height: 0; - } - - .editor .editor_Toolbar{ - background: url(images/toolbar_row.png) repeat-x top left; - height: 25px; - font-family: Verdana; - font-size: 11px; - border-bottom: 1px solid #c3c3c3; - position: relative; - margin: 0; - padding: 0; - overflow: hidden; - } - - .editor .TB_Start{ - display:none; - } - - .editor .editor_seperator{ - border-left: 1px solid #c3c3c3; - border-right: 1px solid #FFFFFF; - height: 17px; - float: left; - margin: 4px 6px 0 6px; - } - - .editor .TB_End{ - display: none; - } - - .editor .editor_Toolbar div, - .editor_popup a:hover, - .editor_popup a:link, - .editor_popup a:visited, - .editor_popup a:active { - color:#333; - cursor:default; - font-weight:normal; - text-decoration:none; - position: relative; - } - - .editor .editor_Toolbar div{ - background: url("images/toolbar_btn.gif") no-repeat -4px -42px; - } - - .editor .editor_Toolbar div.right{ - position: absolute; - top: 0px; - right: 0px; - width: 4px; - height: 21px; - margin: 0; - background: url("images/toolbar_btn.gif") no-repeat 0 -42px; - } - - .editor .editor_Toolbar div, - .editor_popup a.editor_smallcell{ - display: block; - width: 22px; - height: 21px; - float: left; - cursor: default; - margin-top: 2px; - margin-left: 5px; - text-align: center; - padding: 0; - } - - .editor .editor_Toolbar div.hover { - background-position: -4px 0px; - } - - .editor .editor_Toolbar div.active, - .editor .editor_Toolbar div.editor_selected, - .editor_popup a:hover{ - background-position: -4px -21px; - } - - .editor .editor_Toolbar div.fontpicker div.right, - .editor .editor_Toolbar div.fontsizepicker div.right, - .editor .editor_Toolbar div.fontstylepicker div.right, - .editor .editor_Toolbar div.paragraphpicker div.right, - .editor .editor_Toolbar div.hover div.right{ - background-position: 0 0; - } - - .editor .editor_Toolbar div.editor_selected div.right{ - background-position: 0 -21px; - } - - .editor .editor_Toolbar div.dropdown_small{ - width: 32px !important; - } - - .editor .editor_Toolbar div.fontpicker, - .editor .editor_Toolbar div.fontsizepicker, - .editor .editor_Toolbar div.fontstylepicker, - .editor .editor_Toolbar div.paragraphpicker{ - background-position: -4px 0px; - margin-top: 2px; - text-align: left !important; - padding-left: 4px; - overflow: hidden; - } - - .editor .editor_Toolbar div.fontpicker, - .editor .editor_Toolbar div.fontstylepicker, - .editor .editor_Toolbar div.paragraphpicker{ - width: 120px !important; - } - - .editor .editor_Toolbar div.fontsizepicker{ - width: 60px !important; - } - - .editor .editor_Toolbar div span, - .editor_popup .editor_panelbuttons a span, - .editor_popup .editor_paneltoolbar a span{ - display:block; - font-size:10px; - } - - .editor .editor_Toolbar div span.selectarrow{ - position: absolute; - background: url(images/editor/toolbar.icons.gif) no-repeat -740px 0; - top: 0px; - right: 6px; - width: 8px; - height: 20px; - display:block; - z-index: 1; - } - - .editor .editor_Toolbar .editor_icon{ - background:url(images/editor/toolbar.icons.gif) no-repeat 20px 20px; - display:block; - width:20px; - height:20px; - } - - .editor .editor_Toolbar .dropdown_small .editor_icon { - position: absolute; - top: 0px; - left: 1px; - } - - .editor .editor_Toolbar div.editor_disabled{ - opacity:0.5; - filter:alpha(opacity=50); - color:#888; - } - - .editor .editor_Toolbar div.colorpreview{ - position: absolute; - bottom: 1px; - left: -2px; - background:#9A9B9A; - height:4px; - overflow:hidden; - width:16px; - } - - .editor .editor_Toolbar span.fontpreview, - .editor .editor_Toolbar span.fontsizepreview, - .editor .editor_Toolbar span.fontstylepreview, - .editor .editor_Toolbar span.paragraphpreview{ - width:100%; - height:18px; - font-size: 11px; - margin-left:2px; - line-height: 18px; - vertical-align: middle; - overflow:hidden; - } - - /* Popup/ Panel styles */ - .editor_popup{ - margin-top : -1px; - border: 1px solid #bdbcbd; - padding: 2px 0; - background: #ffffff repeat-y top left; - z-index: 1000; - color: #0d5381; - font-family : Tahoma; - font-size : 11px; - text-align: left; - cursor: default; - } - - .editor_popup .editor_panelfirst{ - display: block; - cursor: move; - color: #333; - font-weight: bold; - font-size: 10px; - line-height: 12px; - margin: 0 2px 0 0; - width: 100%; - height: 12px; - text-align: right; - vertical-align: middle; - } - - .editor_popup .editor_panelfirst a{ - padding: 0 4px 0 0 !important; - color: #D4D0C8 !important; - } - - .editor_popup .editor_panelfirst a:hover{ - background: none !important; - border: 0 !important; - color: #333 !important; - } - - .editor_popup .editor_panelrow a:hover{ - border: 2px solid #25a8e7 !important; - padding: 1px !important; - } - - .editor_popup a.editor_largecell{ - display:inline; - float: left; - border:1px solid #dcdcdc; - padding: 2px; - margin: 0 1px 0 1px; - - width:12px; - height:12px; - width:12px !important; - height:12px !important; - line-height: 12px; - font-size: 12px; - text-align: center; - vertical-align: middle; - } - - .editor_popup a.editor_largestcell{ - display:inline; - float: left; - border:1px solid #dcdcdc; - padding: 2px; - margin: 0 1px 0 1px; - - width:20px; - height:20px; - width:20px !important; - height:20px !important; - line-height: 20px; - font-size: 12px; - text-align: center; - vertical-align: middle; - } - - .editor_popup a.editor_panelcell{ - border:1px solid #dcdcdc; - padding: 2px; - width:6px; - height:6px; - margin: 0px 2px 2px 2px; - overflow:hidden; - } - - .editor_popup a.editor_font, - .editor_popup a.editor_fontsize, - .editor_popup a.editor_fontstyle, - .editor_popup a.editor_paragraph{ - display: block; - height: 15px; - padding: 3px; - border: 0; - width: auto; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - background: white; - color: black; - cursor: default; - float: none; - margin:0; - } - - .editor_popup a.editor_paragraph *{ - margin-top: 0; - margin-bottom: 0; - } - - .editor_popup a.editor_fontsize, - .editor_popup a.editor_paragraph{ - height: auto; - line-height: auto; - vertical-align: baseline; - } - - .editor_popup a.editor_font:hover, - .editor_popup a.editor_fontsize:hover, - .editor_popup a.editor_fontstyle:hover, - .editor_popup a.editor_paragraph:hover{ - background-color: #25a8e7; - color: #ffffff; - } - - .editor_popup div.editor_panelrow{ - position: relative; - margin: 0; - padding: 0; - width: auto; - height: auto; - display: block; - } - - .editor_popup div.editor_paneltoolbar{ - margin-left: 4px !important; - z-index: 1; - } - - .editor_panelrow .editor_paneltab{ - width: 196px; - margin: -5px 4px 4px 4px; - padding: 4px; - border: 1px solid #333; - display: block; - z-index: 0; - } - - .editor_panelrow div.closed{ - display: none; - } - - .editor_popup .editor_paneltoolbar{ - height: 26px !important; - overflow: visible; - } - - .editor_popup div.editor_panelrowinput{ - height: 24px !important; - } - - .editor_popup div.editor_panelrowbtns{ - height: 30px !important; - } - - .editor_popup label{ - position: relative; - float: left; - padding: 2px 0 0 6px; - margin: 0; - font-size: 11px; - height: 20px; - width: auto; - overflow: hidden; - } - - .editor_popup .editor_input, - .editor_popup select, - .editor_popup button{ - position: relative; - float: right; - border:1px solid #808080; - margin: 4px 4px 0 0; - width: 120px; - overflow: hidden; - } - - .editor_popup .editor_input{ - font-family : Arial; - height : 16px; - } - - .editor_popup .editor_checkbox{ - position: relative; - float: right; - margin: 6px 4px 0 0; - overflow: hidden; - } - - .editor_popup .editor_textarea{ - position: relative; - float: right; - border:1px solid #808080; - margin: 4px 4px 0 0; - width: 286px; - height: 200px; - font-family: 'Courier New', Courier, mono; - font-size: 12px; - overflow: hidden; - display: block; - } - - .editor_popup button{ - margin: 8px 4px 4px 0; - width: 80px; - display: inline; - } - - .editor_tablepopup{ - vertical-align: bottom; - } - - .editor_popup .editor_paneltable_cont{ - position: absolute; - background: white; - left: 2px; - top: 2px; - display: block; - -moz-user-select: none; - -khtml-user-select: none; - user-select: none; - z-index: 0; - } - - .editor_popup .editor_paneltable_sel{ - position: absolute; - background: #68768a; - left: 4px; - top: 4px; - display: block; - z-index: 1; - } - - .editor_popup .editor_paneltable{ - position: relative; - background: url(images/editor/tablecell.gif) repeat top left; - left: 4px; - top: 4px; - display: block; - z-index: 3; - } - - .editor_popup .editor_paneltable td{ - background: #fff; - border: 1px solid #333; - padding: 0; - margin: 4px; - width: 20px !important; - height: 20px !important; - } - - .editor_popup .editor_paneltable td.selected{ - background: navy; - } - - .editor_popup .editor_paneltablecancel{ - position: absolute; - width: 100%; - height: 20px; - bottom: 0px; - line-height: 20px; - text-align: center; - vertical-align: middle; - display: block; - } - - .editor textarea{ - position: absolute; - z-index: 10000; - bottom: 0px; - left: 0px; - border: 0; - } - - /* Containers */ - .editor iframe {display:block; background:#FFF} - - /* Theme */ - .editor .editor_Toolbar span.editor_bold {background-position:0 0} - .editor .editor_Toolbar span.editor_italic {background-position:-60px 0} - .editor .editor_Toolbar span.editor_underline {background-position:-140px 0} - .editor .editor_Toolbar span.editor_strikethrough {background-position:-120px 0} - .editor .editor_Toolbar span.editor_undo {background-position:-160px 0} - .editor .editor_Toolbar span.editor_redo {background-position:-100px 0} - .editor .editor_Toolbar span.editor_cleanup {background-position:-40px 0} - .editor .editor_Toolbar span.editor_bullist {background-position:-20px 0} - .editor .editor_Toolbar span.editor_numlist {background-position:-80px 0} - .editor .editor_Toolbar span.editor_justifyleft {background-position:-460px 0} - .editor .editor_Toolbar span.editor_justifyright {background-position:-480px 0} - .editor .editor_Toolbar span.editor_justifycenter {background-position:-420px 0} - .editor .editor_Toolbar span.editor_justifyfull {background-position:-440px 0} - .editor .editor_Toolbar span.editor_anchor {background-position:-200px 0} - .editor .editor_Toolbar span.editor_indent {background-position:-400px 0} - .editor .editor_Toolbar span.editor_outdent {background-position:-540px 0} - .editor .editor_Toolbar span.editor_link {background-position:-500px 0} - .editor .editor_Toolbar span.editor_unlink {background-position:-640px 0} - .editor .editor_Toolbar span.editor_sub {background-position:-600px 0} - .editor .editor_Toolbar span.editor_sup {background-position:-620px 0} - .editor .editor_Toolbar span.editor_removeformat {background-position:-580px 0} - .editor .editor_Toolbar span.editor_newdocument {background-position:-520px 0} - .editor .editor_Toolbar span.editor_image {background-position:-380px 0} - .editor .editor_Toolbar span.editor_help {background-position:-340px 0} - .editor .editor_Toolbar span.editor_code {background-position:-260px 0} - .editor .editor_Toolbar span.editor_hr {background-position:-360px 0} - .editor .editor_Toolbar span.editor_visualaid {background-position:-660px 0} - .editor .editor_Toolbar span.editor_charmap {background-position:-240px 0} - .editor .editor_Toolbar span.editor_paste {background-position:-560px 0} - .editor .editor_Toolbar span.editor_copy {background-position:-700px 0} - .editor .editor_Toolbar span.editor_cut {background-position:-680px 0} - .editor .editor_Toolbar span.editor_blockquote {background-position:-220px 0} - .editor .editor_Toolbar span.editor_forecolor {background-position:-720px 0; height: 16px} - .editor .editor_Toolbar span.editor_backcolor {background-position:-760px 0; height: 16px} - .editor .editor_Toolbar span.editor_forecolorpicker {background-position:-720px 0} - .editor .editor_Toolbar span.editor_backcolorpicker {background-position:-760px 0} - - /* Plugins */ - .editor .editor_Toolbar span.editor_advhr {background-position:-0px -20px} - .editor .editor_Toolbar span.editor_ltr {background-position:-20px -20px} - .editor .editor_Toolbar span.editor_rtl {background-position:-40px -20px} - .editor .editor_Toolbar span.editor_emotions {background-position:-60px -20px} - .editor .editor_Toolbar span.editor_fullpage {background-position:-80px -20px} - .editor .editor_Toolbar span.editor_fullscreen {background-position:-100px -20px} - .editor .editor_Toolbar span.editor_iespell {background-position:-120px -20px} - .editor .editor_Toolbar span.editor_insertdate {background-position:-140px -20px} - .editor .editor_Toolbar span.editor_inserttime {background-position:-160px -20px} - .editor .editor_Toolbar span.editor_absolute {background-position:-180px -20px} - .editor .editor_Toolbar span.editor_backward {background-position:-200px -20px} - .editor .editor_Toolbar span.editor_forward {background-position:-220px -20px} - .editor .editor_Toolbar span.editor_insert_layer {background-position:-240px -20px} - .editor .editor_Toolbar span.editor_insertlayer {background-position:-260px -20px} - .editor .editor_Toolbar span.editor_movebackward {background-position:-280px -20px} - .editor .editor_Toolbar span.editor_moveforward {background-position:-300px -20px} - .editor .editor_Toolbar span.editor_media {background-position:-320px -20px} - .editor .editor_Toolbar span.editor_nonbreaking {background-position:-340px -20px} - .editor .editor_Toolbar span.editor_pastetext {background-position:-360px -20px} - .editor .editor_Toolbar span.editor_pasteword {background-position:-380px -20px} - .editor .editor_Toolbar span.editor_selectall {background-position:-400px -20px} - .editor .editor_Toolbar span.editor_preview {background-position:-420px -20px} - .editor .editor_Toolbar span.editor_print {background-position:-440px -20px} - .editor .editor_Toolbar span.editor_cancel {background-position:-460px -20px} - .editor .editor_Toolbar span.editor_save {background-position:-480px -20px} - .editor .editor_Toolbar span.editor_replace {background-position:-500px -20px} - .editor .editor_Toolbar span.editor_search {background-position:-520px -20px} - .editor .editor_Toolbar span.editor_styleprops {background-position:-560px -20px} - .editor .editor_Toolbar span.editor_table {background-position:-580px -20px} - .editor_popup .editor_paneltoolbar span.editor_cell_props {background-position:-600px -20px} - .editor_popup .editor_panelbuttons span.editor_delete_table {background-position:-620px -20px} - .editor_popup .editor_panelbuttons span.editor_delete_col {background-position:-640px -20px} - .editor_popup .editor_panelbuttons span.editor_delete_row {background-position:-660px -20px} - .editor_popup .editor_panelbuttons span.editor_col_after {background-position:-680px -20px} - .editor_popup .editor_panelbuttons span.editor_col_before {background-position:-700px -20px} - .editor_popup .editor_panelbuttons span.editor_row_after {background-position:-720px -20px} - .editor_popup .editor_panelbuttons span.editor_row_before {background-position:-740px -20px} - .editor_popup .editor_panelbuttons span.editor_merge_cells {background-position:-760px -20px} - .editor_popup .editor_paneltoolbar span.editor_table_props {background-position:-980px -20px} - .editor_popup .editor_paneltoolbar span.editor_row_props {background-position:-780px -20px} - .editor_popup .editor_panelbuttons span.editor_split_cells {background-position:-800px -20px} - .editor .editor_Toolbar span.editor_template {background-position:-820px -20px} - .editor .editor_Toolbar span.editor_visualchars {background-position:-840px -20px} - .editor .editor_Toolbar span.editor_abbr {background-position:-860px -20px} - .editor .editor_Toolbar span.editor_acronym {background-position:-880px -20px} - .editor .editor_Toolbar span.editor_attribs {background-position:-900px -20px} - .editor .editor_Toolbar span.editor_cite {background-position:-920px -20px} - .editor .editor_Toolbar span.editor_del {background-position:-940px -20px} - .editor .editor_Toolbar span.editor_ins {background-position:-960px -20px} - .editor .editor_Toolbar span.editor_pagebreak {background-position:0 -40px} - .editor .editor_Toolbar span.editor_spellchecker {background-position:-540px -20px} - ]]></j:style> - <j:docstyle><![CDATA[ - html{ - cursor: text; - border: 0; - } - body - { - margin: 8px; - padding: 0; - border: 0; - color: #000; - font-family: Verdana,Arial,Helvetica,sans-serif; - font-size: 10pt; - background: #fff; - word-wrap: break-word; - } - .itemAnchor - { - background:url(images/editor/items.gif) no-repeat left bottom; - line-height:6px; - overflow:hidden; - padding-left:12px; - width:12px; - } - .visualAid table, - .visualAid table td - { - border: 1px dashed #bbb; - } - .visualAid table td - { - margin: 8px; - } - h1{ - margin : 15px 0 15px 0; - } - p - { - margin: 0; - padding: 0; - } - ]]></j:docstyle> - - <j:presentation> - <j:main - toolbar = "div[1]" - editor = "div[2]" - linked = "textarea" - iframe = "true" - erroffsetx = "0" - erroffsety = "100"> - <div class="editor"> - <div class="toolbar_container"> - - </div> - <div class="editor_Area"> - - </div> - </div> - </j:main> - <j:toolbar container="."> - <div class="editor_Toolbar"> - <span class="TB_Start"> </span> - </div> - </j:toolbar> - <j:divider> - <span class="editor_seperator"> </span> - </j:divider> - <j:button label="span"> - <div class="editor_disabled"> - <span> </span> - <div class="right"> </div> - </div> - </j:button> - - <j:toolbars> - <j:toolbar> - Bold, Italic, Underline, Strikethrough, |, - Sub, Sup, |, - Table, |, justifyleft, justifycenter, justifyright, - justifyfull, |, Code, |, Anchor, - Link, Unlink, Charmap - </j:toolbar> - <j:toolbar> - FontStyle, Paragraph, Fonts, Fontsize, |, RemoveFormat - </j:toolbar> - <j:toolbar> - Cut, Copy, Paste, PasteText, |, - Bullist, NumList, |, - Forecolor, Backcolor, |, - Search, Replace, |, Outdent, Indent - </j:toolbar> - </j:toolbars> - <j:fonts> - Andale Mono=andale mono,times; - Arial=arial,helvetica,sans-serif; - Arial Black=arial black,avant garde; - Book Antiqua=book antiqua,palatino; - Comic Sans MS=comic sans ms,sans-serif; - Courier New=courier new,courier; - Georgia=georgia,palatino; - Helvetica=helvetica; - Impact=impact,chicago; - Symbol=symbol; - Tahoma=tahoma,arial,helvetica,sans-serif; - Terminal=terminal,monaco; - Times New Roman=times new roman,times; - Trebuchet MS=trebuchet ms,geneva; - Verdana=verdana,geneva; - Webdings=webdings; - Wingdings=wingdings,zapf dingbats - </j:fonts> - <j:fontsizes> - 1, 2, 3, 4, 5, 6, 7 - </j:fontsizes> - <j:blockformats> - normal, h1, h2, h3, h4, h5, h6, pre, address - </j:blockformats> - <j:fontstyles><![CDATA[ - style1 = .style1 { - color: red; - font-weight: bolder; - } - Another = style2 { - color: navy; - font-size: 16px; - } - Last one = .style3 { - color: green; - font-weight: bold; - font-style: italic; - } - ]]></j:fontstyles> - <j:empty caption="."> - <div class="empty"></div> - </j:empty> - </j:presentation> -</j:editor> -<j:editor name="editsmall"> - <j:presentation> - <j:main toolbar="div[1]" editor="div[2]" linked="textarea" iframe="true"> - <div class="editor"> - <div class="toolbar_container"> - - </div> - <div class="editor_Area"> - - </div> - </div> - </j:main> - <j:toolbar container="."> - <div class="editor_Toolbar"> - <span class="TB_Start"> </span> - </div> - </j:toolbar> - <j:divider> - <span class="editor_seperator"> </span> - </j:divider> - <j:button label="span"> - <div class="editor_disabled"> - <span> </span> - <div class="right"> </div> - </div> - </j:button> - - <j:toolbars> - <j:toolbar> - Bold, Italic, Underline, Strikethrough, |, - JustifyLeft, JustifyCenter, JustifyRight, JustifyFull, |, - FontStyle, Paragraph, Fonts, Fontsize, |, RemoveFormat - </j:toolbar> - <j:toolbar> - Cut, Copy, Paste, PasteText, |, - Search, Replace, Bullist, NumList, |, - Outdent, Indent, Blockquote, |, - Undo, Redo, |, - Link, Unlink, Anchor, Hr, Table, |, - Forecolor, Backcolor - </j:toolbar> - <j:toolbar> - Sub, Sup, |, - InsertDate, InsertTime, Charmap, Emotions, |, - Print, Preview, VisualAid, |, - Code - </j:toolbar> - </j:toolbars> - <j:emotions path="images/editor"> - cool, cry, embarassed, foot-in-mouth, frown, innocent, - kiss, laughing, money-mouth, sealed, smile, surprised, - tongue-out, undecided, wink, yell - </j:emotions> - <j:fonts> - Andale Mono=andale mono,times; - Arial=arial,helvetica,sans-serif; - Arial Black=arial black,avant garde; - Book Antiqua=book antiqua,palatino; - Comic Sans MS=comic sans ms,sans-serif; - Courier New=courier new,courier; - Georgia=georgia,palatino; - Helvetica=helvetica; - Impact=impact,chicago; - Symbol=symbol; - Tahoma=tahoma,arial,helvetica,sans-serif; - Terminal=terminal,monaco; - Times New Roman=times new roman,times; - Trebuchet MS=trebuchet ms,geneva; - Verdana=verdana,geneva; - Webdings=webdings; - Wingdings=wingdings,zapf dingbats - </j:fonts> - <j:fontsizes> - 1, 2, 3, 4, 5, 6, 7 - </j:fontsizes> - <j:blockformats> - normal, h1, h2, h3, h4, h5, h6, pre, address - </j:blockformats> - <j:fontstyles><![CDATA[ - style1 = .style1 { - color: red; - font-weight: bolder; - } - Another = style2 { - color: navy; - font-size: 16px; - } - Last one = .style3 { - color: green; - font-weight: bold; - font-style: italic; - } - ]]></j:fontstyles> - <j:empty caption="."> - <div class="empty"></div> - </j:empty> - </j:presentation> -</j:editor> -<j:slideshow name="slideshow"> - <j:style><![CDATA[ - .slideshow { - position: fixed; - left : 0; - top : 0; - width : 100%; - height : 100%; - display : none; - z-index : 100; - } - - .slideshow .curtain { - background-color: black; - position : absolute; - left : 0; - top : 0; - width : 100%; - height : 100%; - z-index : 10; - margin : 0; - } - - .slideshow .close { - position : absolute; - right : 10px; - top : 10px; - background-image : url(images/close.png); - background-repeat: no-repeat; - display : block; - z-index : 1000; - cursor : pointer; - width : 22px; - height : 22px; - } - - .slideshow .previous { - left : 0; - background-image : url(images/arrow_left.png); - background-repeat: no-repeat; - } - - .slideshow .next { - right : -15px; - background-image : url(images/arrow_right.png); - background-repeat: no-repeat; - } - - .slideshow .next, .slideshow .previous { - padding : 10px; - display : block; - position : absolute; - top : 50%; - margin-top: -40px; - z-index : 1000; - cursor : pointer; - width : 40px; - height : 40px; - } - - .slideshow .body .move { - width : 19px; - height : 19px; - position : absolute; - right : 0; - bottom : 0; - background-image : url(images/arrows.png); - background-repeat: no-repeat; - display : none; - } - - .slideshow .body img { - display : none; - cursor : hand; - cursor : default; - position: relative; - z-index : 100; - } - - .slideshow .body { - background-color: white; - width : 100px; - height : 100px; - position : fixed; - left : 50%; - top : 50%; - margin-left : -50px; - margin-top : -50px; - overflow : hidden; - border : 20px solid white; - display : none; - z-index : 11; - } - - .slideshow div { - position: fixed; - bottom : 0; - z-index : 1000; - } - - .slideshow div .title { - position : relative; - width : 100%; - min-height : 31px; - display : none; - font-family : Tahoma; - font-size : 11px; - color : white; - padding : 10px; - overflow : hidden; - z-index : 1001; - border-top : 1px solid #636363; - background-color: #585858; - } - - .slideshow div .title .icon { - position : relative; - background-image : url(images/info.png); - background-repeat: no-repeat; - width : 31px; - height : 31px; - float : left; - margin-right : 15px; - } - - .slideshow div .title .content { - float : left; - position : relative; - width : 95%; - min-height: 11px; - } - - .slideshow div .thumbnails { - position : relative; - width : 100%; - min-height : 30px; - z-index : 1001; - display : none; - border-top : 1px solid #707070; - background-color: #646464; - } - - .slideshow div .thumbnails .picture { - border : 2px solid white; - opacity : 0.3; - filter:progid:DXImageTransform.Microsoft.Alpha(opacity=30); - position: relative; - margin : 5px; - } - - .slideshow div .thumbnails .picture:hover { - opacity: 1; - filter:progid:DXImageTransform.Microsoft.Alpha(opacity=100); - cursor : pointer; - border : 2px solid #464646; - } - - .slideshow div .thumbnails .selected { - border : 2px solid #464646; - opacity: 1; - filter:progid:DXImageTransform.Microsoft.Alpha(opacity=100); - } - - .slideshow div .thumbnails .tprevious { - width : 20px; - margin-right : 20px; - height : 100%; - position : relative; - float : left; - background-image : url(images/tprevious.jpg); - background-repeat : no-repeat; - background-position: left center; - } - - .slideshow div .thumbnails .tprevious:hover { - background-image: url(images/tprevious2.jpg); - } - - .slideshow div .thumbnails .tnext { - width : 20px; - margin-left : 20px; - height : 100%; - position : relative; - float : right; - background-image : url(images/tnext.jpg); - background-repeat : no-repeat; - background-position: right center; - } - - .slideshow div .thumbnails .tnext:hover { - background-image: url(images/tnext2.jpg); - } - - .slideshow div .thumbnails .tbody { - position : relative; - overflow : hidden; - white-spaces: nowrap; - margin : 0 auto; - } - - .slideshow .body .loading { - margin-left: -30px; - margin-top : -7px; - width : 60px; - height : 17px; - position : absolute; - left : 50%; - top : 50%; - z-index : 99; - text-align : center; - font-family: Tahoma; - font-weight: bold; - font-size : 14px; - display : block; - color : #4c4c4c; - } - ]]></j:style> - - <j:presentation> - <j:main - container="." - move="div/div" - curtain="blockquote" - image="div/img" - body="div" - close="span" - next="span[2]" - previous="span[3]" - beam = "div[2]" - title="div[2]/span" - content="div[2]/span/div[2]" - thumbnails="div[2]/div" - tprevious="div[2]/div/div" - tbody="div[2]/div/div[3]" - tnext="div[2]/div/div[2]" - loading="div/div[2]" - > - <div class="slideshow"> - <blockquote class="curtain"> </blockquote> - <div class="body"> - <img /> - <div class="move"> </div> - <div class="loading"> </div> - </div> - <span class="close"> </span> - <span class="next"> </span> - <span class="previous"> </span> - <div> - <span class="title"> - <div class="icon"> </div> - <div class="content"> </div> - </span> - <div class="thumbnails"> - <div class="tprevious"> </div> - <div class="tnext"> </div> - <div class="tbody"> </div> - </div> - </div> - </div> - </j:main> - <j:thumbnail> - <div class="picture"> </div> - </j:thumbnail> - </j:presentation> -</j:slideshow> -<!-- refguide --> -<j:list name="listcomments"> - <j:style><![CDATA[ - .listcomments{ - overflow: auto; - position: relative; - cursor: default; - cursor : auto; - } - - .listcomments div{ - margin : 0 0 20px 0; - background : #f2f2f2; - padding : 10px; - } - - .listcomments .message{ - /*font-family : Courier New;*/ - background : white; - margin : 10px 0 0 0; - } - - .listcomments blockquote{ - margin : 0; - padding : 0; - font-family : Arial; - } - - .listcomments pre{ - margin : 10px 0 10px 0; - } - - .listcomments h3{ - font-size : 12pt; - font-family : Arial; - margin : 0; - } - - .listcomments{ - line-height : 1.3em; - } - - .listcomments .highlight{ - background-color : #FFF59A; - } - ]]></j:style> - - <j:presentation> - <j:main container="."> - <div class='listcomments'> - </div> - </j:main> - <j:item - class = "." - caption = "." - select = "." - > - <div> </div> - </j:item> - <j:loading> - <div class="loading">Loading...</div> - </j:loading> - <j:empty caption="."> - <div class="message">-</div> - </j:empty> - </j:presentation> -</j:list> -<j:bar name="basic"> - <j:style><![CDATA[ - .basic{ - position : absolute; - border: 1px solid #c3c3c3; - } - ]]></j:style> - - <j:presentation> - <j:main container="."> - <div class="basic"> - </div> - </j:main> - </j:presentation> -</j:bar> -<j:caldropdown name="caldropdown"> - <j:style><![CDATA[ - .caldropdown { - position : relative; - background : url("images/dropdown.png") no-repeat top right; - width : 134px; - height : 17px; - margin : 0; - padding : 2px 18px 0 0; - color : #4b4b4b; - font-family : Tahoma; - font-size : 11px; - } - - .caldropdownError { - background-position : right -57px; - } - - .caldropdownDisabled { - color : #bebebe; - } - - .caldropdownFocus { - background-position : right -19px; - } - - .caldropdownOver { - - } - - .caldropdownDown { - position : relative; - background-position : right -38px; - } - - .caldropdown .caldropdownLeftBorder { - background : url("images/dropdown.png") no-repeat top left; - float : left; - margin : -2px 0 0 0; - width : 2px; - _margin : -2px -1px 0 0; - height : 19px; - } - - .caldropdown .caldropdownlabel { - padding : 0 0 0 4px; - cursor : default; - height : 15px; - margin : 0 0 0 2px; - } - - .caldropdownError .caldropdownLeftBorder { - background-position : 0 -57px; - } - - .caldropdownError .caldropdownlabel { - background-color : #ffb500; - color : #fbfbfb; - } - - .caldropdownInitial .caldropdownLeftBorder { - } - - .caldropdownInitial .caldropdownlabel { - color : #999; - } - - .caldropdownInitial.caldropdownFocus .caldropdownLeftBorder { - background-position : 0 -19px; - } - - .caldropdownInitial.caldropdownFocus .caldropdownlabel { - background-color : transparent; - color : #ffffff; - } - - .caldropdownFocus .caldropdownLeftBorder { - background-position : 0 -19px; - } - - .caldropdownFocus .caldropdownlabel { - background-color : #25a8e7; - color : #ffffff; - } - - .caldropdownDown .caldropdownLeftBorder { - background-position : 0 -38px; - } - - .caldropdownDown .caldropdownlabel { - color : #4b4b4b; - background-color : white; - } - - .calSlider { - position : absolute; - top : 0; - left : 0; - width : 120px; - margin-top : -1px; - border : 1px solid #327fbd; - background-color : #ffffff; - z-index : 1000; - color : #0d5381; - font-family : Tahoma; - font-size : 11px; - display : none; - overflow : auto; - } - - .calSlider .navigation { - display : block; - margin : 0 auto; - height : 16px; - padding : 3px; - } - - .calSlider .navigation .button { - width : 13px; - height : 13px; - position : relative; - color : #4b4b4b; - } - - .calSlider .navigation .today { - font-size : 11px; - text-align : right; - display : block; - width : 32px; - padding : 3px; - cursor : pointer; - position : absolute; - background-color : white; - right : 37px; - z-index : 100000; - } - - .calSlider .navigation .status { - font-size : 11px; - text-align : center; - display : block; - width : 90px; - white-space : nowrap; - padding : 3px 0 3px 0; - left : 50%; - margin-left : -45px; - position : absolute; - z-index : 80000; - } - - .calSlider .navigation .nextMonth { - background-image : url(images/calendar_m_plus.png); - margin : 3px 0 3px 0; - cursor : pointer; - position : absolute; - right : 23px; - display : block; - z-index : 100000; - } - - .calSlider .navigation .nextYear { - background-image : url(images/calendar_y_plus.png); - margin : 3px 0 3px 0; - cursor : pointer; - position : absolute; - right : 6px; - display : block; - z-index : 100000; - } - - - .calSlider .navigation .prevMonth { - background-image : url(images/calendar_m_minus.png); - margin : 3px 3px 3px 0; - cursor : pointer; - position : absolute; - left : 23px; - display : block; - z-index : 100000; - } - - .calSlider .navigation .prevYear { - background-image : url(images/calendar_y_minus.png); - margin : 3px 3px 3px 0; - cursor : pointer; - position : absolute; - left : 6px; - display : block; - z-index : 100000; - } - - .calSlider .navigation .hover { - background-color : #e1e1e1; - } - - .calSlider .daysofweek { - margin : 0 auto; - display : block; - position : relative; - } - - .calSlider .daysofweek .dayofweek { - border : 1px solid #c1c1c1; - float : left; - font-family : Tahoma; - font-size : 11px; - color : #4b4b4b; - display : block; - margin : 1px; - text-align : center; - cursor : default; - background-color : #dadada; - background-image : url(images/new_cal_big.jpg); - background-position : 50% 50%; - background-repeat : no-repeat; - overflow : hidden; - } - - .calSlider .row { - margin : 0 auto; - display : block; - position : relative; - padding : 0 1px 0 1px; - } - - .calSlider .row .cell { - position : relative; - background-color : #ededed; - color : #4b4b4b; - border : 1px solid #b2b2b2; - float : left; - text-align : center; - cursor : default; - display : block; - background-image : url(images/new_cal_big.jpg); - background-position : 50% 50%; - background-repeat : no-repeat; - background-color : #dadada; - } - - .calSlider .row .weekend { - color : #ed1c24; - background-color : #dadada; - border : 1px solid #b2b2b2; - } - - .calSlider .row .disabled { - border : 1px solid white; - color : #e1e1e1; - background-color : white; - background-image : none; - } - - .calSlider .row .hover { - border : 1px solid #a09d9d; - background-color : #cac8c9; - opacity : 0.7; - filter:progid:DXImageTransform.Microsoft.Alpha(opacity=70); - } - - .calSlider .row .active { - border : 1px solid black; - background-color : #b7b7b7; - background-image : url(images/new_cal_sel_big.jpg); - } - ]]></j:style> - <j:style condition="jpf.isGecko"><![CDATA[ - .calSlider .row .cell { - float : none; - display : -moz-grid; - } - ]]></j:style> - - <j:presentation> - <j:main label="div[2]" button="."> - <div class='caldropdown'> - <div class='caldropdownLeftBorder'> </div> - <div class='caldropdownlabel'>-</div> - </div> - </j:main> - <j:container contents="." navigation="div[1]" daysofweek="div[2]"> - <div class='calSlider'> - <div class="navigation"> </div> - <div class="daysofweek"> </div> - </div> - </j:container> - <j:cell> - <div class="cell"> </div> - </j:cell> - <j:row> - <div class="row"> </div> - </j:row> - <j:day> - <div class="dayofweek"> </div> - </j:day> - <j:button> - <div class="button"> </div> - </j:button> - <j:empty caption="."> - <div class="empty">-</div> - </j:empty> - </j:presentation> -</j:caldropdown> -<j:datagrid name="propedit"> - <j:style><![CDATA[ - .propedit{ - border: 1px solid #c3c3c3; - /*border-left : 14px solid #cfcbc2;*/ - background-color: white; - cursor: default; - - font-family: Tahoma; - font-size: 11px; - - padding: 0 0 0 0; - } - div.propedit{ - position : relative; - } - - .propedit .headings{ - position : relative; - top : 0; - left : 0; - height : 17px; - z-index : 10; - background-color : #e6e6e6; - margin : 0; /*margin : 0 16px 0 0; Temp disabled for non scrolling */ - white-space : nowrap; - } - - .fixed .headings{ - overflow : hidden; - z-index : 100; - } - - .propedit .headings span{ - display : inline-block; - height : 15px; - } - - .propedit .headings span b{ - font-weight : normal; - - background : #e6e6e6 no-repeat 0 50%; - overflow : hidden; - text-overflow : ellipsis; - - padding : 2px 1px 0px 3px; - margin : 0 -1px 0 -1px; - border-right : 1px solid #cfcbc2; - border-left : 1px solid #cfcbc2; - display : block; - height : 15px; - font-weight : bold; - } - - .propedit .headings span.hover{ - } - - .propedit .headings span.down b, .propedit .headings span.drag b{ - color: white; - background-color: #25a8e7; - } - - .propedit .headings span.ascending b{ - background-image : url(images/sort_asc_n.gif); - background-repeat : no-repeat; - background-position : right 6px; - } - - .propedit .headings span.descending b{ - background-image : url(images/sort_desc_n.gif); - background-repeat : no-repeat; - background-position : right 6px; - } - - .propedit .headings span.drag{ - border : 1px solid white; - } - - .virtual .records{ - overflow : hidden; - } - - .fixed .records{ - overflow-x: auto; - } - - .propedit body.records{ - overflow : visible; - margin : 0; - border : 0; - padding : 17px 0 0 0; - white-space : nowrap; - } - - .propedit iframe{ - position : absolute; - left : 0; - top : 0; - width : 100%; - height : 100%; - } - - html.propedit{ - overflow-x: hidden; - overflow-y: auto; /* Should be auto. This was scroll */ - border : 0; - margin : 0; - } - - html.fixed{ - overflow-x : auto; - } - - .propedit .records div dl{ - font-weight : normal; - padding : 2px 1px 2px 3px; - display : block; - border : 1px solid #cfcbc2; - overflow : hidden; - min-height : 13px; - margin : 0 -1px 0 -1px; - cursor : default; - } - - .propedit .records div span{ - display : inline-block; - vertical-align : top; - - background : white no-repeat 0 50%; - text-overflow : ellipsis; - white-space : nowrap; - } - - .propedit .records div{ - margin-bottom : -1px; - } - - .propedit .records .tall dl{height : 36px;} - .propedit .records .tall span{height : 40px;} - .propedit .records .tall{height : 41px;} - - .propedit .records .selected .celllabel dl{ - background-color: #f0f0f0; - color: black;/*#4b4b4b;*/ - } - - .propeditFocus .records .selected .celllabel dl{ - color: white; - background-color: #25a8e7; - } - - .propedit .records .cellselected dl{ - background : white; - color : black; - cursor : text; - } - - .propeditFocus .records .cellselected dl{ - } - - /*.propedit .records .cellselected{ - background-color: #f0f0f0; - color: #4b4b4b; - } - .propeditFocus .records .cellselected{ - color: white; - background-color: #25a8e7; - }*/ - - .propedit .move_pointer{ - height : 100px; - width : 2px; - position : absolute; - top : 0; - margin : -10px 0 0 -4px; - width : 9px; - height : 38px; - background : url(images/column_picker.gif) no-repeat 0 0; - overflow : hidden; - z-index : 1000; - } - - .propedit .size_pointer{ - border : 1px dotted gray; - border-width : 0 1px 0 1px; - height : 100%; - position : absolute; - top : 0px; - z-index : 1000; - cursor : w-resize; - } - - .pointer{ - display : none; - } - - .propedit #txt_rename{ - font-family: Tahoma; - font-size: 8pt; - word-break: keep-all; - overflow: hidden; - cursor: text; - background-color: white; - - height : 14px; - border : 1px solid #cfcbc2; - border-width : 1px 1px 1px 0; - padding : 2px 1px 1px 3px; - position : relative; - z-index : 10; - } - - .propedit input#txt_rename{ - outline : none; - padding : 2px 0 1px 2px; - margin : 0 -2px 0 -1px; - border-width : 1px 1px 1px 1px; - } - - .propedit .ddbtn{ - width : 11px; - height : 10px; - padding : 2px 0 2px 2.5px; - border : 2px outset; - display : none; - position : absolute; - right : 0; - overflow : hidden; - background : #cfcbc2 url(images/sort_asc.gif) no-repeat 3px 5px; - text-decoration : none; - } - - .propeditcontainerdropdown, .propeditcontainerset, .ddjmlcontainer{ - display : none; - text-decoration : none; - border : 1px solid black; - background : white; - position : absolute; - overflow : hidden; - margin : 0; - padding : 0; - } - - .ddjmlcontainer{ - /*padding : 5px;*/ - overflow : hidden; - } - - .propeditcontainerdropdown div, .propeditcontainerset div{ - display: block; - height: 15px; - padding: 1px 3px 1px 3px; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - background-color: white; - color: black; - cursor: default; - } - - .propeditcontainerdropdown div.hover{ - background-color: #25a8e7; - color: #ffffff; - } - - .propeditcontainerset div.hover{ - background-color : #eee; - } - - .propeditcontainerset div{ - padding : 2px 3px 0 1px; - } - - .propeditcontainerset div span{ - width: 12px; - height: 12px; - overflow: hidden; - margin : 1px 3px 0 1px; - float : left; - background: url("images/checkbox.png") no-repeat 0 -12px; - } - - .propeditcontainerset div.checked span{ - background-position: 0 -24px; - } - - .propedit .btncustom{ - width : 11px; - height : 10px; - padding : 2px 0 2px 2.5px; - border : 2px outset; - background-color : #cfcbc2; - display : none; - position : absolute; - right : 0; - overflow : hidden; - line-height : 10px; - font-family : Tahoma; - font-size : 7pt; - font-weight : bold; - text-decoration : none; - } - - .propedit u.down{ - border : 2px inset; - padding : 3px 0 1px 3.5px; - width : 10px; - background-position : 4px 6px; - } - - /*.propeditFocus .btncustom, .propeditFocus .ddbtn{ - display : block; - }*/ - - .propedit .empty, .propedit .offline, .propedit .loading{ - text-align: center; - padding: 8px 0 0 5px; - color: #AAA; - font-weight : normal; - } - - .propedit .item{ - padding : 3px 4px 4px 2px; - /*border-bottom : 1px solid #eee;*/ - margin : 0 -3px 0 -3px; - cursor : default; - } - - .propedit .item i{ - overflow : hidden; - width : 14px; - height : 14px; - background : #eee; - text-align : center; - margin : 0 5px 0 2px; - font-size : 10px; - float : left; - font-style: normal; - } - - .propedit .item i:hover{ - color: white; - background-color: #25a8e7; - } - - .propedit .newitem{ - padding : 2px; - margin : -1px 0 -1px 0; - cursor : text; - border-bottom : 1px dotted #cfcbc2; - height : 14px; - } - - .propedit div span.propedit_lookupmultiple dl{ - padding : 0; - } - - .propedit div span.propedit_lookupmultiple dl div, .propedit div span.propedit_childrenmultiple dl div{ - position : relative; - padding-left : 22px; - } - - .propedit div span.propedit_lookupmultiple dl div i, .propedit div span.propedit_childrenmultiple dl div i{ - position : absolute; - left : 1px; - } - - .propedit div span.propedit_lookupmultiple dl div i{ - left : 3px; - } - - .propedit div span.propedit_lookupmultiple #txt_rename{ - margin : -1px; - } - ]]></j:style> - <j:style condition="jpf.isIE"><![CDATA[ - .propedit .headings div{ - } - - .propedit .records div span{ - } - ]]></j:style> - <j:style condition="jpf.isIE6"><![CDATA[ - .propedit{ - overflow-x : hidden; - padding-right : 16px; - } - - .fixed .headings{ - width : 100%; - } - - .fixed .records{ - width : 100%; - padding-left : -16px; - text-index : expression(this.style.paddingLeft='16px'); - } - - .fixed .records div{ - margin-left : -16px; - } - - .fixed .records div span{ - overflow : hidden; - height : 19px; - margin-top : -1px; - } - - .propedit body.records{ - padding : 18px 0 0 0; - } - - .fixed .records div span dl{ - width : expression(this.parentNode.offsetWidth - 5); - } - - .propedit iframe{ - height : expression(this.parentNode.parentNode.offsetHeight - 2); - width : expression(this.parentNode.parentNode.offsetWidth - 2); - } - - html.propedit body.records { - margin-right : -20px; - } - - .propedit .size_pointer{ - height : expression(this.parentNode.offsetHeight - 2); - } - ]]></j:style> - <j:style condition="!jpf.isIE"><![CDATA[ - .propedit .btncustom, .propedit .ddbtn{ - -moz-border-top-colors: #D4D0C8 #FFFFFF; - -moz-border-left-colors: #D4D0C8 #FFFFFF; - -moz-border-bottom-colors: black gray; - -moz-border-right-colors: black gray; - - margin-top : -19px; - } - - .propedit u.down{ - -moz-border-top-colors: gray black; - -moz-border-left-colors: gray black; - -moz-border-bottom-colors: #FFFFFF #D4D0C8; - -moz-border-right-colors: #FFFFFF #D4D0C8; - } - - .propedit .item i{ - margin : 0 5px 0 3px; - font-size : 11px; - line-height : 11px; - } - - .propedit .records{ - overflow-x: hidden; - overflow-y: auto; - height : 100%; - position : absolute; - top : 0; - left : 0; - width : 100%; - padding : 0; - white-space : nowrap; - } - - .propedit .records>div:first-child{ - margin-top : 17px; - } - ]]></j:style> - <j:style condition="jpf.isGecko && !jpf.isGecko3"><![CDATA[ - .propedit .headings{ - height : 18px; - } - - .propedit .headings span{ - height : 18px; - } - - .propedit .records div span{ - height : 18px; - } - - .propedit .records div{ - height : 18px; - } - - .propedit .records div span dl{ - border-width : 0 1px 1px 0; - } - - .propedit .headings span{ - display : -moz-inline-grid; - overflow : visible; - position : relative; - } - - .propedit .records{ - } - - .propedit .records div span{ - display : -moz-inline-grid; - overflow : visible; - position : relative; - } - - .propedit input#txt_rename{ - position : absolute; - padding : 1px 1px 0 2px; - } - ]]></j:style> - <j:style condition="jpf.isGecko3"> - .propedit .records .cellselected dl{ - } - - .propedit input#txt_rename{ - position : relative; - padding-top : 2px; - } - </j:style> - - <j:presentation> - <j:main - head = "div[1]" - body = "div[3]" - pointer = "div[2]" - - widthdiff = "2" - defaultwidth = "70" - scalerename = "true" - iframe = "true" - > - <div class="propedit"> - <div class='headings'> - - </div> - <div class='pointer'> </div> - <div class='records'> </div> - </div> - </j:main> - - <j:headitem class="." caption="b/text()"> - <span><b>-</b></span> - </j:headitem> - - <j:rowheaditem class="." caption="text()"> - <span>-</span> - </j:rowheaditem> - - <j:row class="." container="."> - <div /> - </j:row> - - <j:dragindicator> - <div class='dragdg'> </div> - </j:dragindicator> - - <j:cell caption="dl"><span><dl> </dl></span></j:cell> - - <j:container container="."> - <div class="dginfo">-</div> - </j:container> - - <j:dropdown> - <u class="ddbtn"> </u> - </j:dropdown> - - <j:dropdown_container item-height="17"> - <ul class="propeditcontainerdropdown"> </ul> - </j:dropdown_container> - - <j:jml_container jml="true"> - <ul class="ddjmlcontainer"> </ul> - </j:jml_container> - - <j:custom> - <u class="btncustom">...</u> - </j:custom> - - <j:loading> - <div class="loading"><span></span><label>Loading...</label></div> - </j:loading> - - <j:empty caption="."> - <div class="empty"> </div> - </j:empty> - </j:presentation> -</j:datagrid> -<j:spinner name="spinner"> - <j:style><![CDATA[ - .spinner { - position : relative; - height : 19px; - margin : 0; - padding : 0; - min-width : 35px; - } - - .spinner .divfix { - display : block; - position : absolute; - text-align : right; - height : 19px; - left : 0; - right : 19px; - margin : 0; - z-index : 9000; - padding : 0; - border : 0; - } - - .spinner .divfix input { - outline : none; - display : block; - border-top : 1px solid #b2b2b2; - border-left : 1px solid #b2b2b2; - border-bottom : 1px solid #b2b2b2; - border-right : 0; - padding : 1px 1px 2px 0; - position : absolute; - text-align : right; - left : 0; - height : 14px; - background-position : 0 0; - background-image : url(images/spinner_body2.png); - color : black; - font-family : Tahoma; - font-size : 11px; - width : 100%; - margin : 0; - z-index : 10000; - } - - .spinner .buttons { - display : block; - width : 18px; - height : 19px; - position : absolute; - right : 0; - z-index : 11000; - } - - .spinner .buttons .plus { - height : 9px; - width : 18px; - cursor : default; - border-left : 0; - border-right : 1px solid #b2b2b2; - border-bottom : 0; - border-top : 1px solid #b2b2b2; - background-image : url(images/spinner_plus.png); - background-position : 0 0; - margin : 0; - } - - .spinner .buttons .minus { - height : 8px; - width : 18px; - cursor : default; - border-left : 0; - border-right : 1px solid #b2b2b2; - border-bottom : 1px solid #b2b2b2; - border-top : 0; - background-image : url(images/spinner_minus.png); - background-position : 0 0; - } - - .spinner .buttons .plusFocus { - background-position : 0 27px; - border-top : 1px solid #327fbd; - border-right : 1px solid #327fbd; - } - - .spinner .buttons .minusFocus { - background-position : 0 24px; - border-bottom : 1px solid #327fbd; - border-right : 1px solid #327fbd; - } - - .spinner .buttons .plusDown { - background-position : 0 9px; - border-top : 1px solid #327fbd; - border-right : 1px solid #327fbd; - } - - .spinner .buttons .minusDown { - background-position : 0 8px; - border-bottom : 1px solid #327fbd; - border-right : 1px solid #327fbd; - } - - .spinner .buttons .plusHover { - background-position : 0 18px; - } - - .spinner .buttons .minusHover { - background-position : 0 16px; - } - - .spinner .divfix .focus { - background-position : 0 17px; - border-top : 1px solid #327fbd; - border-bottom : 1px solid #327fbd; - border-left : 1px solid #327fbd; - border-right : 0; - } - ]]></j:style> - <j:style condition="jpf.isOpera"><![CDATA[ - .spinner .divfix { - right : 20px; - } - ]]></j:style> - <j:presentation> - <j:main - container="." - input="div[2]/input" - buttonplus="div/div[1]" - buttonminus="div/div[2]"> - <div class="spinner"> - <div class="buttons"> - <div class="plus"> </div> - <div class="minus"> </div> - </div> - <div class="divfix"> - <input type="text" /> - </div> - </div> - </j:main> - </j:presentation> -</j:spinner> -<j:calendar name="calendar"> - <j:style><![CDATA[ - .caldropdown{ - position : relative; - width : 134px; - height : 19px; - color : #4b4b4b; - margin : 0; - font-family : Tahoma; - font-size : 11px; - } - - .caldropdown .first { - width:2px; - background-color:red; - height : 19px; - background-image : url(images/calendar_left.png); - background-position : 0 0; - float : left; - } - - .caldropdown .button { - height : 19px; - width : 18px; - background-image : url(images/calendar_button.png); - background-position : 0 0; - float : left; - } - - .caldropdown .dropdownlabel{ - cursor : default; - float : left; - background-image : url(images/calendar_body.png); - background-position : 0 0; - height : 14px; - padding : 3px 0 2px 2px; - text-align : left; - color : #4b4b4b; - overflow : hidden; - } - - .caldropdown .focus { - background-position : 0 38px; - color : white; - } - - .caldropdown .down { - background-position : 0 19px; - color : #4b4b4b; - } - - .calendar { - position : absolute; - top : 0; - left : 0; - border : 1px solid #b2b2b2; - z-index : 1000; - color : #0d5381; - font-family : Tahoma; - background-color : white; - font-size : 11px; - display : none; - overflow : auto; - } - - .calendar .navigation { - display : block; - margin : 0 auto; - height : 16px; - padding : 3px; - } - - .calendar .navigation .button { - width : 13px; - height : 13px; - position : relative; - color : #4b4b4b; - } - - .calendar .navigation .today { - font-size : 11px; - text-align : center; - display : block; - width : 50px; - padding : 3px; - float : right; - cursor : pointer; - } - - .calendar .navigation .status { - font-size : 11px; - text-align : center; - display : block; - width : 90px; - white-space : nowrap; - padding : 3px; - left : 50%; - margin-left : -45px; - position : absolute; - background-color : white; - } - - .calendar .navigation .nextMonth { - background-image : url(images/calendar_m_plus.png); - float : right; - margin : 3px; - cursor : pointer; - } - - .calendar .navigation .prevMonth { - background-image : url(images/calendar_m__minus.png); - float : left; - margin : 3px; - cursor : pointer; - } - - .calendar .navigation .nextYear { - background-image : url(images/calendar_y_plus.png); - float : right; - margin : 3px; - cursor : pointer; - } - - .calendar .navigation .prevYear { - background-image : url(images/calendar_y_minus.png); - float : left; - margin : 3px; - cursor : pointer; - } - - .calendar .navigation .nextMonth:hover, - .calendar .navigation .prevMonth:hover, - .calendar .navigation .nextYear:hover, - .calendar .navigation .prevYear:hover, - .calendar .navigation .today:hover { - background-color : #ebebeb; - } - - .calendar .daysofweek { - margin : 0 auto; - display : block; - position : relative; - } - - .calendar .daysofweek .dayofweek { - border : 1px solid #c1c1c1; - float : left; - font-family : Tahoma; - font-size : 11px; - color : #4b4b4b; - display : block; - margin : 1px; - text-align : center; - cursor : default; - background-color : #e6e6e6; - overflow : hidden; - } - - .calendar .row { - margin : 0 auto; - display : block; - position : relative; - } - - .calendar .row .cell { - position : relative; - background-color : #ededed; - color : #4b4b4b; - border : 1px solid #c1c1c1; - margin : 1px; - float : left; - text-align : center; - cursor : default; - display : -moz-grid; - } - - .calendar .row .weekend { - color : #ed1c24; - background-color : #ededed; - } - - .calendar .row .disabled { - color : #e1e1e1; - background-color : white; - } - - .calendar .row .active { - border : 1px solid #707070; - background-color : #c0c0c0; - } - - .calendar .row .hover { - border : 1px solid #c0bdbd; - margin : 1px; - background-color : #dcdcdc; - } - ]]></j:style> - <j:style condition="jpf.isGecko"><![CDATA[ - .calendar .row .cell { - float : none; - display : -moz-grid; - } - ]]></j:style> - - <j:presentation> - <j:main - first="div[1]" - label="div[2]" - button="div[3]" - > - <div class='caldropdown'> - <div class="first"> </div> - <div class='dropdownlabel'>-</div> - <div class="button"> </div> - </div> - </j:main> - <j:container contents="." navigation="div[1]" daysofweek="div[2]"> - <div class='calendar'> - <div class="navigation"> </div> - <div class="daysofweek"> </div> - </div> - </j:container> - <j:cell> - <div class="cell"> </div> - </j:cell> - <j:row> - <div class="row"> </div> - </j:row> - <j:day> - <div class="dayofweek"> </div> - </j:day> - <j:button> - <div class="button"> </div> - </j:button> - <j:empty caption="text()"> - <div class="empty">-</div> - </j:empty> - </j:presentation> -</j:calendar> -</j:skin> diff --git a/ajax-broker/sso.php b/ajax-broker/sso.php deleted file mode 100644 index c43da27..0000000 --- a/ajax-broker/sso.php +++ /dev/null @@ -1,229 +0,0 @@ -<?php -/** - * Helper class for broker of single sign-on - */ -class SingleSignOn_Broker -{ - /** - * Pass 401 http response of the server to the client - */ - public $pass401=false; - - /** - * Url of SSO server - * @var string - */ - public $url = "http://sso-server.adaniels.nl/sso.php"; - - /** - * My identifier, given by SSO provider. - * @var string - */ - public $broker = "LYNX"; - - /** - * My secret word, given by SSO provider. - * @var string - */ - public $secret = "klm345"; - - /** - * Need to be shorter than session expire of SSO server - * @var string - */ - public $sessionExpire = 1800; - - /** - * Session hash - * @var string - */ - protected $sessionToken; - - /** - * User info recieved from the server. - * @var array - */ - protected $userinfo; - - - /** - * Class constructor - */ - public function __construct($auto_attach=true) - { - if (isset($_COOKIE['session_token'])) $this->sessionToken = $_COOKIE['session_token']; - - if ($auto_attach && !isset($this->sessionToken)) { - header("Location: " . $this->getAttachUrl() . "&redirect=". urlencode("http://{$_SERVER["SERVER_NAME"]}{$_SERVER["REQUEST_URI"]}"), true, 307); - exit; - } - } - - /** - * Get session token - * - * @return string - */ - public function getSessionToken() - { - if (!isset($this->sessionToken)) { - $this->sessionToken = md5(uniqid(rand(), true)); - setcookie('session_token', $this->sessionToken, time() + $this->sessionExpire); - } - - return $this->sessionToken; - } - - /** - * Generate session id from session key - * - * @return string - */ - protected function getSessionId() - { - if (!isset($this->sessionToken)) return null; - return "SSO-{$this->broker}-{$this->sessionToken}-" . md5('session' . $this->sessionToken . $_SERVER['REMOTE_ADDR'] . $this->secret); - } - - /** - * Get URL to attach session at SSO server - * - * @return string - */ - public function getAttachUrl() - { - $token = $this->getSessionToken(); - $checksum = md5("attach{$token}{$_SERVER['REMOTE_ADDR']}{$this->secret}"); - return "{$this->url}?cmd=attach&broker={$this->broker}&token=$token&checksum=$checksum"; - } - - - /** - * Login at sso server. - * - * @param string $username - * @param string $password - * @return boolean - */ - public function login($username=null, $password=null) - { - if (!isset($username) && isset($_REQUEST['username'])) $username=$_REQUEST['username']; - if (!isset($password) && isset($_REQUEST['password'])) $password=$_REQUEST['password']; - - list($ret, $body) = $this->serverCmd('login', array('username'=>$username, 'password'=>$password)); - - switch ($ret) { - case 200: $this->parseInfo($body); - return 1; - case 401: if ($this->pass401) header("HTTP/1.1 401 Unauthorized"); - return 0; - default: throw new Exception("SSO failure: The server responded with a $ret status" . (!empty($body) ? ': "' . substr(str_replace("\n", " ", trim(strip_tags($body))), 0, 256) .'".' : '.')); - } - } - - /** - * Logout at sso server. - */ - public function logout() - { - list($ret, $body) = $this->serverCmd('logout'); - if ($ret != 200) throw new Exception("SSO failure: The server responded with a $ret status" . (!empty($body) ? ': "' . substr(str_replace("\n", " ", trim(strip_tags($body))), 0, 256) .'".' : '.')); - - return true; - } - - - /** - * Set user info from user XML - * - * @param string $xml - */ - protected function parseInfo($xml) - { - $sxml = new SimpleXMLElement($xml); - - $this->userinfo['identity'] = $sxml['identity']; - foreach ($sxml as $key=>$value) $this->userinfo[$key] = (string)$value; - } - - /** - * Get user information. - */ - public function getInfo() - { - if (!isset($this->userinfo)) { - list($ret, $body) = $this->serverCmd('info'); - - switch ($ret) { - case 200: $this->parseInfo($body); break; - case 401: if ($this->pass401) header("HTTP/1.1 401 Unauthorized"); - $this->userinfo = false; break; - default: throw new Exception("SSO failure: The server responded with a $ret status" . (!empty($body) ? ': "' . substr(str_replace("\n", " ", trim(strip_tags($body))), 0, 256) .'".' : '.')); - } - } - - return $this->userinfo; - } - - /** - * Ouput user information as XML - */ - public function info() - { - $this->getInfo(); - - if (!$this->userinfo) { - header("HTTP/1.0 401 Unauthorized"); - echo "Not logged in"; - exit; - } - - header('Content-type: text/xml; charset=UTF-8'); - echo '<?xml version="1.0" encoding="UTF-8" ?>', "\n"; - echo '<user identity="' . htmlspecialchars($this->userinfo['identity'], ENT_COMPAT, 'UTF-8') . '">', "\n"; - - foreach ($this->userinfo as $key=>$value) { - if ($key == 'identity') continue; - echo "<$key>", htmlspecialchars($value, ENT_COMPAT, 'UTF-8'), "</$key>", "\n"; - } - - echo '</user>'; - } - - - /** - * Execute on SSO server. - * - * @param string $cmd Command - * @param array $vars Post variables - * @return array - */ - protected function serverCmd($cmd, $vars=null) - { - $curl = curl_init($this->url . '?cmd=' . urlencode($cmd)); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); - curl_setopt($curl, CURLOPT_COOKIE, "PHPSESSID=" . $this->getSessionId()); - - if (isset($vars)) { - curl_setopt($curl, CURLOPT_POST, true); - curl_setopt($curl, CURLOPT_POSTFIELDS, $vars); - } - - curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); - - $body = curl_exec($curl); - $ret = curl_getinfo($curl, CURLINFO_HTTP_CODE); - if (curl_errno($curl) != 0) throw new Exception("SSO failure: HTTP request to server failed. " . curl_error($curl)); - - return array($ret, $body); - } -} - -// Execute controller command -if (realpath($_SERVER["SCRIPT_FILENAME"]) == realpath(__FILE__) && isset($_GET['cmd'])) { - $ctl = new SingleSignOn_Broker(false); - $ctl->pass401 = true; - $ret = $ctl->$_GET['cmd'](); - - if (is_scalar($ret)) echo $ret; -} diff --git a/broker/index.php b/broker/index.php deleted file mode 100644 index 782de2e..0000000 --- a/broker/index.php +++ /dev/null @@ -1,29 +0,0 @@ -<?php -require_once("sso.php"); - -$sso = new SingleSignOn_Broker(); -$user = $sso->getInfo(); - -if (!$user) { - header("Location: login.php", true, 307); - exit; -} - -?> - -<html> - <head> - <title>Single Sign-On demo (<?= $sso->broker ?>)</title> - </head> - <body> - <h1>Single Sign-On demo</h1> - <h2><?= $sso->broker ?></h2> - - <dl> - <? foreach($user as $key=>$value) : ?> - <dt><?= $key ?></dt><dd><?= $value ?></dd> - <? endforeach; ?> - </dl> - <a href="login.php?logout=1">Logout</a> - </body> -</html> diff --git a/broker/login.php b/broker/login.php deleted file mode 100644 index c65eb3d..0000000 --- a/broker/login.php +++ /dev/null @@ -1,34 +0,0 @@ -<?php -require_once("sso.php"); - -$sso = new SingleSignOn_Broker(); - -if (!empty($_GET['logout'])) { - $sso->logout(); -} elseif ($sso->getInfo() || ($_SERVER['REQUEST_METHOD'] == 'POST' && $sso->login())) { - header("Location: index.php", true, 303); - exit; -} - -if ($_SERVER['REQUEST_METHOD'] == 'POST') $errmsg = "Login failed"; - -?> - -<html> - <head> - <title>Single Sign-On demo (<?= $sso->broker ?>) - Login</title> - </head> - <body> - <h1>Single Sign-On demo - Login</h1> - <h2><?= $sso->broker ?></h2> - - <? if (isset($errmsg)): ?><div style="color:red"><?= $errmsg ?></div><? endif; ?> - <form action="login.php" method="POST"> - <table> - <tr><td>Username</td><td><input type="text" name="username" /></td></tr> - <tr><td>Password</td><td><input type="password" name="password" /></td></tr> - <tr><td></td><td><input type="submit" value="Login" /></td></tr> - </table> - </form> - </body> -</html> diff --git a/broker/sso.php b/broker/sso.php deleted file mode 100644 index c43da27..0000000 --- a/broker/sso.php +++ /dev/null @@ -1,229 +0,0 @@ -<?php -/** - * Helper class for broker of single sign-on - */ -class SingleSignOn_Broker -{ - /** - * Pass 401 http response of the server to the client - */ - public $pass401=false; - - /** - * Url of SSO server - * @var string - */ - public $url = "http://sso-server.adaniels.nl/sso.php"; - - /** - * My identifier, given by SSO provider. - * @var string - */ - public $broker = "LYNX"; - - /** - * My secret word, given by SSO provider. - * @var string - */ - public $secret = "klm345"; - - /** - * Need to be shorter than session expire of SSO server - * @var string - */ - public $sessionExpire = 1800; - - /** - * Session hash - * @var string - */ - protected $sessionToken; - - /** - * User info recieved from the server. - * @var array - */ - protected $userinfo; - - - /** - * Class constructor - */ - public function __construct($auto_attach=true) - { - if (isset($_COOKIE['session_token'])) $this->sessionToken = $_COOKIE['session_token']; - - if ($auto_attach && !isset($this->sessionToken)) { - header("Location: " . $this->getAttachUrl() . "&redirect=". urlencode("http://{$_SERVER["SERVER_NAME"]}{$_SERVER["REQUEST_URI"]}"), true, 307); - exit; - } - } - - /** - * Get session token - * - * @return string - */ - public function getSessionToken() - { - if (!isset($this->sessionToken)) { - $this->sessionToken = md5(uniqid(rand(), true)); - setcookie('session_token', $this->sessionToken, time() + $this->sessionExpire); - } - - return $this->sessionToken; - } - - /** - * Generate session id from session key - * - * @return string - */ - protected function getSessionId() - { - if (!isset($this->sessionToken)) return null; - return "SSO-{$this->broker}-{$this->sessionToken}-" . md5('session' . $this->sessionToken . $_SERVER['REMOTE_ADDR'] . $this->secret); - } - - /** - * Get URL to attach session at SSO server - * - * @return string - */ - public function getAttachUrl() - { - $token = $this->getSessionToken(); - $checksum = md5("attach{$token}{$_SERVER['REMOTE_ADDR']}{$this->secret}"); - return "{$this->url}?cmd=attach&broker={$this->broker}&token=$token&checksum=$checksum"; - } - - - /** - * Login at sso server. - * - * @param string $username - * @param string $password - * @return boolean - */ - public function login($username=null, $password=null) - { - if (!isset($username) && isset($_REQUEST['username'])) $username=$_REQUEST['username']; - if (!isset($password) && isset($_REQUEST['password'])) $password=$_REQUEST['password']; - - list($ret, $body) = $this->serverCmd('login', array('username'=>$username, 'password'=>$password)); - - switch ($ret) { - case 200: $this->parseInfo($body); - return 1; - case 401: if ($this->pass401) header("HTTP/1.1 401 Unauthorized"); - return 0; - default: throw new Exception("SSO failure: The server responded with a $ret status" . (!empty($body) ? ': "' . substr(str_replace("\n", " ", trim(strip_tags($body))), 0, 256) .'".' : '.')); - } - } - - /** - * Logout at sso server. - */ - public function logout() - { - list($ret, $body) = $this->serverCmd('logout'); - if ($ret != 200) throw new Exception("SSO failure: The server responded with a $ret status" . (!empty($body) ? ': "' . substr(str_replace("\n", " ", trim(strip_tags($body))), 0, 256) .'".' : '.')); - - return true; - } - - - /** - * Set user info from user XML - * - * @param string $xml - */ - protected function parseInfo($xml) - { - $sxml = new SimpleXMLElement($xml); - - $this->userinfo['identity'] = $sxml['identity']; - foreach ($sxml as $key=>$value) $this->userinfo[$key] = (string)$value; - } - - /** - * Get user information. - */ - public function getInfo() - { - if (!isset($this->userinfo)) { - list($ret, $body) = $this->serverCmd('info'); - - switch ($ret) { - case 200: $this->parseInfo($body); break; - case 401: if ($this->pass401) header("HTTP/1.1 401 Unauthorized"); - $this->userinfo = false; break; - default: throw new Exception("SSO failure: The server responded with a $ret status" . (!empty($body) ? ': "' . substr(str_replace("\n", " ", trim(strip_tags($body))), 0, 256) .'".' : '.')); - } - } - - return $this->userinfo; - } - - /** - * Ouput user information as XML - */ - public function info() - { - $this->getInfo(); - - if (!$this->userinfo) { - header("HTTP/1.0 401 Unauthorized"); - echo "Not logged in"; - exit; - } - - header('Content-type: text/xml; charset=UTF-8'); - echo '<?xml version="1.0" encoding="UTF-8" ?>', "\n"; - echo '<user identity="' . htmlspecialchars($this->userinfo['identity'], ENT_COMPAT, 'UTF-8') . '">', "\n"; - - foreach ($this->userinfo as $key=>$value) { - if ($key == 'identity') continue; - echo "<$key>", htmlspecialchars($value, ENT_COMPAT, 'UTF-8'), "</$key>", "\n"; - } - - echo '</user>'; - } - - - /** - * Execute on SSO server. - * - * @param string $cmd Command - * @param array $vars Post variables - * @return array - */ - protected function serverCmd($cmd, $vars=null) - { - $curl = curl_init($this->url . '?cmd=' . urlencode($cmd)); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); - curl_setopt($curl, CURLOPT_COOKIE, "PHPSESSID=" . $this->getSessionId()); - - if (isset($vars)) { - curl_setopt($curl, CURLOPT_POST, true); - curl_setopt($curl, CURLOPT_POSTFIELDS, $vars); - } - - curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); - - $body = curl_exec($curl); - $ret = curl_getinfo($curl, CURLINFO_HTTP_CODE); - if (curl_errno($curl) != 0) throw new Exception("SSO failure: HTTP request to server failed. " . curl_error($curl)); - - return array($ret, $body); - } -} - -// Execute controller command -if (realpath($_SERVER["SCRIPT_FILENAME"]) == realpath(__FILE__) && isset($_GET['cmd'])) { - $ctl = new SingleSignOn_Broker(false); - $ctl->pass401 = true; - $ret = $ctl->$_GET['cmd'](); - - if (is_scalar($ret)) echo $ret; -} diff --git a/codeception.yml b/codeception.yml new file mode 100644 index 0000000..3a8fca8 --- /dev/null +++ b/codeception.yml @@ -0,0 +1,21 @@ +actor: Tester +paths: + tests: tests + log: tests/_output + data: tests/_data + support: tests/_support + envs: tests/_envs +settings: + bootstrap: _bootstrap.php + colors: true + memory_limit: 1024M +extensions: + enabled: + - Codeception\Extension\RunFailed +modules: + config: + Db: + dsn: '' + user: '' + password: '' + dump: tests/_data/dump.sql diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..367e3fe --- /dev/null +++ b/composer.json @@ -0,0 +1,32 @@ +{ + "name": "jasny/sso", + "description": "Simple Single Sign-On", + "keywords": ["sso", "auth"], + "license": "MIT", + "homepage": "http://www.jasny.net/articles/simple-single-sign-on-for-php/", + "authors": [ + { + "name": "Arnold Daniels", + "email": "arnold@jasny.net", + "homepage": "http://www.jasny.net" + } + ], + "support": { + "issues": "https://github.com/jasny/sso/issues", + "source": "https://github.com/jasny/sso" + }, + "require": { + "php": ">=5.3.0", + "codeception/codeception": "*", + "desarrolla2/cache": "dev-master", + "jasny/validation-result": "^0.1.1" + }, + "autoload": { + "psr-4": { + "Jasny\\SSO\\": "src/" + } + }, + "require-dev": { + "jasny/php-code-quality": "^1.1" + } +} diff --git a/diagrams.odg b/diagrams.odg Binary files differdeleted file mode 100644 index 4ec65ee..0000000 --- a/diagrams.odg +++ /dev/null diff --git a/examples/ajax-broker/api.php b/examples/ajax-broker/api.php new file mode 100644 index 0000000..996b813 --- /dev/null +++ b/examples/ajax-broker/api.php @@ -0,0 +1,38 @@ +<?php + +require_once __DIR__ . '/../../vendor/autoload.php'; + +$broker = new Jasny\SSO\Broker(getenv('SSO_SERVER'), getenv('SSO_BROKER_ID'), getenv('SSO_BROKER_SECRET')); + +if (empty($_REQUEST['command']) || !method_exists($broker, $_REQUEST['command'])) { + header("Content-Type: application/json"); + header("HTTP/1.1 400 Bad Request"); + echo json_encode(['error' => 'Command not specified']); + exit(); +} + +try { + $result = $broker->{$_REQUEST['command']}(); +} catch (Exception $e) { + $status = $e->getCode() ?: 500; + $result = ['error' => $e->getMessage()]; +} + +// JSONP +if (!empty($_GET['callback'])) { + if (!isset($result)) $result = null; + if (!isset($status)) $status = isset($result) ? 200 : 204; + + header('Content-Type: application/javascript'); + echo $_GET['callback'] . '(' . json_encode($result) . ', ' . $status . ')'; + return; +} + +// REST +if (!$result) { + http_response_code(204); +} else { + http_response_code(isset($status) ? $status : 200); + header("Content-Type: application/json"); + echo json_encode($result); +} diff --git a/examples/ajax-broker/app.js b/examples/ajax-broker/app.js new file mode 100644 index 0000000..7a627c9 --- /dev/null +++ b/examples/ajax-broker/app.js @@ -0,0 +1,107 @@ ++function($) { + // Init + attach(); + + /** + * Attach session. + * Will redirect to SSO server. + */ + function attach() { + var req = $.ajax({ + url: 'api.php?command=attach', + crossDomain: true, + dataType: 'jsonp' + }); + + req.done(function(data, code) { + if (code && code >= 400) { // jsonp failure + showError(data.error); + return; + } + + loadUserInfo(); + }); + + req.fail(function(jqxhr) { + showError(jqxhr.responseJSON || jqxhr.textResponse) + }); + } + + /** + * Do an AJAX request to the API + * + * @param command API command + * @param params POST data + * @param callback Callback function + */ + function doApiRequest(command, params, callback) { + var req = $.ajax({ + url: 'api.php?command=' + command, + method: params ? 'POST' : 'GET', + data: params, + dataType: 'json' + }); + + req.done(callback); + + req.fail(function(jqxhr) { + showError(jqxhr.responseJSON || jqxhr.textResponse); + }); + } + + /** + * Display the error message + * + * @param data + */ + function showError(data) { + var message = typeof data === 'object' && data.error ? data.error : 'Unexpected error'; + $('#error').text(message).show(); + } + + /** + * Load and display user info + */ + function loadUserInfo() { + doApiRequest('getUserinfo', null, showUserInfo); + } + + /** + * Display user info + * + * @param info + */ + function showUserInfo(info) { + $('body').removeClass('anonymous authenticated'); + $('#user-info').html(''); + + if (info) { + for (var key in info) { + $('#user-info').append($('<dt>').text(key)); + $('#user-info').append($('<dd>').text(info[key])); + } + } + + $('body').addClass(info ? 'authenticated' : 'anonymous'); + } + + /** + * Submit login form through AJAX + */ + $('#login-form').on('submit', function(e) { + e.preventDefault(); + + $('#error').text('').hide(); + + var data = { + username: this.username.value, + password: this.password.value + }; + + doApiRequest('login', data, showUserInfo); + }); + + $('#logout').on('click', function() { + doApiRequest('logout', {}, function() { showUserInfo(null); }); + }) +}(jQuery); diff --git a/examples/ajax-broker/index.html b/examples/ajax-broker/index.html new file mode 100644 index 0000000..8b8a98b --- /dev/null +++ b/examples/ajax-broker/index.html @@ -0,0 +1,56 @@ +<!doctype html> +<html> + <head> + <title>Single Sign-On Ajax demo</title> + <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"> + + <style> + .state { + display: none; + } + body.anonymous .state.anonymous, + body.authenticated .state.authenticated { + display: initial; + } + </style> + </head> + <body> + <div class="container"> + <h1>Single Sign-On Ajax demo</h1> + + <div id="error" class="alert alert-danger" style="display: none;"></div> + + <form id="login-form" class="form-horizontal state anonymous"> + <div class="form-group"> + <label for="inputUsername" class="col-sm-2 control-label">Username</label> + <div class="col-sm-10"> + <input type="text" name="username" class="form-control" id="inputUsername"> + </div> + </div> + <div class="form-group"> + <label for="inputPassword" class="col-sm-2 control-label">Password</label> + <div class="col-sm-10"> + <input type="password" name="password" class="form-control" id="inputPassword"> + </div> + </div> + + <div class="form-group"> + <div class="col-sm-offset-2 col-sm-10"> + <button type="submit" class="btn btn-default">Login</button> + </div> + </div> + </form> + + <div class="state authenticated"> + <h3>Logged in</h3> + <dl id="user-info" class="dl-horizontal"></dl> + + <a id="logout" class="btn btn-default">Logout</a> + </div> + </div> + + <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script> + <script src="app.js"></script> + </body> +</html> + diff --git a/examples/broker/error.php b/examples/broker/error.php new file mode 100644 index 0000000..52c7a53 --- /dev/null +++ b/examples/broker/error.php @@ -0,0 +1,25 @@ +<?php +require_once __DIR__ . '/../../vendor/autoload.php'; + +$broker = new Jasny\SSO\Broker(getenv('SSO_SERVER'), getenv('SSO_BROKER_ID'), getenv('SSO_BROKER_SECRET')); +$error = $_GET['sso_error']; + +?> +<!doctype html> +<html> + <head> + <title>Single Sign-On demo (<?= $broker->broker ?>)</title> + <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"> + </head> + <body> + <div class="container"> + <h1>Single Sign-On demo <small>(<?= $broker->broker ?>)</small></h1> + + <div class="alert alert-danger"> + <?= $error ?> + </div> + + <a href="/">Try again</a> + </div> + </body> +</html> diff --git a/examples/broker/index.php b/examples/broker/index.php new file mode 100644 index 0000000..2a5f12d --- /dev/null +++ b/examples/broker/index.php @@ -0,0 +1,39 @@ +<?php +require_once __DIR__ . '/../../vendor/autoload.php'; + +if (isset($_GET['sso_error'])) { + header("Location: error.php?sso_error=" . $_GET['sso_error'], true, 307); + exit; +} + +$broker = new Jasny\SSO\Broker(getenv('SSO_SERVER'), getenv('SSO_BROKER_ID'), getenv('SSO_BROKER_SECRET')); +$broker->attach(true); + +$user = $broker->getUserInfo(); + +if (!$user) { + header("Location: login.php", true, 307); + exit; +} +?> +<!doctype html> +<html> + <head> + <title><?= $broker->broker ?> (Single Sign-On demo)</title> + <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"> + </head> + <body> + <div class="container"> + <h1><?= $broker->broker ?> <small>(Single Sign-On demo)</small></h1> + <h3>Logged in</h3> + + <dl class="dl-horizontal"> + <?php foreach ($user as $key => $value) : ?> + <dt><?= $key ?></dt><dd><?= $value ?></dd> + <?php endforeach; ?> + </dl> + + <a id="logout" class="btn btn-default" href="login.php?logout=1">Logout</a> + </div> + </body> +</html> diff --git a/examples/broker/login.php b/examples/broker/login.php new file mode 100644 index 0000000..e51fe39 --- /dev/null +++ b/examples/broker/login.php @@ -0,0 +1,56 @@ +<?php +require_once __DIR__ . '/../../vendor/autoload.php'; + +$broker = new Jasny\SSO\Broker(getenv('SSO_SERVER'), getenv('SSO_BROKER_ID'), getenv('SSO_BROKER_SECRET')); +$broker->attach(); + +if (!empty($_GET['logout'])) { + $broker->logout(); +} elseif ($broker->getUserInfo() || ($_SERVER['REQUEST_METHOD'] == 'POST' && $broker->login($_POST['username'], $_POST['password']))) { + header("Location: index.php", true, 303); + exit; +} + +if ($_SERVER['REQUEST_METHOD'] == 'POST') $errmsg = "Login failed"; +?> +<!doctype html> +<html> + <head> + <title><?= $broker->broker ?> | Login (Single Sign-On demo)</title> + <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"> + + <style> + h1 { + margin-bottom: 30px; + } + </style> + </head> + <body> + <div class="container"> + <h1><?= $broker->broker ?> <small>(Single Sign-On demo)</small></h1> + + <?php if (isset($errmsg)): ?><div class="alert alert-danger"><?= $errmsg ?></div><?php endif; ?> + + <form class="form-horizontal" action="login.php" method="post"> + <div class="form-group"> + <label for="inputUsername" class="col-sm-2 control-label">Username</label> + <div class="col-sm-10"> + <input type="text" name="username" class="form-control" id="inputUsername"> + </div> + </div> + <div class="form-group"> + <label for="inputPassword" class="col-sm-2 control-label">Password</label> + <div class="col-sm-10"> + <input type="password" name="password" class="form-control" id="inputPassword"> + </div> + </div> + + <div class="form-group"> + <div class="col-sm-offset-2 col-sm-10"> + <button type="submit" class="btn btn-default">Login</button> + </div> + </div> + </form> + </div> + </body> +</html> diff --git a/examples/server/.htaccess b/examples/server/.htaccess new file mode 100644 index 0000000..7bb4b5b --- /dev/null +++ b/examples/server/.htaccess @@ -0,0 +1,6 @@ +RewriteEngine On + +RewriteCond %{REQUEST_FILENAME} !-d +RewriteCond %{REQUEST_FILENAME} !-f +RewriteRule (.+) index.php?command=$1 [L] + diff --git a/examples/server/MySSOServer.php b/examples/server/MySSOServer.php new file mode 100644 index 0000000..ca523b0 --- /dev/null +++ b/examples/server/MySSOServer.php @@ -0,0 +1,90 @@ +<?php + +use Jasny\ValidationResult; +use Jasny\SSO; + +/** + * Example SSO server. + * + * Normally you'd fetch the broker info and user info from a database, rather then declaring them in the code. + */ +class MySSOServer extends SSO\Server +{ + /** + * Registered brokers + * @var array + */ + private static $brokers = [ + 'Alice' => ['secret'=>'8iwzik1bwd'], + 'Greg' => ['secret'=>'7pypoox2pc'], + 'Julias' => ['secret'=>'ceda63kmhp'] + ]; + + /** + * System users + * @var array + */ + private static $users = array ( + 'jackie' => [ + 'fullname' => 'Jackie Black', + 'email' => 'jackie.black@example.com', + 'password' => '$2y$10$lVUeiphXLAm4pz6l7lF9i.6IelAqRxV4gCBu8GBGhCpaRb6o0qzUO' // jackie123 + ], + 'john' => [ + 'fullname' => 'John Doe', + 'email' => 'john.doe@example.com', + 'password' => '$2y$10$RU85KDMhbh8pDhpvzL6C5.kD3qWpzXARZBzJ5oJ2mFoW7Ren.apC2' // john123 + ], + ); + + /** + * Get the API secret of a broker and other info + * + * @param string $brokerId + * @return array + */ + protected function getBrokerInfo($brokerId) + { + return isset(self::$brokers[$brokerId]) ? self::$brokers[$brokerId] : null; + } + + /** + * Authenticate using user credentials + * + * @param string $username + * @param string $password + * @return ValidationResult + */ + protected function authenticate($username, $password) + { + if (!isset($username)) { + return ValidationResult::error("username isn't set"); + } + + if (!isset($password)) { + return ValidationResult::error("password isn't set"); + } + + if (!isset(self::$users[$username]) || !password_verify($password, self::$users[$username]['password'])) { + return ValidationResult::error("Invalid credentials"); + } + + return ValidationResult::success(); + } + + + /** + * Get the user information + * + * @return array + */ + protected function getUserInfo($username) + { + if (!isset(self::$users[$username])) return null; + + $user = compact('username') + self::$users[$username]; + unset($user['password']); + + return $user; + } +} diff --git a/examples/server/index.php b/examples/server/index.php new file mode 100644 index 0000000..5416eb9 --- /dev/null +++ b/examples/server/index.php @@ -0,0 +1,18 @@ +<?php + +require_once __DIR__ . '/../../vendor/autoload.php'; +require_once 'MySSOServer.php'; + +$ssoServer = new MySSOServer(); +$command = isset($_REQUEST['command']) ? $_REQUEST['command'] : null; + +if (!$command || !method_exists($ssoServer, $command)) { + header("HTTP/1.1 404 Not Found"); + header('Content-type: application/json; charset=UTF-8'); + + echo json_encode(['error' => 'Unknown command']); + exit(); +} + +$result = $ssoServer->$command(); + diff --git a/server/empty.png b/server/empty.png Binary files differdeleted file mode 100644 index 61dc432..0000000 --- a/server/empty.png +++ /dev/null diff --git a/server/sso.php b/server/sso.php deleted file mode 100644 index 95a4114..0000000 --- a/server/sso.php +++ /dev/null @@ -1,238 +0,0 @@ -<?php - -/** - * A simple single sign-on server using PHP session linking. - * Don't use session.auto_start or session_start(). - */ -class SingleSignOn_Server -{ - /** - * Path to link files. Set this to use link files instead of symlinks. - * Don't forget to clean up old session files once in a while. - * - * @var string - */ - public $links_path; - - /** - * Flag to indicate the sessionStart has been called - * @var boolean - */ - protected $started=false; - - /** - * Information of the brokers. - * This should be data in a database. - * - * @var array - */ - protected static $brokers = array( - 'ALEX' => array('secret'=>"abc123"), - 'BINCK' => array('secret'=>"xyz789"), - 'UZZA' => array('secret'=>"rino222"), - 'AJAX' => array('secret'=>"amsterdam"), - 'LYNX' => array('secret'=>"klm345"), - ); - - /** - * Information of the users. - * This should be data in a database. - * - * @var array - */ - protected static $users = array( - 'jan' => array('password'=>"jan1", 'fullname'=>"Jan Smit", 'email'=>"jan@smit.nl"), - 'peter' => array('password'=>"peter1", 'fullname'=>"Peter de Vries", 'email'=>"peter.r.de-vries@sbs.nl"), - 'bart' => array('password'=>"bart1", 'fullname'=>"Bart de Graaf", 'email'=>"graaf@bnn.info"), - 'henk' => array('password'=>"henk1", 'fullname'=>"Henk Westbroek", 'email'=>"henk@amsterdam.com") - ); - - /** - * The current broker - * @var string - */ - protected $broker = null; - - - /** - * Class constructor. - */ - public function __construct() - { - if (!function_exists('symlink')) $this->links_path = sys_get_temp_dir(); - } - - /** - * Start session and protect against session hijacking - */ - protected function sessionStart() - { - if ($this->started) return; - $this->started = true; - - // Broker session - $matches = null; - if (isset($_REQUEST[session_name()]) && preg_match('/^SSO-(\w*+)-(\w*+)-([a-z0-9]*+)$/', $_REQUEST[session_name()], $matches)) { - $sid = $_REQUEST[session_name()]; - - if (isset($this->links_path) && file_exists("{$this->links_path}/$sid")) { - session_id(file_get_contents("{$this->links_path}/$sid")); - session_start(); - setcookie(session_name(), "", 1); - } else { - session_start(); - } - - if (!isset($_SESSION['client_addr'])) { - session_destroy(); - $this->fail("Not attached"); - } - - if ($this->generateSessionId($matches[1], $matches[2], $_SESSION['client_addr']) != $sid) { - session_destroy(); - $this->fail("Invalid session id"); - } - - $this->broker = $matches[1]; - return; - } - - // User session - session_start(); - if (isset($_SESSION['client_addr']) && $_SESSION['client_addr'] != $_SERVER['REMOTE_ADDR']) session_regenerate_id(true); - if (!isset($_SESSION['client_addr'])) $_SESSION['client_addr'] = $_SERVER['REMOTE_ADDR']; - } - - /** - * Generate session id from session token - * - * @return string - */ - protected function generateSessionId($broker, $token, $client_addr=null) - { - if (!isset(self::$brokers[$broker])) return null; - - if (!isset($client_addr)) $client_addr = $_SERVER['REMOTE_ADDR']; - return "SSO-{$broker}-{$token}-" . md5('session' . $token . $client_addr . self::$brokers[$broker]['secret']); - } - - /** - * Generate session id from session token - * - * @return string - */ - protected function generateAttachChecksum($broker, $token) - { - if (!isset(self::$brokers[$broker])) return null; - return md5('attach' . $token . $_SERVER['REMOTE_ADDR'] . self::$brokers[$broker]['secret']); - } - - /** - * Authenticate - */ - public function login() - { - $this->sessionStart(); - - if (empty($_POST['username'])) $this->failLogin("No user specified"); - if (empty($_POST['password'])) $this->failLogin("No password specified"); - - if (!isset(self::$users[$_POST['username']]) || self::$users[$_POST['username']]['password'] != $_POST['password']) $this->failLogin("Incorrect credentials"); - - $_SESSION['user'] = $_POST['username']; - $this->info(); - } - - /** - * Log out - */ - public function logout() - { - $this->sessionStart(); - unset($_SESSION['user']); - echo 1; - } - - - /** - * Attach a user session to a broker session - */ - public function attach() - { - $this->sessionStart(); - - if (empty($_REQUEST['broker'])) $this->fail("No broker specified"); - if (empty($_REQUEST['token'])) $this->fail("No token specified"); - if (empty($_REQUEST['checksum']) || $this->generateAttachChecksum($_REQUEST['broker'], $_REQUEST['token']) != $_REQUEST['checksum']) $this->fail("Invalid checksum"); - - if (!isset($this->links_path)) { - $link = (session_save_path() ? session_save_path() : sys_get_temp_dir()) . "/sess_" . $this->generateSessionId($_REQUEST['broker'], $_REQUEST['token']); - if (!file_exists($link)) $attached = symlink('sess_' . session_id(), $link); - if (!$attached) trigger_error("Failed to attach; Symlink wasn't created.", E_USER_ERROR); - } else { - $link = "{$this->links_path}/" . $this->generateSessionId($_REQUEST['broker'], $_REQUEST['token']); - if (!file_exists($link)) $attached = file_put_contents($link, session_id()); - if (!$attached) trigger_error("Failed to attach; Link file wasn't created.", E_USER_ERROR); - } - - if (isset($_REQUEST['redirect'])) { - header("Location: " . $_REQUEST['redirect'], true, 307); - exit; - } - - // Output an image specially for AJAX apps - header("Content-Type: image/png"); - readfile("empty.png"); - } - - /** - * Ouput user information as XML. - * Doesn't return e-mail address to brokers with security level < 2. - */ - public function info() - { - $this->sessionStart(); - if (!isset($_SESSION['user'])) $this->failLogin("Not logged in"); - - header('Content-type: text/xml; charset=UTF-8'); - echo '<?xml version="1.0" encoding="UTF-8" ?>', "\n"; - - echo '<user identity="' . htmlspecialchars($_SESSION['user'], ENT_COMPAT, 'UTF-8') . '">'; - echo ' <fullname>' . htmlspecialchars(self::$users[$_SESSION['user']]['fullname'], ENT_COMPAT, 'UTF-8') . '</fullname>'; - echo ' <email>' . htmlspecialchars(self::$users[$_SESSION['user']]['email'], ENT_COMPAT, 'UTF-8') . '</email>'; - echo '</user>'; - } - - - /** - * An error occured. - * I would normaly solve this by throwing an Exception and use an exception handler. - * - * @param string $message - */ - protected function fail($message) - { - header("HTTP/1.1 406 Not Acceptable"); - echo $message; - exit; - } - - /** - * Login failure. - * I would normaly solve this by throwing a LoginException and use an exception handler. - * - * @param string $message - */ - protected function failLogin($message) - { - header("HTTP/1.1 401 Unauthorized"); - echo $message; - exit; - } -} - -// Execute controller command -if (realpath($_SERVER["SCRIPT_FILENAME"]) == realpath(__FILE__) && isset($_GET['cmd'])) { - $ctl = new SingleSignOn_Server(); - $ctl->$_GET['cmd'](); -} diff --git a/src/Broker.php b/src/Broker.php new file mode 100644 index 0000000..a9ffdd7 --- /dev/null +++ b/src/Broker.php @@ -0,0 +1,252 @@ +<?php +namespace Jasny\SSO; + +use Jasny\ValidationResult; + +/** + * Single sign-on broker. + * + * The broker lives on the website visited by the user. The broken doesn't have any user credentials stored. Instead it + * will talk to the SSO server in name of the user, verifying credentials and getting user information. + */ +class Broker +{ + /** + * Url of SSO server + * @var string + */ + protected $url; + + /** + * My identifier, given by SSO provider. + * @var string + */ + public $broker; + + /** + * My secret word, given by SSO provider. + * @var string + */ + protected $secret; + + /** + * Session token of the client + * @var string + */ + public $token; + + /** + * User info recieved from the server. + * @var array + */ + protected $userinfo; + + + /** + * Class constructor + * + * @param string $url Url of SSO server + * @param string $broker My identifier, given by SSO provider. + * @param string $secret My secret word, given by SSO provider. + */ + public function __construct($url, $broker, $secret) + { + if (!$url) throw new \InvalidArgumentException("SSO server URL not specified"); + if (!$broker) throw new \InvalidArgumentException("SSO broker id not specified"); + if (!$secret) throw new \InvalidArgumentException("SSO broker secret not specified"); + + $this->url = $url; + $this->broker = $broker; + $this->secret = $secret; + + if (isset($_COOKIE[$this->getCookieName()])) $this->token = $_COOKIE[$this->getCookieName()]; + } + + /** + * Get the cookie name. + * + * Note: Using the broker name in the cookie name. + * This resolves issues when multiple brokers are on the same domain. + * + * @return string + */ + protected function getCookieName() + { + return 'sso_token_' . strtolower($this->broker); + } + + /** + * Generate session id from session key + * + * @return string + */ + protected function getSessionId() + { + if (!$this->token) return null; + + $checksum = hash('sha256', 'session' . $this->token . $_SERVER['REMOTE_ADDR'] . $this->secret); + return "SSO-{$this->broker}-{$this->token}-$checksum"; + } + + /** + * Generate session token + */ + public function generateToken() + { + if (isset($this->token)) return; + + $this->token = base_convert(md5(uniqid(rand(), true)), 16, 36); + setcookie($this->getCookieName(), $this->token, time() + 3600); + } + + /** + * Check if we have an SSO token. + * + * @return boolean + */ + public function isAttached() + { + return isset($this->token); + } + + /** + * Get URL to attach session at SSO server. + * + * @param array $params + * @return string + */ + public function getAttachUrl($params = []) + { + $this->generateToken(); + + $data = [ + 'command' => 'attach', + 'broker' => $this->broker, + 'token' => $this->token, + 'checksum' => hash('sha256', 'attach' . $this->token . $_SERVER['REMOTE_ADDR'] . $this->secret) + ] + $_GET; + + return $this->url . "?" . http_build_query($data + $params); + } + + /** + * Attach our session to the user's session on the SSO server. + * + * @param string|true $returnUrl The URL the client should be returned to after attaching + */ + public function attach($returnUrl = null) + { + if ($this->isAttached()) return; + + if ($returnUrl === true) { + $protocol = !empty($_SERVER['HTTPS']) ? 'https://' : 'http://'; + $returnUrl = $protocol . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; + } + + $params = ['return_url' => $returnUrl]; + $url = $this->getAttachUrl($params); + + header("Location: $url", true, 307); + echo "You're redirected to <a href='$url'>$url</a>"; + exit(); + } + + /** + * Get the request url for a command + * + * @param string $command + * @param array $params Query parameters + * @return string + */ + protected function getRequestUrl($command, $params = []) + { + $params['command'] = $command; + $params['sso_session'] = $this->getSessionId(); + + return $this->url . '?' . http_build_query($params); + } + + /** + * Execute on SSO server. + * + * @param string $method HTTP method: 'GET', 'POST', 'DELETE' + * @param string $command Command + * @param array|string $data Query or post parameters + * @return array|object + */ + protected function request($method, $command, $data = null) + { + $url = $this->getRequestUrl($command, !$data || $method === 'POST' ? [] : $data); + + $ch = curl_init($url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); + + if ($method === 'POST' && !empty($data)) { + $post = is_string($data) ? $data : http_build_query($data); + curl_setopt($ch, CURLOPT_POSTFIELDS, $post); + } + + $response = curl_exec($ch); + if (curl_errno($ch) != 0) { + throw new Exception("Server request failed: " . curl_error($ch), 500); + } + + $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); + list($contentType) = explode(';', curl_getinfo($ch, CURLINFO_CONTENT_TYPE)); + + if ($contentType != 'application/json') { + $message = "Expected application/json response, got $contentType"; + error_log($message . "\n\n" . $response); + throw new Exception($message, $httpCode); + } + + $data = json_decode($response, true); + if ($httpCode >= 400) throw new Exception($data['error'] ?: $response, $httpCode); + + return $data; + } + + + /** + * Log the client in at the SSO server. + * + * Only brokers marked trused can collect and send the user's credentials. Other brokers should omit $username and + * $password. + * + * @param string $username + * @param string $password + * @return array user info + * @throws Exception if login fails eg due to incorrect credentials + */ + public function login($username = null, $password = null) + { + if (!isset($username) && isset($_POST['username'])) $username = $_POST['username']; + if (!isset($password) && isset($_POST['password'])) $password = $_POST['password']; + + $result = $this->request('POST', 'login', compact('username', 'password')); + $this->userinfo = $result; + + return $this->userinfo; + } + + /** + * Logout at sso server. + */ + public function logout() + { + $this->request('POST', 'logout'); + } + + /** + * Get user information. + */ + public function getUserInfo() + { + if (!isset($this->userinfo)) { + $this->userinfo = $this->request('GET', 'userInfo'); + } + + return $this->userinfo; + } +} diff --git a/src/Exception.php b/src/Exception.php new file mode 100644 index 0000000..3188b89 --- /dev/null +++ b/src/Exception.php @@ -0,0 +1,9 @@ +<?php +namespace Jasny\SSO; + +/** + * SSO Exception + */ +class Exception extends \Exception +{ +} diff --git a/src/Server.php b/src/Server.php new file mode 100644 index 0000000..bb0222a --- /dev/null +++ b/src/Server.php @@ -0,0 +1,337 @@ +<?php +namespace Jasny\SSO; + +require_once __DIR__ . '/../vendor/autoload.php'; + +use Desarrolla2\Cache\Cache; +use Desarrolla2\Cache\Adapter; + +/** + * Single sign-on server. + * + * The SSO server is responsible of managing users sessions which are available for brokers. + * + * To use the SSO server, extend this class and implement the abstract methods. + * This class may be used as controller in an MVC application. + */ +abstract class Server +{ + /** + * Cache that stores the special session data for the brokers. + * + * @var Cache + */ + protected $cache; + + /** + * @var string + */ + protected $returnType; + + + /** + * Class constructor + */ + public function __construct() + { + $this->cache = $this->createCacheAdapter(); + } + + /** + * Create a cache to store the broker session id. + * + * @return Cache + */ + protected function createCacheAdapter() + { + $adapter = new Adapter\File('/tmp'); + $adapter->setOption('ttl', 10 * 3600); + + return new Cache($adapter); + } + + + /** + * Start session and protect against session hijacking + */ + protected function startSession() + { + $matches = null; + + if ( + isset($_GET['sso_session']) + && preg_match('/^SSO-(\w*+)-(\w*+)-([a-z0-9]*+)$/', $_GET['sso_session'], $matches) + ) { + $this->startBrokerSession($_GET['sso_session'], $matches[1], $matches[2]); + } else { + $this->startUserSession(); + } + } + + /** + * Start the session for broker requests to the SSO server + */ + protected function startBrokerSession($sid, $brokerId, $token) + { + $linkedId = $this->cache->get($sid); + + if (!$linkedId) { + return $this->fail("The broker session id isn't attached to a user session", 403); + } + + if (session_status() === PHP_SESSION_ACTIVE) { + if ($linkedId !== session_id()) throw new \Exception("Session has already started."); + return; + } + + session_id($linkedId); + session_start(); + + if (!isset($_SESSION['client_addr'])) { + session_destroy(); + return $this->fail("Unknown client IP address for the attached session", 500); + } + + if ($this->generateSessionId($brokerId, $token, $_SESSION['client_addr']) != $sid) { + session_destroy(); + return $this->fail("Checksum failed: Client IP address may have changed", 403); + } + + $this->broker = $brokerId; + return; + } + + /** + * Start the session when a user visits the SSO server + */ + protected function startUserSession() + { + if (session_status() !== PHP_SESSION_ACTIVE) session_start(); + + if (isset($_SESSION['client_addr']) && $_SESSION['client_addr'] !== $_SERVER['REMOTE_ADDR']) { + session_regenerate_id(true); + } + + if (!isset($_SESSION['client_addr'])) { + $_SESSION['client_addr'] = $_SERVER['REMOTE_ADDR']; + } + } + + + /** + * Generate session id from session token + * + * @return string + */ + protected function generateSessionId($brokerId, $token, $client_addr = null) + { + $broker = $this->getBrokerInfo($brokerId); + + if (!isset($broker)) return null; + if (!isset($client_addr)) $client_addr = $_SERVER['REMOTE_ADDR']; + + return "SSO-{$brokerId}-{$token}-" . hash('sha256', 'session' . $token . $client_addr . $broker['secret']); + } + + /** + * Generate session id from session token + * + * @return string + */ + protected function generateAttachChecksum($brokerId, $token) + { + $broker = $this->getBrokerInfo($brokerId); + if (!isset($broker)) return null; + + return hash('sha256', 'attach' . $token . $_SERVER['REMOTE_ADDR'] . $broker['secret']); + } + + + /** + * Detect the type for the HTTP response. + * Should only be done for an `attach` request. + */ + protected function detectReturnType() + { + if (!empty($_GET['return_url'])) { + $this->returnType = 'redirect'; + } elseif (!empty($_GET['callback'])) { + $this->returnType = 'jsonp'; + } elseif (strpos($_SERVER['HTTP_ACCEPT'], 'image/') !== false) { + $this->returnType = 'image'; + } elseif (strpos($_SERVER['HTTP_ACCEPT'], 'application/json') !== false) { + $this->returnType = 'json'; + } + + error_log($this->returnType); + } + + /** + * Attach a user session to a broker session + */ + public function attach() + { + $this->detectReturnType(); + + if (empty($_REQUEST['broker'])) return $this->fail("No broker specified", 400); + if (empty($_REQUEST['token'])) return $this->fail("No token specified", 400); + + if (!$this->returnType) return $this->fail("No return url specified", 400); + + $checksum = $this->generateAttachChecksum($_REQUEST['broker'], $_REQUEST['token']); + + if (empty($_REQUEST['checksum']) || $checksum != $_REQUEST['checksum']) { + return $this->fail("Invalid checksum", 400); + } + + $this->startUserSession(); + $sid = $this->generateSessionId($_REQUEST['broker'], $_REQUEST['token']); + + $this->cache->set($sid, session_id()); + $this->outputAttachSuccess(); + } + + /** + * Output on a successful attach + */ + protected function outputAttachSuccess() + { + if ($this->returnType === 'image') { + $this->outputImage(); + } + + if ($this->returnType === 'json') { + header('Content-type: application/json; charset=UTF-8'); + echo json_encode(['success' => 'attached']); + } + + if ($this->returnType === 'jsonp') { + $data = json_encode(['success' => 'attached']); + echo $_REQUEST['callback'] . "($data, 200);"; + } + + if ($this->returnType === 'redirect') { + $url = $_REQUEST['return_url']; + header("Location: $url", true, 307); + echo "You're being redirected to <a href='{$url}'>$url</a>"; + } + } + + /** + * Output a 1x1px transparent image + */ + protected function outputImage() + { + header('Content-Type: image/png'); + echo base64_decode('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQ' + . 'MAAAAl21bKAAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZg' + . 'AAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII='); + } + + + /** + * Authenticate + */ + public function login() + { + $this->startSession(); + + if (empty($_POST['username'])) $this->fail("No username specified", 400); + if (empty($_POST['password'])) $this->fail("No password specified", 400); + + $validation = $this->authenticate($_POST['username'], $_POST['password']); + + if ($validation->failed()) { + return $this->fail($validation->getError(), 400); + } + + $_SESSION['sso_user'] = $_POST['username']; + $this->userInfo(); + } + + /** + * Log out + */ + public function logout() + { + $this->startSession(); + unset($_SESSION['sso_user']); + + header('Content-type: application/json; charset=UTF-8'); + http_response_code(204); + } + + /** + * Ouput user information as json. + */ + public function userInfo() + { + $this->startSession(); + $user = null; + + if (isset($_SESSION['sso_user'])) { + $user = $this->getUserInfo($_SESSION['sso_user']); + if (!$user) return $this->fail("User not found", 500); // Shouldn't happen + } + + header('Content-type: application/json; charset=UTF-8'); + echo json_encode($user); + } + + + /** + * An error occured. + * + * @param string $message + * @param int $http_status + */ + protected function fail($message, $http_status = 500) + { + if ($http_status === 500) trigger_error($message, E_USER_WARNING); + + if ($this->returnType === 'jsonp') { + echo $_REQUEST['callback'] . "(" . json_encode(['error' => $message]) . ", $http_status);"; + exit(); + } + + if ($this->returnType === 'redirect') { + $url = $_REQUEST['return_url'] . '?sso_error=' . $message; + header("Location: $url", true, 307); + echo "You're being redirected to <a href='{$url}'>$url</a>"; + exit(); + } + + http_response_code($http_status); + header('Content-type: application/json; charset=UTF-8'); + + echo json_encode(['error' => $message]); + exit(); + } + + + /** + * Authenticate using user credentials + * + * @param string $username + * @param string $password + * @return \Jasny\ValidationResult + */ + abstract protected function authenticate($username, $password); + + /** + * Get the secret key and other info of a broker + * + * @param string $brokerId + * @return array + */ + abstract protected function getBrokerInfo($brokerId); + + /** + * Get the information about a user + * + * @param string $username + * @return array|object + */ + abstract protected function getUserInfo($username); +} + diff --git a/sso-diagram_ajax.png b/sso-diagram_ajax.png Binary files differdeleted file mode 100644 index 8272843..0000000 --- a/sso-diagram_ajax.png +++ /dev/null diff --git a/sso-diagram_alex.png b/sso-diagram_alex.png Binary files differdeleted file mode 100644 index e3a338c..0000000 --- a/sso-diagram_alex.png +++ /dev/null diff --git a/sso-diagram_binck.png b/sso-diagram_binck.png Binary files differdeleted file mode 100644 index 4fce026..0000000 --- a/sso-diagram_binck.png +++ /dev/null diff --git a/sso-diagram_no-sso.png b/sso-diagram_no-sso.png Binary files differdeleted file mode 100644 index 0500c19..0000000 --- a/sso-diagram_no-sso.png +++ /dev/null diff --git a/tests/_bootstrap.php b/tests/_bootstrap.php new file mode 100644 index 0000000..6c8c4f5 --- /dev/null +++ b/tests/_bootstrap.php @@ -0,0 +1,3 @@ +<?php + +require_once __DIR__ . '/../vendor/autoload.php'; diff --git a/tests/_data/dump.sql b/tests/_data/dump.sql new file mode 100644 index 0000000..4bc742c --- /dev/null +++ b/tests/_data/dump.sql @@ -0,0 +1 @@ +/* Replace this file with actual dump of your database */
\ No newline at end of file diff --git a/tests/_output/.gitignore b/tests/_output/.gitignore new file mode 100644 index 0000000..c96a04f --- /dev/null +++ b/tests/_output/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore
\ No newline at end of file diff --git a/tests/_support/AcceptanceTester.php b/tests/_support/AcceptanceTester.php new file mode 100644 index 0000000..bfa59cb --- /dev/null +++ b/tests/_support/AcceptanceTester.php @@ -0,0 +1,26 @@ +<?php + + +/** + * Inherited Methods + * @method void wantToTest($text) + * @method void wantTo($text) + * @method void execute($callable) + * @method void expectTo($prediction) + * @method void expect($prediction) + * @method void amGoingTo($argumentation) + * @method void am($role) + * @method void lookForwardTo($achieveValue) + * @method void comment($description) + * @method \Codeception\Lib\Friend haveFriend($name, $actorClass = null) + * + * @SuppressWarnings(PHPMD) +*/ +class AcceptanceTester extends \Codeception\Actor +{ + use _generated\AcceptanceTesterActions; + + /** + * Define custom actions here + */ +} diff --git a/tests/_support/Helper/Acceptance.php b/tests/_support/Helper/Acceptance.php new file mode 100644 index 0000000..dde2082 --- /dev/null +++ b/tests/_support/Helper/Acceptance.php @@ -0,0 +1,9 @@ +<?php +namespace Helper; +// here you can define custom actions +// all public methods declared in helper class will be available in $I + +class Acceptance extends \Codeception\Module +{ + +} diff --git a/tests/_support/Helper/BrokerApi.php b/tests/_support/Helper/BrokerApi.php new file mode 100644 index 0000000..5de9761 --- /dev/null +++ b/tests/_support/Helper/BrokerApi.php @@ -0,0 +1,9 @@ +<?php +namespace Helper; +// here you can define custom actions +// all public methods declared in helper class will be available in $I + +class BrokerApi extends \Codeception\Module +{ + +} diff --git a/tests/_support/Helper/Functional.php b/tests/_support/Helper/Functional.php new file mode 100644 index 0000000..34fbe73 --- /dev/null +++ b/tests/_support/Helper/Functional.php @@ -0,0 +1,9 @@ +<?php +namespace Helper; +// here you can define custom actions +// all public methods declared in helper class will be available in $I + +class Functional extends \Codeception\Module +{ + +} diff --git a/tests/_support/Helper/ServerApi.php b/tests/_support/Helper/ServerApi.php new file mode 100644 index 0000000..2387b19 --- /dev/null +++ b/tests/_support/Helper/ServerApi.php @@ -0,0 +1,9 @@ +<?php +namespace Helper; +// here you can define custom actions +// all public methods declared in helper class will be available in $I + +class ServerApi extends \Codeception\Module +{ + +} diff --git a/tests/_support/Helper/Unit.php b/tests/_support/Helper/Unit.php new file mode 100644 index 0000000..4862e82 --- /dev/null +++ b/tests/_support/Helper/Unit.php @@ -0,0 +1,9 @@ +<?php +namespace Helper; +// here you can define custom actions +// all public methods declared in helper class will be available in $I + +class Unit extends \Codeception\Module +{ + +} diff --git a/tests/_support/ServerApiTester.php b/tests/_support/ServerApiTester.php new file mode 100644 index 0000000..e6d4c8c --- /dev/null +++ b/tests/_support/ServerApiTester.php @@ -0,0 +1,39 @@ +<?php + +/** + * Inherited Methods + * @method void wantToTest($text) + * @method void wantTo($text) + * @method void execute($callable) + * @method void expectTo($prediction) + * @method void expect($prediction) + * @method void amGoingTo($argumentation) + * @method void am($role) + * @method void lookForwardTo($achieveValue) + * @method void comment($description) + * @method \Codeception\Lib\Friend haveFriend($name, $actorClass = null) + * + * @SuppressWarnings(PHPMD) +*/ +class ServerApiTester extends \Codeception\Actor +{ + use _generated\ApiTesterActions; + + /** + * Define custom actions here + */ + + public $defaultArgs = []; + + public function sendServerRequest($command, $extraArgs = array()) + { + $args = $this->defaultArgs; + $args['command'] = $command; + + foreach ($extraArgs as $key => $value) { + $args[$key] = $value; + } + + $this->sendPost('/', $args); + } +} diff --git a/tests/_support/_generated/AcceptanceTesterActions.php b/tests/_support/_generated/AcceptanceTesterActions.php new file mode 100644 index 0000000..f059ac4 --- /dev/null +++ b/tests/_support/_generated/AcceptanceTesterActions.php @@ -0,0 +1,1972 @@ +<?php //[STAMP] 0384a77df3b83831988cd9166a4acb23 +namespace _generated; + +// This class was automatically generated by build task +// You should not change it manually as it will be overwritten on next build +// @codingStandardsIgnoreFile + +use Codeception\Module\PhpBrowser; +use Helper\Acceptance; + +trait AcceptanceTesterActions +{ + /** + * @return \Codeception\Scenario + */ + abstract protected function getScenario(); + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Sets the HTTP header to the passed value - which is used on + * subsequent HTTP requests through PhpBrowser. + * + * Example: + * ```php + * <?php + * $I->setHeader('X-Requested-With', 'Codeception'); + * $I->amOnPage('test-headers.php'); + * ?> + * ``` + * + * @param string $name the name of the request header + * @param string $value the value to set it to for subsequent + * requests + * @see \Codeception\Module\PhpBrowser::setHeader() + */ + public function setHeader($name, $value) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('setHeader', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Deletes the header with the passed name. Subsequent requests + * will not have the deleted header in its request. + * + * Example: + * ```php + * <?php + * $I->setHeader('X-Requested-With', 'Codeception'); + * $I->amOnPage('test-headers.php'); + * // ... + * $I->deleteHeader('X-Requested-With'); + * $I->amOnPage('some-other-page.php'); + * ?> + * ``` + * + * @param string $name the name of the header to delete. + * @see \Codeception\Module\PhpBrowser::deleteHeader() + */ + public function deleteHeader($name) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('deleteHeader', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Authenticates user for HTTP_AUTH + * + * @param $username + * @param $password + * @see \Codeception\Module\PhpBrowser::amHttpAuthenticated() + */ + public function amHttpAuthenticated($username, $password) { + return $this->getScenario()->runStep(new \Codeception\Step\Condition('amHttpAuthenticated', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Open web page at the given absolute URL and sets its hostname as the base host. + * + * ``` php + * <?php + * $I->amOnUrl('http://codeception.com'); + * $I->amOnPage('/quickstart'); // moves to http://codeception.com/quickstart + * ?> + * ``` + * @see \Codeception\Module\PhpBrowser::amOnUrl() + */ + public function amOnUrl($url) { + return $this->getScenario()->runStep(new \Codeception\Step\Condition('amOnUrl', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Changes the subdomain for the 'url' configuration parameter. + * Does not open a page; use `amOnPage` for that. + * + * ``` php + * <?php + * // If config is: 'http://mysite.com' + * // or config is: 'http://www.mysite.com' + * // or config is: 'http://company.mysite.com' + * + * $I->amOnSubdomain('user'); + * $I->amOnPage('/'); + * // moves to http://user.mysite.com/ + * ?> + * ``` + * + * @param $subdomain + * + * @return mixed + * @see \Codeception\Module\PhpBrowser::amOnSubdomain() + */ + public function amOnSubdomain($subdomain) { + return $this->getScenario()->runStep(new \Codeception\Step\Condition('amOnSubdomain', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Low-level API method. + * If Codeception commands are not enough, use [Guzzle HTTP Client](http://guzzlephp.org/) methods directly + * + * Example: + * + * ``` php + * <?php + * $I->executeInGuzzle(function (\GuzzleHttp\Client $client) { + * $client->get('/get', ['query' => ['foo' => 'bar']]); + * }); + * ?> + * ``` + * + * It is not recommended to use this command on a regular basis. + * If Codeception lacks important Guzzle Client methods, implement them and submit patches. + * + * @param callable $function + * @see \Codeception\Module\PhpBrowser::executeInGuzzle() + */ + public function executeInGuzzle($function) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('executeInGuzzle', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Opens the page for the given relative URI. + * + * ``` php + * <?php + * // opens front page + * $I->amOnPage('/'); + * // opens /register page + * $I->amOnPage('/register'); + * ?> + * ``` + * + * @param $page + * @see \Codeception\Lib\InnerBrowser::amOnPage() + */ + public function amOnPage($page) { + return $this->getScenario()->runStep(new \Codeception\Step\Condition('amOnPage', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Perform a click on a link or a button, given by a locator. + * If a fuzzy locator is given, the page will be searched for a button, link, or image matching the locator string. + * For buttons, the "value" attribute, "name" attribute, and inner text are searched. + * For links, the link text is searched. + * For images, the "alt" attribute and inner text of any parent links are searched. + * + * The second parameter is a context (CSS or XPath locator) to narrow the search. + * + * Note that if the locator matches a button of type `submit`, the form will be submitted. + * + * ``` php + * <?php + * // simple link + * $I->click('Logout'); + * // button of form + * $I->click('Submit'); + * // CSS button + * $I->click('#form input[type=submit]'); + * // XPath + * $I->click('//form/*[@type=submit]'); + * // link in context + * $I->click('Logout', '#nav'); + * // using strict locator + * $I->click(['link' => 'Login']); + * ?> + * ``` + * + * @param $link + * @param $context + * @see \Codeception\Lib\InnerBrowser::click() + */ + public function click($link, $context = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('click', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that the current page contains the given string. + * Specify a locator as the second parameter to match a specific region. + * + * ``` php + * <?php + * $I->see('Logout'); // I can suppose user is logged in + * $I->see('Sign Up','h1'); // I can suppose it's a signup page + * $I->see('Sign Up','//body/h1'); // with XPath + * ?> + * ``` + * + * @param $text + * @param null $selector + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::see() + */ + public function canSee($text, $selector = null) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('see', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that the current page contains the given string. + * Specify a locator as the second parameter to match a specific region. + * + * ``` php + * <?php + * $I->see('Logout'); // I can suppose user is logged in + * $I->see('Sign Up','h1'); // I can suppose it's a signup page + * $I->see('Sign Up','//body/h1'); // with XPath + * ?> + * ``` + * + * @param $text + * @param null $selector + * @see \Codeception\Lib\InnerBrowser::see() + */ + public function see($text, $selector = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('see', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that the current page doesn't contain the text specified. + * Give a locator as the second parameter to match a specific region. + * + * ```php + * <?php + * $I->dontSee('Login'); // I can suppose user is already logged in + * $I->dontSee('Sign Up','h1'); // I can suppose it's not a signup page + * $I->dontSee('Sign Up','//body/h1'); // with XPath + * ?> + * ``` + * + * @param $text + * @param null $selector + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::dontSee() + */ + public function cantSee($text, $selector = null) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('dontSee', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that the current page doesn't contain the text specified. + * Give a locator as the second parameter to match a specific region. + * + * ```php + * <?php + * $I->dontSee('Login'); // I can suppose user is already logged in + * $I->dontSee('Sign Up','h1'); // I can suppose it's not a signup page + * $I->dontSee('Sign Up','//body/h1'); // with XPath + * ?> + * ``` + * + * @param $text + * @param null $selector + * @see \Codeception\Lib\InnerBrowser::dontSee() + */ + public function dontSee($text, $selector = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('dontSee', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that there's a link with the specified text. + * Give a full URL as the second parameter to match links with that exact URL. + * + * ``` php + * <?php + * $I->seeLink('Logout'); // matches <a href="#">Logout</a> + * $I->seeLink('Logout','/logout'); // matches <a href="/logout">Logout</a> + * ?> + * ``` + * + * @param $text + * @param null $url + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::seeLink() + */ + public function canSeeLink($text, $url = null) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('seeLink', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that there's a link with the specified text. + * Give a full URL as the second parameter to match links with that exact URL. + * + * ``` php + * <?php + * $I->seeLink('Logout'); // matches <a href="#">Logout</a> + * $I->seeLink('Logout','/logout'); // matches <a href="/logout">Logout</a> + * ?> + * ``` + * + * @param $text + * @param null $url + * @see \Codeception\Lib\InnerBrowser::seeLink() + */ + public function seeLink($text, $url = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('seeLink', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that the page doesn't contain a link with the given string. + * If the second parameter is given, only links with a matching "href" attribute will be checked. + * + * ``` php + * <?php + * $I->dontSeeLink('Logout'); // I suppose user is not logged in + * $I->dontSeeLink('Checkout now', '/store/cart.php'); + * ?> + * ``` + * + * @param $text + * @param null $url + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::dontSeeLink() + */ + public function cantSeeLink($text, $url = null) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeLink', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that the page doesn't contain a link with the given string. + * If the second parameter is given, only links with a matching "href" attribute will be checked. + * + * ``` php + * <?php + * $I->dontSeeLink('Logout'); // I suppose user is not logged in + * $I->dontSeeLink('Checkout now', '/store/cart.php'); + * ?> + * ``` + * + * @param $text + * @param null $url + * @see \Codeception\Lib\InnerBrowser::dontSeeLink() + */ + public function dontSeeLink($text, $url = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('dontSeeLink', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that current URI contains the given string. + * + * ``` php + * <?php + * // to match: /home/dashboard + * $I->seeInCurrentUrl('home'); + * // to match: /users/1 + * $I->seeInCurrentUrl('/users/'); + * ?> + * ``` + * + * @param $uri + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::seeInCurrentUrl() + */ + public function canSeeInCurrentUrl($uri) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('seeInCurrentUrl', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that current URI contains the given string. + * + * ``` php + * <?php + * // to match: /home/dashboard + * $I->seeInCurrentUrl('home'); + * // to match: /users/1 + * $I->seeInCurrentUrl('/users/'); + * ?> + * ``` + * + * @param $uri + * @see \Codeception\Lib\InnerBrowser::seeInCurrentUrl() + */ + public function seeInCurrentUrl($uri) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('seeInCurrentUrl', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that the current URI doesn't contain the given string. + * + * ``` php + * <?php + * $I->dontSeeInCurrentUrl('/users/'); + * ?> + * ``` + * + * @param $uri + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::dontSeeInCurrentUrl() + */ + public function cantSeeInCurrentUrl($uri) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeInCurrentUrl', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that the current URI doesn't contain the given string. + * + * ``` php + * <?php + * $I->dontSeeInCurrentUrl('/users/'); + * ?> + * ``` + * + * @param $uri + * @see \Codeception\Lib\InnerBrowser::dontSeeInCurrentUrl() + */ + public function dontSeeInCurrentUrl($uri) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('dontSeeInCurrentUrl', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that the current URL is equal to the given string. + * Unlike `seeInCurrentUrl`, this only matches the full URL. + * + * ``` php + * <?php + * // to match root url + * $I->seeCurrentUrlEquals('/'); + * ?> + * ``` + * + * @param $uri + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::seeCurrentUrlEquals() + */ + public function canSeeCurrentUrlEquals($uri) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('seeCurrentUrlEquals', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that the current URL is equal to the given string. + * Unlike `seeInCurrentUrl`, this only matches the full URL. + * + * ``` php + * <?php + * // to match root url + * $I->seeCurrentUrlEquals('/'); + * ?> + * ``` + * + * @param $uri + * @see \Codeception\Lib\InnerBrowser::seeCurrentUrlEquals() + */ + public function seeCurrentUrlEquals($uri) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('seeCurrentUrlEquals', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that the current URL doesn't equal the given string. + * Unlike `dontSeeInCurrentUrl`, this only matches the full URL. + * + * ``` php + * <?php + * // current url is not root + * $I->dontSeeCurrentUrlEquals('/'); + * ?> + * ``` + * + * @param $uri + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::dontSeeCurrentUrlEquals() + */ + public function cantSeeCurrentUrlEquals($uri) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeCurrentUrlEquals', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that the current URL doesn't equal the given string. + * Unlike `dontSeeInCurrentUrl`, this only matches the full URL. + * + * ``` php + * <?php + * // current url is not root + * $I->dontSeeCurrentUrlEquals('/'); + * ?> + * ``` + * + * @param $uri + * @see \Codeception\Lib\InnerBrowser::dontSeeCurrentUrlEquals() + */ + public function dontSeeCurrentUrlEquals($uri) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('dontSeeCurrentUrlEquals', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that the current URL matches the given regular expression. + * + * ``` php + * <?php + * // to match root url + * $I->seeCurrentUrlMatches('~$/users/(\d+)~'); + * ?> + * ``` + * + * @param $uri + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::seeCurrentUrlMatches() + */ + public function canSeeCurrentUrlMatches($uri) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('seeCurrentUrlMatches', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that the current URL matches the given regular expression. + * + * ``` php + * <?php + * // to match root url + * $I->seeCurrentUrlMatches('~$/users/(\d+)~'); + * ?> + * ``` + * + * @param $uri + * @see \Codeception\Lib\InnerBrowser::seeCurrentUrlMatches() + */ + public function seeCurrentUrlMatches($uri) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('seeCurrentUrlMatches', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that current url doesn't match the given regular expression. + * + * ``` php + * <?php + * // to match root url + * $I->dontSeeCurrentUrlMatches('~$/users/(\d+)~'); + * ?> + * ``` + * + * @param $uri + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::dontSeeCurrentUrlMatches() + */ + public function cantSeeCurrentUrlMatches($uri) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeCurrentUrlMatches', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that current url doesn't match the given regular expression. + * + * ``` php + * <?php + * // to match root url + * $I->dontSeeCurrentUrlMatches('~$/users/(\d+)~'); + * ?> + * ``` + * + * @param $uri + * @see \Codeception\Lib\InnerBrowser::dontSeeCurrentUrlMatches() + */ + public function dontSeeCurrentUrlMatches($uri) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('dontSeeCurrentUrlMatches', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Executes the given regular expression against the current URI and returns the first match. + * If no parameters are provided, the full URI is returned. + * + * ``` php + * <?php + * $user_id = $I->grabFromCurrentUrl('~$/user/(\d+)/~'); + * $uri = $I->grabFromCurrentUrl(); + * ?> + * ``` + * + * @param null $uri + * + * @internal param $url + * @return mixed + * @see \Codeception\Lib\InnerBrowser::grabFromCurrentUrl() + */ + public function grabFromCurrentUrl($uri = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('grabFromCurrentUrl', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that the specified checkbox is checked. + * + * ``` php + * <?php + * $I->seeCheckboxIsChecked('#agree'); // I suppose user agreed to terms + * $I->seeCheckboxIsChecked('#signup_form input[type=checkbox]'); // I suppose user agreed to terms, If there is only one checkbox in form. + * $I->seeCheckboxIsChecked('//form/input[@type=checkbox and @name=agree]'); + * ?> + * ``` + * + * @param $checkbox + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::seeCheckboxIsChecked() + */ + public function canSeeCheckboxIsChecked($checkbox) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('seeCheckboxIsChecked', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that the specified checkbox is checked. + * + * ``` php + * <?php + * $I->seeCheckboxIsChecked('#agree'); // I suppose user agreed to terms + * $I->seeCheckboxIsChecked('#signup_form input[type=checkbox]'); // I suppose user agreed to terms, If there is only one checkbox in form. + * $I->seeCheckboxIsChecked('//form/input[@type=checkbox and @name=agree]'); + * ?> + * ``` + * + * @param $checkbox + * @see \Codeception\Lib\InnerBrowser::seeCheckboxIsChecked() + */ + public function seeCheckboxIsChecked($checkbox) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('seeCheckboxIsChecked', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Check that the specified checkbox is unchecked. + * + * ``` php + * <?php + * $I->dontSeeCheckboxIsChecked('#agree'); // I suppose user didn't agree to terms + * $I->seeCheckboxIsChecked('#signup_form input[type=checkbox]'); // I suppose user didn't check the first checkbox in form. + * ?> + * ``` + * + * @param $checkbox + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::dontSeeCheckboxIsChecked() + */ + public function cantSeeCheckboxIsChecked($checkbox) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeCheckboxIsChecked', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Check that the specified checkbox is unchecked. + * + * ``` php + * <?php + * $I->dontSeeCheckboxIsChecked('#agree'); // I suppose user didn't agree to terms + * $I->seeCheckboxIsChecked('#signup_form input[type=checkbox]'); // I suppose user didn't check the first checkbox in form. + * ?> + * ``` + * + * @param $checkbox + * @see \Codeception\Lib\InnerBrowser::dontSeeCheckboxIsChecked() + */ + public function dontSeeCheckboxIsChecked($checkbox) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('dontSeeCheckboxIsChecked', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that the given input field or textarea contains the given value. + * For fuzzy locators, fields are matched by label text, the "name" attribute, CSS, and XPath. + * + * ``` php + * <?php + * $I->seeInField('Body','Type your comment here'); + * $I->seeInField('form textarea[name=body]','Type your comment here'); + * $I->seeInField('form input[type=hidden]','hidden_value'); + * $I->seeInField('#searchform input','Search'); + * $I->seeInField('//form/*[@name=search]','Search'); + * $I->seeInField(['name' => 'search'], 'Search'); + * ?> + * ``` + * + * @param $field + * @param $value + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::seeInField() + */ + public function canSeeInField($field, $value) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('seeInField', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that the given input field or textarea contains the given value. + * For fuzzy locators, fields are matched by label text, the "name" attribute, CSS, and XPath. + * + * ``` php + * <?php + * $I->seeInField('Body','Type your comment here'); + * $I->seeInField('form textarea[name=body]','Type your comment here'); + * $I->seeInField('form input[type=hidden]','hidden_value'); + * $I->seeInField('#searchform input','Search'); + * $I->seeInField('//form/*[@name=search]','Search'); + * $I->seeInField(['name' => 'search'], 'Search'); + * ?> + * ``` + * + * @param $field + * @param $value + * @see \Codeception\Lib\InnerBrowser::seeInField() + */ + public function seeInField($field, $value) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('seeInField', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that an input field or textarea doesn't contain the given value. + * For fuzzy locators, the field is matched by label text, CSS and XPath. + * + * ``` php + * <?php + * $I->dontSeeInField('Body','Type your comment here'); + * $I->dontSeeInField('form textarea[name=body]','Type your comment here'); + * $I->dontSeeInField('form input[type=hidden]','hidden_value'); + * $I->dontSeeInField('#searchform input','Search'); + * $I->dontSeeInField('//form/*[@name=search]','Search'); + * $I->dontSeeInField(['name' => 'search'], 'Search'); + * ?> + * ``` + * + * @param $field + * @param $value + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::dontSeeInField() + */ + public function cantSeeInField($field, $value) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeInField', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that an input field or textarea doesn't contain the given value. + * For fuzzy locators, the field is matched by label text, CSS and XPath. + * + * ``` php + * <?php + * $I->dontSeeInField('Body','Type your comment here'); + * $I->dontSeeInField('form textarea[name=body]','Type your comment here'); + * $I->dontSeeInField('form input[type=hidden]','hidden_value'); + * $I->dontSeeInField('#searchform input','Search'); + * $I->dontSeeInField('//form/*[@name=search]','Search'); + * $I->dontSeeInField(['name' => 'search'], 'Search'); + * ?> + * ``` + * + * @param $field + * @param $value + * @see \Codeception\Lib\InnerBrowser::dontSeeInField() + */ + public function dontSeeInField($field, $value) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('dontSeeInField', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks if the array of form parameters (name => value) are set on the form matched with the + * passed selector. + * + * ``` php + * <?php + * $I->seeInFormFields('form[name=myform]', [ + * 'input1' => 'value', + * 'input2' => 'other value', + * ]); + * ?> + * ``` + * + * For multi-select elements, or to check values of multiple elements with the same name, an + * array may be passed: + * + * ``` php + * <?php + * $I->seeInFormFields('.form-class', [ + * 'multiselect' => [ + * 'value1', + * 'value2', + * ], + * 'checkbox[]' => [ + * 'a checked value', + * 'another checked value', + * ], + * ]); + * ?> + * ``` + * + * Additionally, checkbox values can be checked with a boolean. + * + * ``` php + * <?php + * $I->seeInFormFields('#form-id', [ + * 'checkbox1' => true, // passes if checked + * 'checkbox2' => false, // passes if unchecked + * ]); + * ?> + * ``` + * + * Pair this with submitForm for quick testing magic. + * + * ``` php + * <?php + * $form = [ + * 'field1' => 'value', + * 'field2' => 'another value', + * 'checkbox1' => true, + * // ... + * ]; + * $I->submitForm('//form[@id=my-form]', $form, 'submitButton'); + * // $I->amOnPage('/path/to/form-page') may be needed + * $I->seeInFormFields('//form[@id=my-form]', $form); + * ?> + * ``` + * + * @param $formSelector + * @param $params + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::seeInFormFields() + */ + public function canSeeInFormFields($formSelector, $params) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('seeInFormFields', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks if the array of form parameters (name => value) are set on the form matched with the + * passed selector. + * + * ``` php + * <?php + * $I->seeInFormFields('form[name=myform]', [ + * 'input1' => 'value', + * 'input2' => 'other value', + * ]); + * ?> + * ``` + * + * For multi-select elements, or to check values of multiple elements with the same name, an + * array may be passed: + * + * ``` php + * <?php + * $I->seeInFormFields('.form-class', [ + * 'multiselect' => [ + * 'value1', + * 'value2', + * ], + * 'checkbox[]' => [ + * 'a checked value', + * 'another checked value', + * ], + * ]); + * ?> + * ``` + * + * Additionally, checkbox values can be checked with a boolean. + * + * ``` php + * <?php + * $I->seeInFormFields('#form-id', [ + * 'checkbox1' => true, // passes if checked + * 'checkbox2' => false, // passes if unchecked + * ]); + * ?> + * ``` + * + * Pair this with submitForm for quick testing magic. + * + * ``` php + * <?php + * $form = [ + * 'field1' => 'value', + * 'field2' => 'another value', + * 'checkbox1' => true, + * // ... + * ]; + * $I->submitForm('//form[@id=my-form]', $form, 'submitButton'); + * // $I->amOnPage('/path/to/form-page') may be needed + * $I->seeInFormFields('//form[@id=my-form]', $form); + * ?> + * ``` + * + * @param $formSelector + * @param $params + * @see \Codeception\Lib\InnerBrowser::seeInFormFields() + */ + public function seeInFormFields($formSelector, $params) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('seeInFormFields', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks if the array of form parameters (name => value) are not set on the form matched with + * the passed selector. + * + * ``` php + * <?php + * $I->dontSeeInFormFields('form[name=myform]', [ + * 'input1' => 'non-existent value', + * 'input2' => 'other non-existent value', + * ]); + * ?> + * ``` + * + * To check that an element hasn't been assigned any one of many values, an array can be passed + * as the value: + * + * ``` php + * <?php + * $I->dontSeeInFormFields('.form-class', [ + * 'fieldName' => [ + * 'This value shouldn\'t be set', + * 'And this value shouldn\'t be set', + * ], + * ]); + * ?> + * ``` + * + * Additionally, checkbox values can be checked with a boolean. + * + * ``` php + * <?php + * $I->dontSeeInFormFields('#form-id', [ + * 'checkbox1' => true, // fails if checked + * 'checkbox2' => false, // fails if unchecked + * ]); + * ?> + * ``` + * + * @param $formSelector + * @param $params + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::dontSeeInFormFields() + */ + public function cantSeeInFormFields($formSelector, $params) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeInFormFields', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks if the array of form parameters (name => value) are not set on the form matched with + * the passed selector. + * + * ``` php + * <?php + * $I->dontSeeInFormFields('form[name=myform]', [ + * 'input1' => 'non-existent value', + * 'input2' => 'other non-existent value', + * ]); + * ?> + * ``` + * + * To check that an element hasn't been assigned any one of many values, an array can be passed + * as the value: + * + * ``` php + * <?php + * $I->dontSeeInFormFields('.form-class', [ + * 'fieldName' => [ + * 'This value shouldn\'t be set', + * 'And this value shouldn\'t be set', + * ], + * ]); + * ?> + * ``` + * + * Additionally, checkbox values can be checked with a boolean. + * + * ``` php + * <?php + * $I->dontSeeInFormFields('#form-id', [ + * 'checkbox1' => true, // fails if checked + * 'checkbox2' => false, // fails if unchecked + * ]); + * ?> + * ``` + * + * @param $formSelector + * @param $params + * @see \Codeception\Lib\InnerBrowser::dontSeeInFormFields() + */ + public function dontSeeInFormFields($formSelector, $params) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('dontSeeInFormFields', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Submits the given form on the page, optionally with the given form + * values. Give the form fields values as an array. + * + * Skipped fields will be filled by their values from the page. + * You don't need to click the 'Submit' button afterwards. + * This command itself triggers the request to form's action. + * + * You can optionally specify what button's value to include + * in the request with the last parameter as an alternative to + * explicitly setting its value in the second parameter, as + * button values are not otherwise included in the request. + * + * Examples: + * + * ``` php + * <?php + * $I->submitForm('#login', [ + * 'login' => 'davert', + * 'password' => '123456' + * ]); + * // or + * $I->submitForm('#login', [ + * 'login' => 'davert', + * 'password' => '123456' + * ], 'submitButtonName'); + * + * ``` + * + * For example, given this sample "Sign Up" form: + * + * ``` html + * <form action="/sign_up"> + * Login: + * <input type="text" name="user[login]" /><br/> + * Password: + * <input type="password" name="user[password]" /><br/> + * Do you agree to our terms? + * <input type="checkbox" name="user[agree]" /><br/> + * Select pricing plan: + * <select name="plan"> + * <option value="1">Free</option> + * <option value="2" selected="selected">Paid</option> + * </select> + * <input type="submit" name="submitButton" value="Submit" /> + * </form> + * ``` + * + * You could write the following to submit it: + * + * ``` php + * <?php + * $I->submitForm( + * '#userForm', + * [ + * 'user' => [ + * 'login' => 'Davert', + * 'password' => '123456', + * 'agree' => true + * ] + * ], + * 'submitButton' + * ); + * ``` + * Note that "2" will be the submitted value for the "plan" field, as it is + * the selected option. + * + * You can also emulate a JavaScript submission by not specifying any + * buttons in the third parameter to submitForm. + * + * ```php + * <?php + * $I->submitForm( + * '#userForm', + * [ + * 'user' => [ + * 'login' => 'Davert', + * 'password' => '123456', + * 'agree' => true + * ] + * ] + * ); + * ``` + * + * Pair this with seeInFormFields for quick testing magic. + * + * ``` php + * <?php + * $form = [ + * 'field1' => 'value', + * 'field2' => 'another value', + * 'checkbox1' => true, + * // ... + * ]; + * $I->submitForm('//form[@id=my-form]', $form, 'submitButton'); + * // $I->amOnPage('/path/to/form-page') may be needed + * $I->seeInFormFields('//form[@id=my-form]', $form); + * ?> + * ``` + * + * Parameter values can be set to arrays for multiple input fields + * of the same name, or multi-select combo boxes. For checkboxes, + * either the string value can be used, or boolean values which will + * be replaced by the checkbox's value in the DOM. + * + * ``` php + * <?php + * $I->submitForm('#my-form', [ + * 'field1' => 'value', + * 'checkbox' => [ + * 'value of first checkbox', + * 'value of second checkbox, + * ], + * 'otherCheckboxes' => [ + * true, + * false, + * false + * ], + * 'multiselect' => [ + * 'first option value', + * 'second option value' + * ] + * ]); + * ?> + * ``` + * + * Mixing string and boolean values for a checkbox's value is not supported + * and may produce unexpected results. + * + * Field names ending in "[]" must be passed without the trailing square + * bracket characters, and must contain an array for its value. This allows + * submitting multiple values with the same name, consider: + * + * ```php + * $I->submitForm('#my-form', [ + * 'field[]' => 'value', + * 'field[]' => 'another value', // 'field[]' is already a defined key + * ]); + * ``` + * + * The solution is to pass an array value: + * + * ```php + * // this way both values are submitted + * $I->submitForm('#my-form', [ + * 'field' => [ + * 'value', + * 'another value', + * ] + * ]); + * ``` + * + * @param $selector + * @param $params + * @param $button + * @see \Codeception\Lib\InnerBrowser::submitForm() + */ + public function submitForm($selector, $params, $button = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('submitForm', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Fills a text field or textarea with the given string. + * + * ``` php + * <?php + * $I->fillField("//input[@type='text']", "Hello World!"); + * $I->fillField(['name' => 'email'], 'jon@mail.com'); + * ?> + * ``` + * + * @param $field + * @param $value + * @see \Codeception\Lib\InnerBrowser::fillField() + */ + public function fillField($field, $value) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('fillField', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Selects an option in a select tag or in radio button group. + * + * ``` php + * <?php + * $I->selectOption('form select[name=account]', 'Premium'); + * $I->selectOption('form input[name=payment]', 'Monthly'); + * $I->selectOption('//form/select[@name=account]', 'Monthly'); + * ?> + * ``` + * + * Provide an array for the second argument to select multiple options: + * + * ``` php + * <?php + * $I->selectOption('Which OS do you use?', array('Windows','Linux')); + * ?> + * ``` + * + * @param $select + * @param $option + * @see \Codeception\Lib\InnerBrowser::selectOption() + */ + public function selectOption($select, $option) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('selectOption', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Ticks a checkbox. For radio buttons, use the `selectOption` method instead. + * + * ``` php + * <?php + * $I->checkOption('#agree'); + * ?> + * ``` + * + * @param $option + * @see \Codeception\Lib\InnerBrowser::checkOption() + */ + public function checkOption($option) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('checkOption', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Unticks a checkbox. + * + * ``` php + * <?php + * $I->uncheckOption('#notify'); + * ?> + * ``` + * + * @param $option + * @see \Codeception\Lib\InnerBrowser::uncheckOption() + */ + public function uncheckOption($option) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('uncheckOption', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Attaches a file relative to the Codeception data directory to the given file upload field. + * + * ``` php + * <?php + * // file is stored in 'tests/_data/prices.xls' + * $I->attachFile('input[@type="file"]', 'prices.xls'); + * ?> + * ``` + * + * @param $field + * @param $filename + * @see \Codeception\Lib\InnerBrowser::attachFile() + */ + public function attachFile($field, $filename) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('attachFile', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * If your page triggers an ajax request, you can perform it manually. + * This action sends a GET ajax request with specified params. + * + * See ->sendAjaxPostRequest for examples. + * + * @param $uri + * @param $params + * @see \Codeception\Lib\InnerBrowser::sendAjaxGetRequest() + */ + public function sendAjaxGetRequest($uri, $params = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('sendAjaxGetRequest', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * If your page triggers an ajax request, you can perform it manually. + * This action sends a POST ajax request with specified params. + * Additional params can be passed as array. + * + * Example: + * + * Imagine that by clicking checkbox you trigger ajax request which updates user settings. + * We emulate that click by running this ajax request manually. + * + * ``` php + * <?php + * $I->sendAjaxPostRequest('/updateSettings', array('notifications' => true)); // POST + * $I->sendAjaxGetRequest('/updateSettings', array('notifications' => true)); // GET + * + * ``` + * + * @param $uri + * @param $params + * @see \Codeception\Lib\InnerBrowser::sendAjaxPostRequest() + */ + public function sendAjaxPostRequest($uri, $params = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('sendAjaxPostRequest', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * If your page triggers an ajax request, you can perform it manually. + * This action sends an ajax request with specified method and params. + * + * Example: + * + * You need to perform an ajax request specifying the HTTP method. + * + * ``` php + * <?php + * $I->sendAjaxRequest('PUT', '/posts/7', array('title' => 'new title')); + * + * ``` + * + * @param $method + * @param $uri + * @param $params + * @see \Codeception\Lib\InnerBrowser::sendAjaxRequest() + */ + public function sendAjaxRequest($method, $uri, $params = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('sendAjaxRequest', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Finds and returns the text contents of the given element. + * If a fuzzy locator is used, the element is found using CSS, XPath, and by matching the full page source by regular expression. + * + * ``` php + * <?php + * $heading = $I->grabTextFrom('h1'); + * $heading = $I->grabTextFrom('descendant-or-self::h1'); + * $value = $I->grabTextFrom('~<input value=(.*?)]~sgi'); // match with a regex + * ?> + * ``` + * + * @param $cssOrXPathOrRegex + * + * @return mixed + * @see \Codeception\Lib\InnerBrowser::grabTextFrom() + */ + public function grabTextFrom($cssOrXPathOrRegex) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('grabTextFrom', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Grabs the value of the given attribute value from the given element. + * Fails if element is not found. + * + * ``` php + * <?php + * $I->grabAttributeFrom('#tooltip', 'title'); + * ?> + * ``` + * + * + * @param $cssOrXpath + * @param $attribute + * @internal param $element + * @return mixed + * @see \Codeception\Lib\InnerBrowser::grabAttributeFrom() + */ + public function grabAttributeFrom($cssOrXpath, $attribute) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('grabAttributeFrom', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * + * @see \Codeception\Lib\InnerBrowser::grabMultiple() + */ + public function grabMultiple($cssOrXpath, $attribute = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('grabMultiple', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * @param $field + * + * @return array|mixed|null|string + * @see \Codeception\Lib\InnerBrowser::grabValueFrom() + */ + public function grabValueFrom($field) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('grabValueFrom', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Sets a cookie with the given name and value. + * You can set additional cookie params like `domain`, `path`, `expire`, `secure` in array passed as last argument. + * + * ``` php + * <?php + * $I->setCookie('PHPSESSID', 'el4ukv0kqbvoirg7nkp4dncpk3'); + * ?> + * ``` + * + * @param $name + * @param $val + * @param array $params + * + * @return mixed + * @see \Codeception\Lib\InnerBrowser::setCookie() + */ + public function setCookie($name, $val, $params = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('setCookie', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Grabs a cookie value. + * You can set additional cookie params like `domain`, `path` in array passed as last argument. + * + * @param $cookie + * + * @param array $params + * @return mixed + * @see \Codeception\Lib\InnerBrowser::grabCookie() + */ + public function grabCookie($cookie, $params = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('grabCookie', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that a cookie with the given name is set. + * You can set additional cookie params like `domain`, `path` as array passed in last argument. + * + * ``` php + * <?php + * $I->seeCookie('PHPSESSID'); + * ?> + * ``` + * + * @param $cookie + * @param array $params + * @return mixed + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::seeCookie() + */ + public function canSeeCookie($cookie, $params = null) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('seeCookie', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that a cookie with the given name is set. + * You can set additional cookie params like `domain`, `path` as array passed in last argument. + * + * ``` php + * <?php + * $I->seeCookie('PHPSESSID'); + * ?> + * ``` + * + * @param $cookie + * @param array $params + * @return mixed + * @see \Codeception\Lib\InnerBrowser::seeCookie() + */ + public function seeCookie($cookie, $params = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('seeCookie', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that there isn't a cookie with the given name. + * You can set additional cookie params like `domain`, `path` as array passed in last argument. + * + * @param $cookie + * + * @param array $params + * @return mixed + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::dontSeeCookie() + */ + public function cantSeeCookie($cookie, $params = null) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeCookie', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that there isn't a cookie with the given name. + * You can set additional cookie params like `domain`, `path` as array passed in last argument. + * + * @param $cookie + * + * @param array $params + * @return mixed + * @see \Codeception\Lib\InnerBrowser::dontSeeCookie() + */ + public function dontSeeCookie($cookie, $params = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('dontSeeCookie', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Unsets cookie with the given name. + * You can set additional cookie params like `domain`, `path` in array passed as last argument. + * + * @param $cookie + * + * @param array $params + * @return mixed + * @see \Codeception\Lib\InnerBrowser::resetCookie() + */ + public function resetCookie($name, $params = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('resetCookie', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that the given element exists on the page and is visible. + * You can also specify expected attributes of this element. + * + * ``` php + * <?php + * $I->seeElement('.error'); + * $I->seeElement('//form/input[1]'); + * $I->seeElement('input', ['name' => 'login']); + * $I->seeElement('input', ['value' => '123456']); + * + * // strict locator in first arg, attributes in second + * $I->seeElement(['css' => 'form input'], ['name' => 'login']); + * ?> + * ``` + * + * @param $selector + * @param array $attributes + * @return + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::seeElement() + */ + public function canSeeElement($selector, $attributes = null) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('seeElement', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that the given element exists on the page and is visible. + * You can also specify expected attributes of this element. + * + * ``` php + * <?php + * $I->seeElement('.error'); + * $I->seeElement('//form/input[1]'); + * $I->seeElement('input', ['name' => 'login']); + * $I->seeElement('input', ['value' => '123456']); + * + * // strict locator in first arg, attributes in second + * $I->seeElement(['css' => 'form input'], ['name' => 'login']); + * ?> + * ``` + * + * @param $selector + * @param array $attributes + * @return + * @see \Codeception\Lib\InnerBrowser::seeElement() + */ + public function seeElement($selector, $attributes = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('seeElement', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that the given element is invisible or not present on the page. + * You can also specify expected attributes of this element. + * + * ``` php + * <?php + * $I->dontSeeElement('.error'); + * $I->dontSeeElement('//form/input[1]'); + * $I->dontSeeElement('input', ['name' => 'login']); + * $I->dontSeeElement('input', ['value' => '123456']); + * ?> + * ``` + * + * @param $selector + * @param array $attributes + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::dontSeeElement() + */ + public function cantSeeElement($selector, $attributes = null) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeElement', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that the given element is invisible or not present on the page. + * You can also specify expected attributes of this element. + * + * ``` php + * <?php + * $I->dontSeeElement('.error'); + * $I->dontSeeElement('//form/input[1]'); + * $I->dontSeeElement('input', ['name' => 'login']); + * $I->dontSeeElement('input', ['value' => '123456']); + * ?> + * ``` + * + * @param $selector + * @param array $attributes + * @see \Codeception\Lib\InnerBrowser::dontSeeElement() + */ + public function dontSeeElement($selector, $attributes = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('dontSeeElement', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that there are a certain number of elements matched by the given locator on the page. + * + * ``` php + * <?php + * $I->seeNumberOfElements('tr', 10); + * $I->seeNumberOfElements('tr', [0,10]); //between 0 and 10 elements + * ?> + * ``` + * @param $selector + * @param mixed $expected : + * - string: strict number + * - array: range of numbers [0,10] + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::seeNumberOfElements() + */ + public function canSeeNumberOfElements($selector, $expected) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('seeNumberOfElements', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that there are a certain number of elements matched by the given locator on the page. + * + * ``` php + * <?php + * $I->seeNumberOfElements('tr', 10); + * $I->seeNumberOfElements('tr', [0,10]); //between 0 and 10 elements + * ?> + * ``` + * @param $selector + * @param mixed $expected : + * - string: strict number + * - array: range of numbers [0,10] + * @see \Codeception\Lib\InnerBrowser::seeNumberOfElements() + */ + public function seeNumberOfElements($selector, $expected) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('seeNumberOfElements', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that the given option is selected. + * + * ``` php + * <?php + * $I->seeOptionIsSelected('#form input[name=payment]', 'Visa'); + * ?> + * ``` + * + * @param $selector + * @param $optionText + * + * @return mixed + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::seeOptionIsSelected() + */ + public function canSeeOptionIsSelected($selector, $optionText) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('seeOptionIsSelected', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that the given option is selected. + * + * ``` php + * <?php + * $I->seeOptionIsSelected('#form input[name=payment]', 'Visa'); + * ?> + * ``` + * + * @param $selector + * @param $optionText + * + * @return mixed + * @see \Codeception\Lib\InnerBrowser::seeOptionIsSelected() + */ + public function seeOptionIsSelected($selector, $optionText) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('seeOptionIsSelected', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that the given option is not selected. + * + * ``` php + * <?php + * $I->dontSeeOptionIsSelected('#form input[name=payment]', 'Visa'); + * ?> + * ``` + * + * @param $selector + * @param $optionText + * + * @return mixed + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::dontSeeOptionIsSelected() + */ + public function cantSeeOptionIsSelected($selector, $optionText) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeOptionIsSelected', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that the given option is not selected. + * + * ``` php + * <?php + * $I->dontSeeOptionIsSelected('#form input[name=payment]', 'Visa'); + * ?> + * ``` + * + * @param $selector + * @param $optionText + * + * @return mixed + * @see \Codeception\Lib\InnerBrowser::dontSeeOptionIsSelected() + */ + public function dontSeeOptionIsSelected($selector, $optionText) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('dontSeeOptionIsSelected', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Asserts that current page has 404 response status code. + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::seePageNotFound() + */ + public function canSeePageNotFound() { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('seePageNotFound', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Asserts that current page has 404 response status code. + * @see \Codeception\Lib\InnerBrowser::seePageNotFound() + */ + public function seePageNotFound() { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('seePageNotFound', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that response code is equal to value provided. + * + * @param $code + * + * @return mixed + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::seeResponseCodeIs() + */ + public function canSeeResponseCodeIs($code) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('seeResponseCodeIs', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that response code is equal to value provided. + * + * @param $code + * + * @return mixed + * @see \Codeception\Lib\InnerBrowser::seeResponseCodeIs() + */ + public function seeResponseCodeIs($code) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('seeResponseCodeIs', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that the page title contains the given string. + * + * ``` php + * <?php + * $I->seeInTitle('Blog - Post #1'); + * ?> + * ``` + * + * @param $title + * + * @return mixed + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::seeInTitle() + */ + public function canSeeInTitle($title) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('seeInTitle', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that the page title contains the given string. + * + * ``` php + * <?php + * $I->seeInTitle('Blog - Post #1'); + * ?> + * ``` + * + * @param $title + * + * @return mixed + * @see \Codeception\Lib\InnerBrowser::seeInTitle() + */ + public function seeInTitle($title) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('seeInTitle', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that the page title does not contain the given string. + * + * @param $title + * + * @return mixed + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::dontSeeInTitle() + */ + public function cantSeeInTitle($title) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeInTitle', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that the page title does not contain the given string. + * + * @param $title + * + * @return mixed + * @see \Codeception\Lib\InnerBrowser::dontSeeInTitle() + */ + public function dontSeeInTitle($title) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('dontSeeInTitle', func_get_args())); + } +} diff --git a/tests/_support/_generated/ApiTesterActions.php b/tests/_support/_generated/ApiTesterActions.php new file mode 100644 index 0000000..48a1129 --- /dev/null +++ b/tests/_support/_generated/ApiTesterActions.php @@ -0,0 +1,905 @@ +<?php //[STAMP] f2684eb7b23eca29342fc64801984a63 +namespace _generated; + +// This class was automatically generated by build task +// You should not change it manually as it will be overwritten on next build +// @codingStandardsIgnoreFile + +use Codeception\Module\REST; + +trait ApiTesterActions +{ + /** + * @return \Codeception\Scenario + */ + abstract protected function getScenario(); + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Sets HTTP header + * + * @param $name + * @param $value + * @part json + * @part xml + * @see \Codeception\Module\REST::haveHttpHeader() + */ + public function haveHttpHeader($name, $value) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('haveHttpHeader', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks over the given HTTP header and (optionally) + * its value, asserting that are there + * + * @param $name + * @param $value + * @part json + * @part xml + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Module\REST::seeHttpHeader() + */ + public function canSeeHttpHeader($name, $value = null) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('seeHttpHeader', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks over the given HTTP header and (optionally) + * its value, asserting that are there + * + * @param $name + * @param $value + * @part json + * @part xml + * @see \Codeception\Module\REST::seeHttpHeader() + */ + public function seeHttpHeader($name, $value = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('seeHttpHeader', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks over the given HTTP header and (optionally) + * its value, asserting that are not there + * + * @param $name + * @param $value + * @part json + * @part xml + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Module\REST::dontSeeHttpHeader() + */ + public function cantSeeHttpHeader($name, $value = null) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeHttpHeader', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks over the given HTTP header and (optionally) + * its value, asserting that are not there + * + * @param $name + * @param $value + * @part json + * @part xml + * @see \Codeception\Module\REST::dontSeeHttpHeader() + */ + public function dontSeeHttpHeader($name, $value = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('dontSeeHttpHeader', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that http response header is received only once. + * HTTP RFC2616 allows multiple response headers with the same name. + * You can check that you didn't accidentally sent the same header twice. + * + * ``` php + * <?php + * $I->seeHttpHeaderOnce('Cache-Control'); + * ?>> + * ``` + * + * @param $name + * @part json + * @part xml + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Module\REST::seeHttpHeaderOnce() + */ + public function canSeeHttpHeaderOnce($name) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('seeHttpHeaderOnce', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that http response header is received only once. + * HTTP RFC2616 allows multiple response headers with the same name. + * You can check that you didn't accidentally sent the same header twice. + * + * ``` php + * <?php + * $I->seeHttpHeaderOnce('Cache-Control'); + * ?>> + * ``` + * + * @param $name + * @part json + * @part xml + * @see \Codeception\Module\REST::seeHttpHeaderOnce() + */ + public function seeHttpHeaderOnce($name) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('seeHttpHeaderOnce', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Returns the value of the specified header name + * + * @param $name + * @param Boolean $first Whether to return the first value or all header values + * + * @return string|array The first header value if $first is true, an array of values otherwise + * @part json + * @part xml + * @see \Codeception\Module\REST::grabHttpHeader() + */ + public function grabHttpHeader($name, $first = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('grabHttpHeader', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Adds HTTP authentication via username/password. + * + * @param $username + * @param $password + * @part json + * @part xml + * @see \Codeception\Module\REST::amHttpAuthenticated() + */ + public function amHttpAuthenticated($username, $password) { + return $this->getScenario()->runStep(new \Codeception\Step\Condition('amHttpAuthenticated', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Adds Digest authentication via username/password. + * + * @param $username + * @param $password + * @part json + * @part xml + * @see \Codeception\Module\REST::amDigestAuthenticated() + */ + public function amDigestAuthenticated($username, $password) { + return $this->getScenario()->runStep(new \Codeception\Step\Condition('amDigestAuthenticated', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Adds Bearer authentication via access token. + * + * @param $accessToken + * @part json + * @part xml + * @see \Codeception\Module\REST::amBearerAuthenticated() + */ + public function amBearerAuthenticated($accessToken) { + return $this->getScenario()->runStep(new \Codeception\Step\Condition('amBearerAuthenticated', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Sends a POST request to given uri. + * + * Parameters and files (as array of filenames) can be provided. + * + * @param $url + * @param array|\JsonSerializable $params + * @param array $files + * @part json + * @part xml + * @see \Codeception\Module\REST::sendPOST() + */ + public function sendPOST($url, $params = null, $files = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('sendPOST', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Sends a HEAD request to given uri. + * + * @param $url + * @param array $params + * @part json + * @part xml + * @see \Codeception\Module\REST::sendHEAD() + */ + public function sendHEAD($url, $params = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('sendHEAD', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Sends an OPTIONS request to given uri. + * + * @param $url + * @param array $params + * @part json + * @part xml + * @see \Codeception\Module\REST::sendOPTIONS() + */ + public function sendOPTIONS($url, $params = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('sendOPTIONS', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Sends a GET request to given uri. + * + * @param $url + * @param array $params + * @part json + * @part xml + * @see \Codeception\Module\REST::sendGET() + */ + public function sendGET($url, $params = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('sendGET', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Sends PUT request to given uri. + * + * @param $url + * @param array $params + * @param array $files + * @part json + * @part xml + * @see \Codeception\Module\REST::sendPUT() + */ + public function sendPUT($url, $params = null, $files = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('sendPUT', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Sends PATCH request to given uri. + * + * @param $url + * @param array $params + * @param array $files + * @part json + * @part xml + * @see \Codeception\Module\REST::sendPATCH() + */ + public function sendPATCH($url, $params = null, $files = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('sendPATCH', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Sends DELETE request to given uri. + * + * @param $url + * @param array $params + * @param array $files + * @part json + * @part xml + * @see \Codeception\Module\REST::sendDELETE() + */ + public function sendDELETE($url, $params = null, $files = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('sendDELETE', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Sends LINK request to given uri. + * + * @param $url + * @param array $linkEntries (entry is array with keys "uri" and "link-param") + * + * @link http://tools.ietf.org/html/rfc2068#section-19.6.2.4 + * + * @author samva.ua@gmail.com + * @part json + * @part xml + * @see \Codeception\Module\REST::sendLINK() + */ + public function sendLINK($url, $linkEntries) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('sendLINK', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Sends UNLINK request to given uri. + * + * @param $url + * @param array $linkEntries (entry is array with keys "uri" and "link-param") + * @link http://tools.ietf.org/html/rfc2068#section-19.6.2.4 + * @author samva.ua@gmail.com + * @part json + * @part xml + * @see \Codeception\Module\REST::sendUNLINK() + */ + public function sendUNLINK($url, $linkEntries) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('sendUNLINK', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks whether last response was valid JSON. + * This is done with json_last_error function. + * + * @part json + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Module\REST::seeResponseIsJson() + */ + public function canSeeResponseIsJson() { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('seeResponseIsJson', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks whether last response was valid JSON. + * This is done with json_last_error function. + * + * @part json + * @see \Codeception\Module\REST::seeResponseIsJson() + */ + public function seeResponseIsJson() { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('seeResponseIsJson', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks whether the last response contains text. + * + * @param $text + * @part json + * @part xml + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Module\REST::seeResponseContains() + */ + public function canSeeResponseContains($text) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('seeResponseContains', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks whether the last response contains text. + * + * @param $text + * @part json + * @part xml + * @see \Codeception\Module\REST::seeResponseContains() + */ + public function seeResponseContains($text) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('seeResponseContains', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks whether last response do not contain text. + * + * @param $text + * @part json + * @part xml + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Module\REST::dontSeeResponseContains() + */ + public function cantSeeResponseContains($text) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeResponseContains', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks whether last response do not contain text. + * + * @param $text + * @part json + * @part xml + * @see \Codeception\Module\REST::dontSeeResponseContains() + */ + public function dontSeeResponseContains($text) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('dontSeeResponseContains', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks whether the last JSON response contains provided array. + * The response is converted to array with json_decode($response, true) + * Thus, JSON is represented by associative array. + * This method matches that response array contains provided array. + * + * Examples: + * + * ``` php + * <?php + * // response: {name: john, email: john@gmail.com} + * $I->seeResponseContainsJson(array('name' => 'john')); + * + * // response {user: john, profile: { email: john@gmail.com }} + * $I->seeResponseContainsJson(array('email' => 'john@gmail.com')); + * + * ?> + * ``` + * + * This method recursively checks if one array can be found inside of another. + * + * @param array $json + * @part json + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Module\REST::seeResponseContainsJson() + */ + public function canSeeResponseContainsJson($json = null) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('seeResponseContainsJson', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks whether the last JSON response contains provided array. + * The response is converted to array with json_decode($response, true) + * Thus, JSON is represented by associative array. + * This method matches that response array contains provided array. + * + * Examples: + * + * ``` php + * <?php + * // response: {name: john, email: john@gmail.com} + * $I->seeResponseContainsJson(array('name' => 'john')); + * + * // response {user: john, profile: { email: john@gmail.com }} + * $I->seeResponseContainsJson(array('email' => 'john@gmail.com')); + * + * ?> + * ``` + * + * This method recursively checks if one array can be found inside of another. + * + * @param array $json + * @part json + * @see \Codeception\Module\REST::seeResponseContainsJson() + */ + public function seeResponseContainsJson($json = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('seeResponseContainsJson', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Returns current response so that it can be used in next scenario steps. + * + * Example: + * + * ``` php + * <?php + * $user_id = $I->grabResponse(); + * $I->sendPUT('/user', array('id' => $user_id, 'name' => 'davert')); + * ?> + * ``` + * + * @version 1.1 + * @return string + * @part json + * @part xml + * @see \Codeception\Module\REST::grabResponse() + */ + public function grabResponse() { + return $this->getScenario()->runStep(new \Codeception\Step\Action('grabResponse', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Returns data from the current JSON response using [JSONPath](http://goessner.net/articles/JsonPath/) as selector. + * JsonPath is XPath equivalent for querying Json structures. Try your JsonPath expressions [online](http://jsonpath.curiousconcept.com/). + * Even for a single value an array is returned. + * + * This method **require [`flow/jsonpath` > 0.2](https://github.com/FlowCommunications/JSONPath/) library to be installed**. + * + * Example: + * + * ``` php + * <?php + * // match the first `user.id` in json + * $firstUser = $I->grabDataFromJsonResponse('$..users[0].id'); + * $I->sendPUT('/user', array('id' => $firstUser[0], 'name' => 'davert')); + * ?> + * ``` + * + * @param $jsonPath + * @return array + * @version 2.0.9 + * @throws \Exception + * @part json + * @see \Codeception\Module\REST::grabDataFromResponseByJsonPath() + */ + public function grabDataFromResponseByJsonPath($jsonPath) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('grabDataFromResponseByJsonPath', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks if json structure in response matches the xpath provided. + * JSON is not supposed to be checked against XPath, yet it can be converted to xml and used with XPath. + * This assertion allows you to check the structure of response json. + * * + * ```json + * { "store": { + * "book": [ + * { "category": "reference", + * "author": "Nigel Rees", + * "title": "Sayings of the Century", + * "price": 8.95 + * }, + * { "category": "fiction", + * "author": "Evelyn Waugh", + * "title": "Sword of Honour", + * "price": 12.99 + * } + * ], + * "bicycle": { + * "color": "red", + * "price": 19.95 + * } + * } + * } + * ``` + * + * ```php + * <?php + * // at least one book in store has author + * $I->seeResponseJsonMatchesXpath('//store/book/author'); + * // first book in store has author + * $I->seeResponseJsonMatchesXpath('//store/book[1]/author'); + * // at least one item in store has price + * $I->seeResponseJsonMatchesXpath('/store//price'); + * ?> + * ``` + * @part json + * @version 2.0.9 + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Module\REST::seeResponseJsonMatchesXpath() + */ + public function canSeeResponseJsonMatchesXpath($xpath) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('seeResponseJsonMatchesXpath', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks if json structure in response matches the xpath provided. + * JSON is not supposed to be checked against XPath, yet it can be converted to xml and used with XPath. + * This assertion allows you to check the structure of response json. + * * + * ```json + * { "store": { + * "book": [ + * { "category": "reference", + * "author": "Nigel Rees", + * "title": "Sayings of the Century", + * "price": 8.95 + * }, + * { "category": "fiction", + * "author": "Evelyn Waugh", + * "title": "Sword of Honour", + * "price": 12.99 + * } + * ], + * "bicycle": { + * "color": "red", + * "price": 19.95 + * } + * } + * } + * ``` + * + * ```php + * <?php + * // at least one book in store has author + * $I->seeResponseJsonMatchesXpath('//store/book/author'); + * // first book in store has author + * $I->seeResponseJsonMatchesXpath('//store/book[1]/author'); + * // at least one item in store has price + * $I->seeResponseJsonMatchesXpath('/store//price'); + * ?> + * ``` + * @part json + * @version 2.0.9 + * @see \Codeception\Module\REST::seeResponseJsonMatchesXpath() + */ + public function seeResponseJsonMatchesXpath($xpath) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('seeResponseJsonMatchesXpath', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks if json structure in response matches [JsonPath](http://goessner.net/articles/JsonPath/). + * JsonPath is XPath equivalent for querying Json structures. Try your JsonPath expressions [online](http://jsonpath.curiousconcept.com/). + * This assertion allows you to check the structure of response json. + * + * This method **require [`flow/jsonpath` > 0.2](https://github.com/FlowCommunications/JSONPath/) library to be installed**. + * + * ```json + * { "store": { + * "book": [ + * { "category": "reference", + * "author": "Nigel Rees", + * "title": "Sayings of the Century", + * "price": 8.95 + * }, + * { "category": "fiction", + * "author": "Evelyn Waugh", + * "title": "Sword of Honour", + * "price": 12.99 + * } + * ], + * "bicycle": { + * "color": "red", + * "price": 19.95 + * } + * } + * } + * ``` + * + * ```php + * <?php + * // at least one book in store has author + * $I->seeResponseJsonMatchesJsonPath('$.store.book[*].author'); + * // first book in store has author + * $I->seeResponseJsonMatchesJsonPath('$.store.book[0].author'); + * // at least one item in store has price + * $I->seeResponseJsonMatchesJsonPath('$.store..price'); + * ?> + * ``` + * + * @part json + * @version 2.0.9 + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Module\REST::seeResponseJsonMatchesJsonPath() + */ + public function canSeeResponseJsonMatchesJsonPath($jsonPath) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('seeResponseJsonMatchesJsonPath', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks if json structure in response matches [JsonPath](http://goessner.net/articles/JsonPath/). + * JsonPath is XPath equivalent for querying Json structures. Try your JsonPath expressions [online](http://jsonpath.curiousconcept.com/). + * This assertion allows you to check the structure of response json. + * + * This method **require [`flow/jsonpath` > 0.2](https://github.com/FlowCommunications/JSONPath/) library to be installed**. + * + * ```json + * { "store": { + * "book": [ + * { "category": "reference", + * "author": "Nigel Rees", + * "title": "Sayings of the Century", + * "price": 8.95 + * }, + * { "category": "fiction", + * "author": "Evelyn Waugh", + * "title": "Sword of Honour", + * "price": 12.99 + * } + * ], + * "bicycle": { + * "color": "red", + * "price": 19.95 + * } + * } + * } + * ``` + * + * ```php + * <?php + * // at least one book in store has author + * $I->seeResponseJsonMatchesJsonPath('$.store.book[*].author'); + * // first book in store has author + * $I->seeResponseJsonMatchesJsonPath('$.store.book[0].author'); + * // at least one item in store has price + * $I->seeResponseJsonMatchesJsonPath('$.store..price'); + * ?> + * ``` + * + * @part json + * @version 2.0.9 + * @see \Codeception\Module\REST::seeResponseJsonMatchesJsonPath() + */ + public function seeResponseJsonMatchesJsonPath($jsonPath) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('seeResponseJsonMatchesJsonPath', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Opposite to seeResponseJsonMatchesJsonPath + * + * @param array $jsonPath + * @part json + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Module\REST::dontSeeResponseJsonMatchesJsonPath() + */ + public function cantSeeResponseJsonMatchesJsonPath($jsonPath) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeResponseJsonMatchesJsonPath', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Opposite to seeResponseJsonMatchesJsonPath + * + * @param array $jsonPath + * @part json + * @see \Codeception\Module\REST::dontSeeResponseJsonMatchesJsonPath() + */ + public function dontSeeResponseJsonMatchesJsonPath($jsonPath) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('dontSeeResponseJsonMatchesJsonPath', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Opposite to seeResponseContainsJson + * + * @part json + * @param array $json + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Module\REST::dontSeeResponseContainsJson() + */ + public function cantSeeResponseContainsJson($json = null) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeResponseContainsJson', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Opposite to seeResponseContainsJson + * + * @part json + * @param array $json + * @see \Codeception\Module\REST::dontSeeResponseContainsJson() + */ + public function dontSeeResponseContainsJson($json = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('dontSeeResponseContainsJson', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks if response is exactly the same as provided. + * + * @part json + * @part xml + * @param $response + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Module\REST::seeResponseEquals() + */ + public function canSeeResponseEquals($response) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('seeResponseEquals', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks if response is exactly the same as provided. + * + * @part json + * @part xml + * @param $response + * @see \Codeception\Module\REST::seeResponseEquals() + */ + public function seeResponseEquals($response) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('seeResponseEquals', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks response code equals to provided value. + * + * @part json + * @part xml + * @param $code + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Module\REST::seeResponseCodeIs() + */ + public function canSeeResponseCodeIs($code) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('seeResponseCodeIs', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks response code equals to provided value. + * + * @part json + * @part xml + * @param $code + * @see \Codeception\Module\REST::seeResponseCodeIs() + */ + public function seeResponseCodeIs($code) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('seeResponseCodeIs', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that response code is not equal to provided value. + * + * @part json + * @part xml + * @param $code + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Module\REST::dontSeeResponseCodeIs() + */ + public function cantSeeResponseCodeIs($code) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeResponseCodeIs', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that response code is not equal to provided value. + * + * @part json + * @part xml + * @param $code + * @see \Codeception\Module\REST::dontSeeResponseCodeIs() + */ + public function dontSeeResponseCodeIs($code) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('dontSeeResponseCodeIs', func_get_args())); + } +} diff --git a/tests/_support/_generated/FunctionalTesterActions.php b/tests/_support/_generated/FunctionalTesterActions.php new file mode 100644 index 0000000..86a9312 --- /dev/null +++ b/tests/_support/_generated/FunctionalTesterActions.php @@ -0,0 +1,18 @@ +<?php //[STAMP] ffada6587f597b23930f2f63d3309fd0 +namespace _generated; + +// This class was automatically generated by build task +// You should not change it manually as it will be overwritten on next build +// @codingStandardsIgnoreFile + +use Helper\Functional; + +trait FunctionalTesterActions +{ + /** + * @return \Codeception\Scenario + */ + abstract protected function getScenario(); + + +} diff --git a/tests/_support/_generated/UnitTesterActions.php b/tests/_support/_generated/UnitTesterActions.php new file mode 100644 index 0000000..661aeaa --- /dev/null +++ b/tests/_support/_generated/UnitTesterActions.php @@ -0,0 +1,348 @@ +<?php //[STAMP] c871459f363e639d6d4c21f535bb78f4 +namespace _generated; + +// This class was automatically generated by build task +// You should not change it manually as it will be overwritten on next build +// @codingStandardsIgnoreFile + +use Codeception\Module\Asserts; +use Helper\Unit; + +trait UnitTesterActions +{ + /** + * @return \Codeception\Scenario + */ + abstract protected function getScenario(); + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that two variables are equal. + * + * @param $expected + * @param $actual + * @param string $message + * + * @return mixed + * @see \Codeception\Module\Asserts::assertEquals() + */ + public function assertEquals($expected, $actual, $message = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('assertEquals', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that two variables are not equal + * + * @param $expected + * @param $actual + * @param string $message + * @see \Codeception\Module\Asserts::assertNotEquals() + */ + public function assertNotEquals($expected, $actual, $message = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('assertNotEquals', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that two variables are same + * + * @param $expected + * @param $actual + * @param string $message + * + * @return mixed + * @see \Codeception\Module\Asserts::assertSame() + */ + public function assertSame($expected, $actual, $message = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('assertSame', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that two variables are not same + * + * @param $expected + * @param $actual + * @param string $message + * @see \Codeception\Module\Asserts::assertNotSame() + */ + public function assertNotSame($expected, $actual, $message = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('assertNotSame', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that actual is greater than expected + * + * @param $expected + * @param $actual + * @param string $message + * @see \Codeception\Module\Asserts::assertGreaterThan() + */ + public function assertGreaterThan($expected, $actual, $message = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('assertGreaterThan', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * @deprecated + * @see \Codeception\Module\Asserts::assertGreaterThen() + */ + public function assertGreaterThen($expected, $actual, $message = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('assertGreaterThen', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that actual is greater or equal than expected + * + * @param $expected + * @param $actual + * @param string $message + * @see \Codeception\Module\Asserts::assertGreaterThanOrEqual() + */ + public function assertGreaterThanOrEqual($expected, $actual, $message = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('assertGreaterThanOrEqual', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * @deprecated + * @see \Codeception\Module\Asserts::assertGreaterThenOrEqual() + */ + public function assertGreaterThenOrEqual($expected, $actual, $message = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('assertGreaterThenOrEqual', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that actual is less than expected + * + * @param $expected + * @param $actual + * @param string $message + * @see \Codeception\Module\Asserts::assertLessThan() + */ + public function assertLessThan($expected, $actual, $message = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('assertLessThan', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that actual is less or equal than expected + * + * @param $expected + * @param $actual + * @param string $message + * @see \Codeception\Module\Asserts::assertLessThanOrEqual() + */ + public function assertLessThanOrEqual($expected, $actual, $message = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('assertLessThanOrEqual', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that haystack contains needle + * + * @param $needle + * @param $haystack + * @param string $message + * @see \Codeception\Module\Asserts::assertContains() + */ + public function assertContains($needle, $haystack, $message = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('assertContains', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that haystack doesn't contain needle. + * + * @param $needle + * @param $haystack + * @param string $message + * @see \Codeception\Module\Asserts::assertNotContains() + */ + public function assertNotContains($needle, $haystack, $message = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('assertNotContains', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that string match with pattern + * + * @param string $pattern + * @param string $string + * @param string $message + * @see \Codeception\Module\Asserts::assertRegExp() + */ + public function assertRegExp($pattern, $string, $message = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('assertRegExp', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that string not match with pattern + * + * @param string $pattern + * @param string $string + * @param string $message + * @see \Codeception\Module\Asserts::assertNotRegExp() + */ + public function assertNotRegExp($pattern, $string, $message = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('assertNotRegExp', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that variable is empty. + * + * @param $actual + * @param string $message + * @see \Codeception\Module\Asserts::assertEmpty() + */ + public function assertEmpty($actual, $message = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('assertEmpty', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that variable is not empty. + * + * @param $actual + * @param string $message + * @see \Codeception\Module\Asserts::assertNotEmpty() + */ + public function assertNotEmpty($actual, $message = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('assertNotEmpty', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that variable is NULL + * + * @param $actual + * @param string $message + * @see \Codeception\Module\Asserts::assertNull() + */ + public function assertNull($actual, $message = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('assertNull', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that variable is not NULL + * + * @param $actual + * @param string $message + * @see \Codeception\Module\Asserts::assertNotNull() + */ + public function assertNotNull($actual, $message = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('assertNotNull', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that condition is positive. + * + * @param $condition + * @param string $message + * @see \Codeception\Module\Asserts::assertTrue() + */ + public function assertTrue($condition, $message = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('assertTrue', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that condition is negative. + * + * @param $condition + * @param string $message + * @see \Codeception\Module\Asserts::assertFalse() + */ + public function assertFalse($condition, $message = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('assertFalse', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks if file exists + * + * @param string $filename + * @param string $message + * @see \Codeception\Module\Asserts::assertFileExists() + */ + public function assertFileExists($filename, $message = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('assertFileExists', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks if file doesn't exist + * + * @param string $filename + * @param string $message + * @see \Codeception\Module\Asserts::assertFileNotExists() + */ + public function assertFileNotExists($filename, $message = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('assertFileNotExists', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Fails the test with message. + * + * @param $message + * @see \Codeception\Module\Asserts::fail() + */ + public function fail($message) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('fail', func_get_args())); + } +} diff --git a/tests/brokerApi.suite.yml b/tests/brokerApi.suite.yml new file mode 100644 index 0000000..fa84d78 --- /dev/null +++ b/tests/brokerApi.suite.yml @@ -0,0 +1,7 @@ +class_name: ServerApiTester +modules: + enabled: + - REST: + url: http://127.0.0.1:9001/examples/ajax-broker/ajax.php + depends: PhpBrowser + part: Json
\ No newline at end of file diff --git a/tests/brokerApi/BrokerTesterCept.php b/tests/brokerApi/BrokerTesterCept.php new file mode 100644 index 0000000..86e7eea --- /dev/null +++ b/tests/brokerApi/BrokerTesterCept.php @@ -0,0 +1,54 @@ +<?php +$token = 'hello_world'; +$broker = "Api"; +$password = 'admin'; +$username = 'admin'; + +$I = new ServerApiTester($scenario); + +$I->wantTo('login through broker and view user data'); +$I->sendServerRequest('getUserInfo'); +$I->seeResponseIsJson(); +$I->seeResponseCodeIs(200); +$I->seeResponseEquals('null'); + +$I->sendServerRequest('attach'); +$I->seeResponseIsJson(); + +$I->sendServerRequest('getUserInfo'); +$I->seeResponseIsJson(); +$I->seeResponseCodeIs(200); +$I->seeResponseEquals('null'); + + +$I->sendServerRequest('login', [ + 'password' => $username, + 'username' => $password +]); +$I->seeResponseCodeIs(200); +$I->seeResponseIsJson(['token' => $token]); + +$I->sendServerRequest('getUserInfo'); +$I->seeResponseCodeIs(200); +$I->seeResponseIsJson(); +$I->seeResponseContainsJson([ + 'fullname' => 'jackie', + 'email' => 'jackie@admin.com', + 'username' => 'admin' +]); + +$I->sendServerRequest('detach'); +$I->sendServerRequest('attach'); + +$I->sendServerRequest('getUserInfo'); +$I->seeResponseCodeIs(200); +$I->seeResponseIsJson(); +$I->seeResponseContainsJson([ + 'fullname' => 'jackie', + 'email' => 'jackie@admin.com', + 'username' => 'admin' +]); + +$I->sendServerRequest('logout'); +$I->seeResponseCodeIs(200); +$I->seeResponseIsJson('null');
\ No newline at end of file diff --git a/tests/brokerApi/_bootstrap.php b/tests/brokerApi/_bootstrap.php new file mode 100644 index 0000000..8a88555 --- /dev/null +++ b/tests/brokerApi/_bootstrap.php @@ -0,0 +1,2 @@ +<?php +// Here you can initialize variables that will be available to your tests diff --git a/tests/serverApi.suite.yml b/tests/serverApi.suite.yml new file mode 100644 index 0000000..18d8b3b --- /dev/null +++ b/tests/serverApi.suite.yml @@ -0,0 +1,7 @@ +class_name: ServerApiTester +modules: + enabled: + - REST: + url: http://127.0.0.1:9000/examples/server + depends: PhpBrowser + part: Json
\ No newline at end of file diff --git a/tests/serverApi/ServerApiCept.php b/tests/serverApi/ServerApiCept.php new file mode 100644 index 0000000..3e98112 --- /dev/null +++ b/tests/serverApi/ServerApiCept.php @@ -0,0 +1,57 @@ +<?php +$token = 'hello_world'; +$broker = "ServerApi"; +$checksum = '514ee01d6ed9a88908790683c203e2ac'; +$password = 'admin'; +$username = 'admin'; + +$I = new ServerApiTester($scenario); +$I->defaultArgs = [ + 'token' => $token, + 'broker' => $broker, 'checksum' => $checksum, + 'PHPSESSID' => 'SSO-ServerApi-hello_world-0949c41dd2c747f8e1d4bfd85dd2f4d8' +]; + +$I->wantTo('attach session and view user info and logout'); +$I->sendServerRequest('attach', ['PHPSESSID' => '']); +$I->seeResponseIsJson(); +$I->seeResponseCodeIs(200); +$I->seeResponseContainsJson(['token' => $token]); + +$I->sendServerRequest('userInfo'); +$I->seeResponseCodeIs(401); +$I->seeResponseIsJson(); +$I->seeResponseContainsJson(['error' => 'Not logged in']); + +$I->sendServerRequest('login', [ + 'password' => 'wrong', + 'username' => 'wrong' +]); + +$I->seeResponseCodeIs(401); +$I->seeResponseIsJson(['error' => 'Incorrect credentials']); + +$I->sendServerRequest('login', [ + 'password' => $username, + 'username' => $password +]); +$I->seeResponseCodeIs(200); +$I->seeResponseIsJson(['token' => $token]); + +$I->sendServerRequest('userInfo'); +$I->seeResponseCodeIs(200); +$I->seeResponseIsJson(); +$I->seeResponseContainsJson([ + 'fullname' => 'jackie', + 'email' => 'jackie@admin.com', + 'username' => 'admin' +]); + +$I->sendServerRequest('logout'); +$I->seeResponseCodeIs(200); +$I->seeResponseIsJson(); + +$I->sendServerRequest('userInfo'); +$I->seeResponseCodeIs(401); +$I->seeResponseIsJson(); +$I->seeResponseContainsJson(['error' => 'Not logged in']);
\ No newline at end of file diff --git a/tests/serverApi/_bootstrap.php b/tests/serverApi/_bootstrap.php new file mode 100644 index 0000000..8a88555 --- /dev/null +++ b/tests/serverApi/_bootstrap.php @@ -0,0 +1,2 @@ +<?php +// Here you can initialize variables that will be available to your tests |