Commit e8c06b21cda3af868a7f2acbf254e7a7e72b24f5

Authored by Rodrigo Gonçalves
1 parent 0fc64633
Exists in master

Ajuste para visualizar campos read-only

CreateOpmUFSC.sh 0 → 100755
... ... @@ -0,0 +1,5 @@
  1 +#!/bin/bash
  2 +LOCAL="$PWD"
  3 +cd /opt/otrs/bin
  4 +./otrs.PackageManager.pl -a build -p "$LOCAL"/NewTicketWizardUFSC.sopm -o "$LOCAL"/
  5 +cd $LOCAL
... ...
FixTemplateGenerator.diff 100644 → 100755
Kernel/Config/Files/NewTicketWizard.xml
... ... @@ -23,6 +23,7 @@
23 23 <JavaScript>thirdparty/alpaca/alpaca-full.min.js</JavaScript>
24 24 <JavaScript>thirdparty/alpaca/jquery.sumoselect.js</JavaScript>
25 25 <JavaScript>thirdparty/alpaca/datatables.js</JavaScript>
  26 + <JavaScript>thirdparty/maskedinput/jquery.maskedinput.min.js</JavaScript>
26 27 <JavaScript>thirdparty/jquery-validate-1.13.0/jquery.validate.js</JavaScript>
27 28 <CSS>alpaca/alpaca-newticketwizard.css</CSS>
28 29 <CSS>alpaca/sumoselect.css</CSS>
... ... @@ -43,6 +44,13 @@
43 44 <Description>Admin</Description>
44 45 <Title>Service forms</Title>
45 46 <NavBarName>Admin</NavBarName>
  47 + <Loader>
  48 + <CSS>jquery.jsonview.css</CSS>
  49 + <JavaScript>jquery.jsonview.js</JavaScript>
  50 + <JavaScript>jquery.chili.js</JavaScript>
  51 + <JavaScript>jquery.chili.recipes.javascript.js</JavaScript>
  52 + <JavaScript>jquery.chili.recipes.js</JavaScript>
  53 + </Loader>
46 54 <NavBarModule>
47 55 <Module>Kernel::Output::HTML::NavBarModuleAdmin</Module>
48 56 <Name>Service forms</Name>
... ... @@ -267,6 +275,7 @@
267 275 <JavaScript>thirdparty/alpaca/jquery.sumoselect.js</JavaScript>
268 276 <JavaScript>thirdparty/alpaca/datatables.js</JavaScript>
269 277 <JavaScript>thirdparty/jquery-validate-1.13.0/jquery.validate.js</JavaScript>
  278 + <JavaScript>thirdparty/maskedinput/jquery.maskedinput.min.js</JavaScript>
270 279 <CSS>alpaca/alpaca-newticketwizard.css</CSS>
271 280 <CSS>alpaca/sumoselect.css</CSS>
272 281 <CSS>alpaca/alpaca-jqueryui-newticketwizard.css</CSS>
... ...
Kernel/Modules/NewTicketWizard.pm
... ... @@ -158,6 +158,8 @@ sub Run {
158 158 }
159 159 elsif ( $ParamObject->GetParam( Param => "Subaction" ) eq "GetFormJSON" ) {
160 160 return $Self->GetFormJSON( ServiceID => $ParamObject->GetParam( Param => "ServiceID" ) );
  161 + } elsif ( $ParamObject->GetParam( Param => "Subaction" ) eq "GetFormCustomProps" ) {
  162 + return $Self->GetFormCustomProps( ServiceID => $ParamObject->GetParam( Param => "ServiceID" ) );
161 163 }
162 164 }
163 165 else {
... ... @@ -227,6 +229,31 @@ sub GetFormJSON {
227 229 );
228 230 }
229 231  
  232 +sub GetFormCustomProps {
  233 + my ( $Self, %Param ) = @_;
  234 + my %serviceForm;
  235 +
  236 + my $ServiceFormObject = $Kernel::OM->Get("Kernel::System::ServiceForm");
  237 + my $LayoutObject = $Kernel::OM->Get("Kernel::Output::HTML::Layout");
  238 + my $ParamObject = $Kernel::OM->Get("Kernel::System::Web::Request");
  239 +
  240 + my $QueueID = $ParamObject->GetParam( Param => "QueueID" );
  241 +
  242 + if ( $Param{ServiceID} ) {
  243 + %serviceForm = $ServiceFormObject->GetServiceFormForQueue( ServiceID => $Param{ServiceID}, QueueID => $QueueID );
  244 + if (! $serviceForm{ServiceID}) {
  245 + %serviceForm = $ServiceFormObject->GetServiceForm( ServiceID => $Param{ServiceID} );
  246 + }
  247 + }
  248 +
  249 + return $LayoutObject->Attachment(
  250 + ContentType => 'text/plain; charset=' . $LayoutObject->{Charset},
  251 + Content => $serviceForm{CustomProps} || "/**/",
  252 + Type => 'inline',
  253 + NoCache => 1,
  254 + );
  255 +}
  256 +
230 257 sub GetForm {
231 258 my ( $Self, %Param ) = @_;
232 259  
... ...
Kernel/Modules/NewTicketWizardPublic.pm
... ... @@ -163,7 +163,10 @@ sub Run {
163 163 }
164 164 elsif ( $ParamObject->GetParam( Param => "Subaction" ) eq "GetFormJSON" ) {
165 165 return $Self->GetFormJSON( ServiceID => $ParamObject->GetParam( Param => "ServiceID" ) );
  166 + } elsif ( $ParamObject->GetParam( Param => "Subaction" ) eq "GetFormCustomProps" ) {
  167 + return $Self->GetFormCustomProps( ServiceID => $ParamObject->GetParam( Param => "ServiceID" ) );
166 168 }
  169 +
167 170 }
168 171 else {
169 172 my ( $schema, $fields ) = $Self->GetForm();
... ... @@ -203,6 +206,32 @@ sub Run {
203 206 }
204 207 }
205 208  
  209 +sub GetFormCustomProps {
  210 + my ( $Self, %Param ) = @_;
  211 + my %serviceForm;
  212 +
  213 + my $ServiceFormObject = $Kernel::OM->Get("Kernel::System::ServiceForm");
  214 + my $LayoutObject = $Kernel::OM->Get("Kernel::Output::HTML::Layout");
  215 + my $ParamObject = $Kernel::OM->Get("Kernel::System::Web::Request");
  216 +
  217 + my $QueueID = $ParamObject->GetParam( Param => "QueueID" );
  218 +
  219 + if ( $Param{ServiceID} ) {
  220 + %serviceForm = $ServiceFormObject->GetServiceFormForQueue( ServiceID => $Param{ServiceID}, QueueID => $QueueID );
  221 + if (! $serviceForm{ServiceID}) {
  222 + %serviceForm = $ServiceFormObject->GetServiceForm( ServiceID => $Param{ServiceID} );
  223 + }
  224 + }
  225 +
  226 + return $LayoutObject->Attachment(
  227 + ContentType => 'text/plain; charset=' . $LayoutObject->{Charset},
  228 + Content => $serviceForm{CustomProps} || "/**/",
  229 + Type => 'inline',
  230 + NoCache => 1,
  231 + );
  232 +}
  233 +
  234 +
206 235 sub GetFormJSON {
207 236 my ( $Self, %Param ) = @_;
208 237 my %serviceForm;
... ...
Kernel/Modules/NewTicketWizardServiceForm.pm
... ... @@ -67,6 +67,7 @@ sub Run {
67 67 $Data{Form} = $serviceForm{Form};
68 68 $Data{Schema} = $serviceForm{Schema};
69 69 $Data{FixedValues} = $serviceForm{FixedValues};
  70 + $Data{CustomProps} = $serviceForm{CustomProps};
70 71 $Data{ServiceID} = $ParamObject->GetParam( Param => "ServiceID" );
71 72 $Data{QueueID} = $ParamObject->GetParam( Param => "QueueID" );
72 73  
... ... @@ -94,6 +95,7 @@ sub Run {
94 95 Introduction => $ParamObject->GetParam( Param => "Introduction" ),
95 96 Form => $ParamObject->GetParam( Param => "Form" ),
96 97 Schema => $ParamObject->GetParam( Param => "Schema" ),
  98 + CustomProps => $ParamObject->GetParam( Param => "CustomProps" ),
97 99 FixedValues => $ParamObject->GetParam( Param => "FixedValues" ),
98 100 );
99 101 } else {
... ... @@ -102,6 +104,7 @@ sub Run {
102 104 Introduction => $ParamObject->GetParam( Param => "Introduction" ),
103 105 Form => $ParamObject->GetParam( Param => "Form" ),
104 106 Schema => $ParamObject->GetParam( Param => "Schema" ),
  107 + CustomProps => $ParamObject->GetParam( Param => "CustomProps" ),
105 108 FixedValues => $ParamObject->GetParam( Param => "FixedValues" ),
106 109 );
107 110 }
... ...
Kernel/Output/HTML/Standard/CustomerFooterNTWUFSC.tt
... ... @@ -7,7 +7,7 @@
7 7 # did not receive this file, see http://www.gnu.org/licenses/agpl.txt.
8 8 # --
9 9  
10   -<div id="footerF" align="center" style="position: absolute; bottom: 10px; width: 100%; margin-top: 18px; margin-bottom: 8px;" class="noPrint">
  10 +<div id="footerF" align="center" style="bottom: 10px; width: 100%; margin-top: 18px; margin-bottom: 8px;" class="noPrint">
11 11  
12 12 <div style="font-size: 0px;">
13 13 <div style="height: 2px; width: 100%; background-image: url('/otrs-web/skins/Customer/default/images/queues-panel/separador.gif'); background-repeat: repeat-x; background-position: 0 50%;"></div>
... ...
Kernel/Output/HTML/Standard/NewTicketWizardServiceFormEdit.tt
... ... @@ -31,15 +31,21 @@
31 31 </div>
32 32 <div class="Clear"></div>
33 33  
34   - <label for="Form">[% Translate("Form") | html %]: </label>
  34 + <label for="FormUI">[% Translate("Form") | html %]: </label>
35 35 <div class="Field">
36   - <textarea name="Form" id="Form" class="W50pc " rows="20">[% Data.Form | html %]</textarea>
  36 +
  37 + <textarea name="Form" id="FormUI" style="width: 50%" class="W50pc " rows="20">[% Data.Form | html %]</textarea>
  38 + <button type="button" onclick='mostraEsconde("FormUI"); return false;'>Exibir JSON</button>
  39 + <div id="jsonFormUIDlg" style="height: 300px; overflow: auto; border-style: solid; border-width: 1px;"><div id="jsonForm"></div></div>
  40 +
37 41 </div>
38 42 <div class="Clear"></div>
39 43  
40 44 <label for="Schema">[% Translate("Schema") | html %]: </label>
41 45 <div class="Field">
42 46 <textarea name="Schema" id="Schema" class="W50pc " rows="20">[% Data.Schema | html %]</textarea>
  47 + <button type="button" onclick='mostraEsconde("Schema"); return false;'>Exibir JSON</button>
  48 + <div id="jsonSchemaDlg" style="height: 300px; overflow: auto; border-style: solid; border-width: 1px;"><div id="jsonSchema"></div></div>
43 49 </div>
44 50 <div class="Clear"></div>
45 51  
... ... @@ -49,6 +55,16 @@
49 55 </div>
50 56 <div class="Clear"></div>
51 57  
  58 + <label for="CustomProps">[% Translate("Custom Properties for basic schema. <BR/>S_xxxxx=yyyy => Schema<BR/>F_xxxxx=yyyy => Form") %]: </label>
  59 + <div class="Field">
  60 + <textarea name="CustomProps" id="CustomProps" class="W50pc " rows="20">[% Data.CustomProps | html %]</textarea>
  61 + <button type="button" onclick='mostraEsconde("CustomProps"); return false;'>Exibir JSON</button>
  62 + <div id="jsonCustomPropsDlg" style="height: 300px; overflow: auto; border-style: solid; border-width: 1px;">
  63 + <code class="chili-lang-javascript" id='jsCode'></code>
  64 + </div>
  65 + </div>
  66 + <div class="Clear"></div>
  67 +
52 68 <div class="Field SpacingTop">
53 69 <button class="Primary" type="submit" value="[% Translate("Submit") | html %]">[% Translate("Submit") | html %]</button>
54 70 [% Translate("or") | html %]
... ... @@ -59,3 +75,51 @@
59 75  
60 76 </form>
61 77 </div>
  78 +
  79 +
  80 +<script type="text/javascript">
  81 + function mostraEsconde(id) {
  82 + idJSON = "#json" + id + "Dlg";
  83 + id = "#" + id;
  84 + $(idJSON).toggle();
  85 + $(idJSON).width($(id).width());
  86 + }
  87 +
  88 +</script>
  89 +
  90 +[% WRAPPER JSOnDocumentComplete %]
  91 +<script type="text/javascript">
  92 +
  93 +
  94 + $("#jsonFormUIDlg").toggle();
  95 + $("#jsonSchemaDlg").toggle();
  96 + $("#jsonCustomPropsDlg").toggle();
  97 +
  98 + setInterval(function() {
  99 + var code = $("#CustomProps").val();
  100 + $("#jsCode").html(code);
  101 + $("#jsCode").chili();
  102 + }, 1000);
  103 +
  104 +
  105 + setInterval(function() {
  106 + var json = "{" + $("#Schema").val() + "}";
  107 + try {
  108 + json = JSON.parse(json);
  109 + $("#jsonSchema").JSONView(json);
  110 + } catch(err) {
  111 + $("#jsonSchema").JSONView({error: "Invalid JSON!"});
  112 + }
  113 + }, 1000);
  114 +
  115 + setInterval(function() {
  116 + var json = "{" + $("#FormUI").val() + "}";
  117 + try {
  118 + json = JSON.parse(json);
  119 + $("#jsonForm").JSONView(json);
  120 + } catch(err) {
  121 + $("#jsonForm").JSONView({error: "Invalid JSON!"});
  122 + }
  123 + }, 1000);
  124 +</script>
  125 +[% END %]
62 126 \ No newline at end of file
... ...
Kernel/System/ServiceForm.pm
... ... @@ -44,7 +44,7 @@ sub GetServiceForm {
44 44  
45 45 # get service form from db
46 46 $DBObject->Prepare(
47   - SQL => 'SELECT service_id, introduction, form, form_schema, fixed_values FROM service_form WHERE service_id = ? and queue_id is null',
  47 + SQL => 'SELECT service_id, introduction, form, form_schema, fixed_values, custom_props FROM service_form WHERE service_id = ? and queue_id is null',
48 48 Bind => [ \$Param{ServiceID} ],
49 49 Limit => 1,
50 50 );
... ... @@ -57,6 +57,7 @@ sub GetServiceForm {
57 57 $ServiceData{Form} = $Row[2];
58 58 $ServiceData{Schema} = $Row[3];
59 59 $ServiceData{FixedValues} = $Row[4];
  60 + $ServiceData{CustomProps} = $Row[5];
60 61 }
61 62  
62 63 return %ServiceData;
... ... @@ -76,7 +77,7 @@ sub GetServiceFormForQueue {
76 77  
77 78 # get service form from db
78 79 $DBObject->Prepare(
79   - SQL => 'SELECT service_id, introduction, form, form_schema, fixed_values FROM service_form WHERE service_id = ? and queue_id = ? ',
  80 + SQL => 'SELECT service_id, introduction, form, form_schema, fixed_values, custom_props FROM service_form WHERE service_id = ? and queue_id = ? ',
80 81 Bind => [ \$Param{ServiceID}, \$Param{QueueID} ],
81 82 Limit => 1,
82 83 );
... ... @@ -89,6 +90,7 @@ sub GetServiceFormForQueue {
89 90 $ServiceData{Form} = $Row[2];
90 91 $ServiceData{Schema} = $Row[3];
91 92 $ServiceData{FixedValues} = $Row[4];
  93 + $ServiceData{CustomProps} = $Row[5];
92 94 }
93 95  
94 96 return %ServiceData;
... ... @@ -119,14 +121,14 @@ sub SaveServiceForm {
119 121 my $update = ($serviceForm{ServiceID});
120 122  
121 123 if ($update) {
122   - $DBObject->Do(SQL => 'UPDATE service_form SET introduction=?,form=?,form_schema=?,fixed_values=? where service_id=? and queue_id is null',
  124 + $DBObject->Do(SQL => 'UPDATE service_form SET introduction=?,form=?,form_schema=?,fixed_values=?,custom_props=? where service_id=? and queue_id is null',
123 125 Bind => [
124   - \$Param{Introduction}, \$Param{Form}, \$Param{Schema}, \$Param{FixedValues}, \$Param{ServiceID}
  126 + \$Param{Introduction}, \$Param{Form}, \$Param{Schema}, \$Param{FixedValues}, \$Param{CustomProps}, \$Param{ServiceID}
125 127 ]);
126 128 } else {
127   - $DBObject->Do(SQL => 'INSERT INTO service_form(service_id,introduction,form,form_schema,fixed_values) VALUES (?,?,?,?,?)',
  129 + $DBObject->Do(SQL => 'INSERT INTO service_form(service_id,introduction,form,form_schema,fixed_values,custom_props) VALUES (?,?,?,?,?,?)',
128 130 Bind => [
129   - \$Param{ServiceID}, \$Param{Introduction}, \$Param{Form}, \$Param{Schema}, \$Param{FixedValues}
  131 + \$Param{ServiceID}, \$Param{Introduction}, \$Param{Form}, \$Param{Schema}, \$Param{FixedValues}, \$Param{CustomProps}
130 132 ]);
131 133 }
132 134  
... ... @@ -160,14 +162,14 @@ sub SaveServiceFormForQueue {
160 162 my $update = ($serviceForm{ServiceID});
161 163  
162 164 if ($update) {
163   - $DBObject->Do(SQL => 'UPDATE service_form SET introduction=?,form=?,form_schema=?,fixed_values=? where service_id=? and queue_id=? ',
  165 + $DBObject->Do(SQL => 'UPDATE service_form SET introduction=?,form=?,form_schema=?,fixed_values=?,custom_props=? where service_id=? and queue_id=? ',
164 166 Bind => [
165   - \$Param{Introduction}, \$Param{Form}, \$Param{Schema}, \$Param{FixedValues}, \$Param{ServiceID}, \$Param{QueueID}
  167 + \$Param{Introduction}, \$Param{Form}, \$Param{Schema}, \$Param{FixedValues}, \$Param{CustomProps}, \$Param{ServiceID}, \$Param{QueueID}
166 168 ]);
167 169 } else {
168   - $DBObject->Do(SQL => 'INSERT INTO service_form(service_id,introduction,form,form_schema,queue_id,fixed_values) VALUES (?,?,?,?,?,?)',
  170 + $DBObject->Do(SQL => 'INSERT INTO service_form(service_id,introduction,form,form_schema,queue_id,fixed_values,custom_props) VALUES (?,?,?,?,?,?,?)',
169 171 Bind => [
170   - \$Param{ServiceID}, \$Param{Introduction}, \$Param{Form}, \$Param{Schema}, \$Param{QueueID}, \$Param{FixedValues}
  172 + \$Param{ServiceID}, \$Param{Introduction}, \$Param{Form}, \$Param{Schema}, \$Param{QueueID}, \$Param{FixedValues}, \$Param{CustomProps}
171 173 ]);
172 174 }
173 175  
... ...
NewTicketWizard.sopm
1 1 <?xml version="1.0" encoding="utf-8" ?>
2 2 <otrs_package version="1.0">
3 3 <Name>NewTicketWizard</Name>
4   - <Version>1.9.3</Version>
  4 + <Version>1.9.11</Version>
5 5 <Framework>4.0.x</Framework>
6 6 <Vendor>SeTIC</Vendor>
7 7 <URL>http://www.setic.ufsc.br</URL>
... ... @@ -18,7 +18,12 @@
18 18 <ChangeLog version="1.8.1">Layout bug fix</ChangeLog>
19 19 <ChangeLog version="1.8.2">Multiselect component</ChangeLog>
20 20 <ChangeLog version="1.9.0">Table support</ChangeLog>
21   - <ChangeLog version="1.9.3">Support for custom template</ChangeLog>
  21 + <ChangeLog version="1.9.4">Support for custom template</ChangeLog>
  22 + <ChangeLog version="1.9.5">Shows and validates JSON in form editing</ChangeLog>
  23 + <ChangeLog version="1.9.6">Support for custom javascript in forms</ChangeLog>
  24 + <ChangeLog version="1.9.7">Fix for datatables instalation</ChangeLog>
  25 + <ChangeLog version="1.9.9">Fix for date fields</ChangeLog>
  26 + <ChangeLog version="1.9.11">Fix for public interface custom properties</ChangeLog>
22 27 <IntroInstall Type="post" Title="Thank you">New Ticket Wizard module installed successfully!</IntroInstall>
23 28 <BuildDate>?</BuildDate>
24 29 <BuildHost>?</BuildHost>
... ... @@ -46,8 +51,15 @@
46 51  
47 52 <File Permission="644" Location="var/httpd/htdocs/js/thirdparty/alpaca/alpaca-full.min.js"></File>
48 53 <File Permission="644" Location="var/httpd/htdocs/js/thirdparty/alpaca/jquery.sumoselect.js"></File>
49   - <File Permission="644" Location="var/httpd/htdocs/js/thirdparty/handlebars/handlebars.js"></File>
  54 + <File Permission="644" Location="var/httpd/htdocs/js/thirdparty/alpaca/datatables.js"></File>
  55 + <File Permission="644" Location="var/httpd/htdocs/js/thirdparty/handlebars/handlebars.js"></File>
  56 + <File Permission="644" Location="var/httpd/htdocs/js/jquery.jsonview.js"></File>
50 57 <File Permission="644" Location="var/httpd/htdocs/js/NewTicketWizard.js"></File>
  58 +
  59 + <File Permission="644" Location="var/httpd/htdocs/js/jquery.chili.js"></File>
  60 + <File Permission="644" Location="var/httpd/htdocs/js/jquery.chili.recipes.javascript.js"></File>
  61 + <File Permission="644" Location="var/httpd/htdocs/js/jquery.chili.recipes.js"></File>
  62 +
51 63  
52 64 <File Permission="644" Location="var/httpd/htdocs/skins/Customer/default/css/alpaca/images/alpaca-icons.png"></File>
53 65 <File Permission="644" Location="var/httpd/htdocs/skins/Customer/default/css/alpaca/images/date.png"></File>
... ... @@ -61,6 +73,10 @@
61 73 <File Permission="644" Location="var/httpd/htdocs/skins/Customer/default/css/alpaca/alpaca-jqueryui-newticketwizard.css"></File>
62 74 <File Permission="644" Location="var/httpd/htdocs/skins/Customer/default/css/alpaca/alpaca-newticketwizard.css"></File>
63 75 <File Permission="644" Location="var/httpd/htdocs/skins/Customer/default/css/alpaca/sumoselect.css"></File>
  76 + <File Permission="644" Location="var/httpd/htdocs/skins/Customer/default/css/alpaca/datatables.css"></File>
  77 +
  78 + <File Permission="644" Location="var/httpd/htdocs/skins/Agent/default/css/jquery.jsonview.css"></File>
  79 +
64 80  
65 81  
66 82 </Filelist>
... ...
NewTicketWizardUFSC.sopm
1 1 <?xml version="1.0" encoding="utf-8" ?>
2 2 <otrs_package version="1.0">
3 3 <Name>NewTicketWizardUFSC</Name>
4   - <Version>1.0.0</Version>
  4 + <Version>1.0.1</Version>
5 5 <Framework>4.0.x</Framework>
6 6 <Vendor>SeTIC</Vendor>
7 7 <URL>http://www.setic.ufsc.br</URL>
8 8 <License>GPLv2</License>
9 9 <Description>NewTicket Wizard Module Template for UFSC</Description>
10 10 <ChangeLog version="1.0.0">First version</ChangeLog>
  11 + <ChangeLog version="1.0.1">Fix for footer</ChangeLog>
11 12 <IntroInstall Type="post" Title="Thank you">New Ticket Wizard UFSC Template module installed successfully!</IntroInstall>
12 13 <BuildDate>?</BuildDate>
13 14 <BuildHost>?</BuildHost>
... ...
sqls.sql 100644 → 100755
... ... @@ -2,5 +2,7 @@ alter table service_form drop foreign key FK_service_form_service_id_id;
2 2 alter table service_form drop primary key;
3 3 alter table service_form add id int auto_increment not null primary key;
4 4 alter table service_form add queue_id int;
5   -
6 5 alter table service_form add fixed_values text;
  6 +
  7 +alter table service_form add custom_props text;
  8 +
... ...
var/httpd/htdocs/js/NewTicketWizard.js
... ... @@ -2,6 +2,7 @@
2 2 * Variables
3 3 */
4 4 var formAlpaca;
  5 +var activeQueue;
5 6  
6 7  
7 8 /**
... ... @@ -79,7 +80,78 @@ var postRenderCallback = function(form) {
79 80 return false;
80 81 });
81 82 }
  83 +
  84 + carregaCustomProps(activeQueue);
  85 +};
  86 +
  87 +
  88 +var postRenderCallbackPublic = function(form) {
  89 + formOptions = form.options.fields;
  90 + formAlpaca = form;
  91 +
  92 + Object.keys(formOptions).forEach(function (key) {
  93 + var value = formOptions[key];
  94 +
  95 + // Extension to set control width
  96 + if (value["control_width"]) {
  97 + $("[name='" + key + "']").width(value["control_width"]);
  98 + }
  99 + });
  100 +
  101 + if (form) {
  102 + $("[name='service']").val($("#ServiceID").val());
  103 + $("[name='submit']").css("font-size", "18px");
  104 +
  105 + form.form.registerSubmitHandler(function(e, form) {
  106 + // validate the entire form (top control + all children)
  107 + form.validate(true);
  108 +
  109 + // draw the validation state (top control + all children)
  110 + form.renderValidationState(true);
  111 +
  112 + // now display something
  113 + if (form.isFormValid()) {
  114 + return true;
  115 + } else {
  116 + alert("Dados inválidos!");
  117 + return false;
  118 + }
  119 + e.stopPropagation();
  120 + return false;
  121 + });
  122 + }
  123 +
  124 + carregaCustomPropsPublic(activeQueue);
82 125 };
  126 +
  127 +function carregaCustomPropsPublic(queue) {
  128 + if (! queue) {
  129 + queue = "";
  130 + }
  131 +
  132 + var url = "/otrs/public.pl?Action=NewTicketWizardPublic;Subaction=GetFormCustomProps" + queue;
  133 +
  134 + url += ";ServiceID=" + $("#ServiceID").val();
  135 +
  136 + $.getScript(url, function(data) {
  137 + }).fail(function(jqXHR, textStatus, errorThrown) {
  138 + alert(textStatus);
  139 + });
  140 +}
  141 +
  142 +function carregaCustomProps(queue) {
  143 + if (! queue) {
  144 + queue = "";
  145 + }
  146 + var url = "/otrs/customer.pl?Action=NewTicketWizard;Subaction=GetFormCustomProps" + queue;
  147 +
  148 + url += ";ServiceID=" + $("#ServiceID").val();
  149 +
  150 + $.getScript(url, function(data) {
  151 + }).fail(function(jqXHR, textStatus, errorThrown) {
  152 + alert(textStatus);
  153 + });
  154 +}
83 155  
84 156 function carregaForm(dataForm, sendText, action, queue) {
85 157 var url = "/otrs/customer.pl?Action=NewTicketWizard;Subaction=GetFormJSON" + queue;
... ... @@ -88,6 +160,7 @@ function carregaForm(dataForm, sendText, action, queue) {
88 160 formAlpaca.destroy();
89 161 }
90 162  
  163 + activeQueue = queue;
91 164 url += ";ServiceID=" + $("#ServiceID").val();
92 165  
93 166 $.getJSON(url, function(data) {
... ... @@ -109,9 +182,11 @@ function carregaForm(dataForm, sendText, action, queue) {
109 182  
110 183 $("[name='submit']").css("font-size", "18px");
111 184  
  185 +
  186 +
112 187  
113 188 }).fail(function(jqXHR, textStatus, errorThrown) {
114   - alert(textStatus);
  189 + alert("Erro ao recuperar: " + url + " => " + textStatus);
115 190 });
116 191 }
117 192  
... ... @@ -143,6 +218,7 @@ function carregaFormPublic(dataForm, sendText, action, queue) {
143 218 //$("#formTicket").find("select").val("");
144 219 }
145 220  
  221 + activeQueue = queue;
146 222 url += ";ServiceID=" + $("#ServiceID").val();
147 223  
148 224 $.getJSON(url, function(data) {
... ... @@ -154,14 +230,14 @@ function carregaFormPublic(dataForm, sendText, action, queue) {
154 230 "data": dataForm,
155 231 "schema": buildSchema(data[0]),
156 232 "options": buildOptions(data[1], sendText, action),
157   - "postRender": postRenderCallback,
  233 + "postRender": postRenderCallbackPublic,
158 234 "view": "jqueryui-create",
159 235 "ui": "jquery-ui"
160 236 });
161 237  
162 238  
163 239 }).fail(function(jqXHR, textStatus, errorThrown) {
164   - alert(textStatus);
  240 + alert("Erro ao recuperar: " + url + " => " + textStatus);
165 241 });
166 242 }
167 243  
... ...
var/httpd/htdocs/js/jquery.chili.js 0 → 100644
... ... @@ -0,0 +1,1810 @@
  1 +/*!
  2 + * Chili - the jQuery plugin for highlighting code
  3 + * http://noteslog.com/chili/
  4 + *
  5 + * Copyright 2010 Andrea Ercolino
  6 + * Dual licensed under the MIT and GPL licenses.
  7 + * http://docs.jquery.com/License
  8 + *
  9 + * VERSION: NEXT - 20151204 1106
  10 + */
  11 +
  12 +(function( $ )
  13 +{
  14 +
  15 + $.extend({
  16 + chili: {
  17 + options: {
  18 + whiteSpace: {
  19 + tabWidth: 4, //spaces
  20 + no1stLine: true //if empty
  21 + },
  22 + automatic: {
  23 + active: true,
  24 + selector: "code",
  25 + context: document
  26 + },
  27 + dynamic: {
  28 + active: true,
  29 + origin: '' //used like: recipeFolder + recipeName + '.js'
  30 + },
  31 + decoration: {
  32 + lineNumbers: !true
  33 + },
  34 + selection: {
  35 + active: true,
  36 + box: {
  37 + style: [
  38 + "position:absolute; z-index:3000; overflow:scroll;",
  39 + "width:16em;",
  40 + "height:9em;",
  41 + "border:1px solid gray;",
  42 + "padding:1em;",
  43 + "background-color:white;"
  44 + ].join(' '),
  45 + top: function(pageX, pageY, width, height)
  46 + {
  47 + var result = pageY - Math.round( height / 2 );
  48 + return result;
  49 + },
  50 + left: function(pageX, pageY, width, height)
  51 + {
  52 + var result = pageX /*- Math.round( width / 2 )*/;
  53 + return result;
  54 + }
  55 + }
  56 + }
  57 + }
  58 + }
  59 + });
  60 +
  61 +
  62 + $(function()
  63 + {
  64 + $.chili.loadStylesheetInline('.chili-ln-off {list-style-type: none;}');
  65 + $.extend($.chili, $.chili.options);
  66 +
  67 + if ($.chili.automatic.active)
  68 + {
  69 + $($.chili.automatic.selector, $.chili.automatic.context).chili();
  70 + }
  71 + });
  72 +
  73 +
  74 + $.extend($.chili, {
  75 + version: "next", // development started on 2010-01-06
  76 +
  77 + /**
  78 + * Returns the language piece of data for the given dom_element
  79 + *
  80 + * @param {Element} dom_element
  81 + *
  82 + * @return String
  83 + */
  84 + codeLanguage: function( dom_element ) {
  85 + var classes = $(dom_element).attr('class');
  86 + var matches = classes.match(/\bchili-lang-(\w+)/);
  87 + var result = matches ? matches[1] : '';
  88 + return result;
  89 + },
  90 +
  91 + /**
  92 + * Returns the line numbers data for the given dom_element
  93 + *
  94 + * @param {Element} dom_element
  95 + *
  96 + * @return Array
  97 + */
  98 + codeLineNumbers: function( dom_element ) {
  99 + var classes = $(dom_element).attr('class');
  100 + var matches = classes.match(/\bchili-ln-(\d+)-([\w][\w\-]*)|\bchili-ln-(\d+)/);
  101 + var result = ! matches
  102 + ? null
  103 + : matches[3]
  104 + ? [ matches[0], matches[3], '' ]
  105 + : [ matches[0], matches[1], matches[2] ];
  106 + return result;
  107 + },
  108 +
  109 + /**
  110 + * Returns the codes of any character of the given text
  111 + * (Used for developing Chili)
  112 + *
  113 + * @param {String} text
  114 + *
  115 + * @return String
  116 + */
  117 + revealChars: function ( text )
  118 + {
  119 + var result = [];
  120 + for (var i=0, iTop=text.length; i<iTop; i++)
  121 + {
  122 + result.push(text[i] + ' <- ' + text.charCodeAt(i));
  123 + }
  124 + result = result.join('\n');
  125 + return result;
  126 + },
  127 +
  128 + /**
  129 + * Loads the given CSS code as a new style element of head
  130 + *
  131 + * @param {string} sourceCode
  132 + */
  133 + loadStylesheetInline: function ( sourceCode )
  134 + {
  135 + if ( document.createElement )
  136 + {
  137 + var style_element = document.createElement( "style" );
  138 + style_element.type = "text/css";
  139 + if ( style_element.styleSheet )
  140 + {
  141 + style_element.styleSheet.cssText = sourceCode; // IE
  142 + }
  143 + else
  144 + {
  145 + var t = document.createTextNode( sourceCode );
  146 + style_element.appendChild( t );
  147 + }
  148 + var head = document.getElementsByTagName( "head" )[0];
  149 + head.appendChild( style_element );
  150 + }
  151 + },
  152 +
  153 + queue: {},
  154 +
  155 + recipes: {},
  156 +
  157 + filters: {
  158 + off: function() {
  159 + return this.text;
  160 + }
  161 + }
  162 + });
  163 +
  164 +
  165 + /**
  166 + * Highlights currently selected elements accordingly to the given options
  167 + *
  168 + * @param {Object} options
  169 + */
  170 + $.fn.chili = function( options )
  171 + {
  172 + var globals = $.extend({}, $.chili);
  173 + $.chili = $.extend( true, $.chili, options || {} );
  174 + this.each(function()
  175 + {
  176 + askDish( this );
  177 + });
  178 + $.chili = globals;
  179 + return this;
  180 + };
  181 +
  182 + /**
  183 + * Returns the recipe path from the given recipeName
  184 + *
  185 + * @param {String} recipeName
  186 + *
  187 + * @return String
  188 + */
  189 + function getRecipePath( recipeName )
  190 + {
  191 + var result = $.chili.dynamic.origin + 'jquery.chili.recipes.' + recipeName + '.js';
  192 + return result;
  193 + }
  194 +
  195 + /**
  196 + * Returns the recipe name from the given recipePath
  197 + *
  198 + * @param {String} recipePath
  199 + *
  200 + * @return String
  201 + */
  202 + function getRecipeName( recipePath )
  203 + {
  204 + var matches = recipePath.match(/\bjquery\.chili\.recipes\.([\w-]+)\.js$/i);
  205 + var result = matches[1];
  206 + return result;
  207 + }
  208 +
  209 + /**
  210 + * Detects the recipe to use for highlighting the given DOM element and
  211 + * makes it happen, for static and dynamic setups
  212 + *
  213 + * @param {Element} dom_element
  214 + */
  215 + function askDish( dom_element )
  216 + {
  217 + var recipeName = $.chili.codeLanguage( dom_element );
  218 + if ( '' == recipeName )
  219 + return;
  220 + var path = getRecipePath( recipeName );
  221 + if ( $.chili.dynamic.active && ! $.chili.recipes[ recipeName ] )
  222 + {
  223 + // dynamic setups come here
  224 + if ( ! $.chili.queue[ path ] )
  225 + {
  226 + downloadRecipe(path, makeDish, [path]);
  227 + }
  228 + $.chili.queue[ path ].push( dom_element );
  229 + }
  230 + else
  231 + {
  232 + // static setups come here
  233 + $(dom_element).trigger( 'chili.before_coloring', [recipeName] );
  234 + makeDish.apply( dom_element, [path] );
  235 + $(dom_element).trigger( 'chili.after_coloring', [recipeName] );
  236 + }
  237 + }
  238 +
  239 + /**
  240 + * Highlights the current DOM element using the recipe identified by the
  241 + * given recipePath
  242 + */
  243 + function makeDish( recipePath )
  244 + {
  245 + var recipeName = getRecipeName(recipePath);
  246 + var recipe = $.chili.recipes[ recipeName ];
  247 + if (! recipe)
  248 + return;
  249 + var ingredients = $( this ).text();
  250 + if (! ingredients)
  251 + return;
  252 + ingredients = fixWhiteSpaceAfterReading(ingredients);
  253 + replaceElement.apply({
  254 + selector: this,
  255 + subject: ingredients,
  256 + module: recipeName,
  257 + context: {}
  258 + });
  259 + fixTextSelection(this);
  260 + checkLineNumbers(this);
  261 + }
  262 +
  263 + /**
  264 + * Replaces source code in the given DOM element with its highlighted
  265 + * version
  266 + */
  267 + function replaceElement()
  268 + {
  269 + filtersPrepare(this);
  270 + var replacement = applyModule( this.subject, this.module, this.context );
  271 + replacement = filtersProcess(this, replacement);
  272 +
  273 + replacement = fixWhiteSpaceBeforeWriting( replacement );
  274 +
  275 + var dom_element = $( this.selector )[0];
  276 + dom_element.innerHTML = replacement;
  277 + }
  278 +
  279 +
  280 + /**
  281 + * Returns the requested action according to the empty configuration of
  282 + * the given values
  283 + *
  284 + * @param {String} recipeName
  285 + * @param {String} blockName
  286 + * @param {String} stepName
  287 + *
  288 + * @return String
  289 + */
  290 + function requestedAction( recipeName, blockName, stepName )
  291 + {
  292 + if ( '' != stepName ) return 'applyStep';
  293 + if ( '' != blockName ) return 'applyBlock';
  294 + if ( '' != recipeName ) return 'applyRecipe';
  295 + return '';
  296 + }
  297 +
  298 + /**
  299 + * Returns the interpretation of the given module into the given context
  300 + *
  301 + * @param {String} module
  302 + * @param {Object} context
  303 + *
  304 + * @return Object
  305 + */
  306 + function detectAction( module, context )
  307 + {
  308 + if (! module) return;
  309 + var re = new RegExp('^(?!(?:/$|.+/$|.+//$|.+//.))([^/]*)(?:/([^/]*)(?:/([^/]+))?)?$');
  310 + var matches = (module || '').match(re);
  311 + if (! matches) return; // Expected recipe[/block[/step]] module format
  312 + var recipeName = matches[1] || '';
  313 + var blockName = matches[2] || '';
  314 + var stepName = matches[3] || '';
  315 + var action = requestedAction( recipeName, blockName, stepName );
  316 + var recipe = getRecipe( recipeName, context );
  317 + var result = {
  318 + action: action
  319 + , recipeName: recipeName
  320 + , blockName: blockName
  321 + , stepName: stepName
  322 + , recipe: recipe
  323 + , module: module
  324 + , context: context
  325 + };
  326 + return result;
  327 + }
  328 +
  329 + /**
  330 + * Returns the cached recipe with the given recipeName if recipeName is
  331 + * not empty, else the recipe from context
  332 + *
  333 + * @param {String} recipeName
  334 + * @param {Object} context
  335 + *
  336 + * @return Object
  337 + */
  338 + function getRecipe( recipeName, context )
  339 + {
  340 + var recipe = null;
  341 + if ( '' == recipeName )
  342 + {
  343 + recipe = context.recipe;
  344 + }
  345 + else
  346 + {
  347 + recipe = $.chili.recipes[ recipeName ];
  348 + }
  349 + return recipe;
  350 + }
  351 +
  352 + /**
  353 + * Downloads a recipe by means of an ajax call and, on success, applies
  354 + * the cbFunction callback, passing it all cbData array elements as
  355 + * arguments, to any element waiting for being highlighted on the queue
  356 + * of the recipe identified by path
  357 + *
  358 + * @param {String} path
  359 + * @param {Function} cbFunction
  360 + * @param {Array} cbData
  361 + */
  362 + function downloadRecipe( path, cbFunction, cbData )
  363 + {
  364 + $.chili.queue[ path ] = [];
  365 + $.getScript( path, function( recipeLoaded )
  366 + {
  367 + var recipeName = getRecipeName( path );
  368 + var q = $.chili.queue[ path ];
  369 + for( var i = 0, iTop = q.length; i < iTop; i++ )
  370 + {
  371 + var el = q[ i ];
  372 + if ('undefined' != typeof el.selector)
  373 + {
  374 + el = $(el.selector)[0];
  375 + }
  376 + $(el).trigger( 'chili.before_coloring', [recipeName] );
  377 + cbFunction.apply(q[ i ], cbData);
  378 + $(el).trigger( 'chili.after_coloring', [recipeName] );
  379 + }
  380 + } );
  381 + }
  382 +
  383 + /**
  384 + * Returns the result of applying the given detected recipe to the given
  385 + * subject
  386 + *
  387 + * @param {String} subject
  388 + * @param {Object} detected
  389 + *
  390 + * @return String
  391 + */
  392 + function applyRecipe( subject, detected )
  393 + {
  394 + var recipe = detected.recipe;
  395 + result = cook(subject, recipe);
  396 + return result;
  397 + }
  398 +
  399 + /**
  400 + * Returns the result of applying the given detected block to the given
  401 + * subject
  402 + *
  403 + * @param {String} subject
  404 + * @param {Object} detected
  405 + *
  406 + * @return String
  407 + */
  408 + function applyBlock( subject, detected )
  409 + {
  410 + var blockName = detected.blockName;
  411 + var recipe = detected.recipe;
  412 + if (! (blockName in recipe))
  413 + {
  414 + result = escapeHtmlSpecialChars(subject);
  415 + }
  416 + else
  417 + {
  418 + result = cook(subject, recipe, blockName);
  419 + }
  420 + return result;
  421 + }
  422 +
  423 + /**
  424 + * Returns the result of applying the given detected step to the given
  425 + * subject
  426 + *
  427 + * @param {String} subject
  428 + * @param {Object} detected
  429 + *
  430 + * @return String
  431 + */
  432 + function applyStep( subject, detected )
  433 + {
  434 + var recipeName = detected.recipeName;
  435 + var blockName = detected.blockName;
  436 + var stepName = detected.stepName;
  437 + var recipe = detected.recipe;
  438 + var context = detected.context;
  439 + if ('' == blockName)
  440 + {
  441 + blockName = context.blockName;
  442 + }
  443 + if (false
  444 + || ! (blockName in recipe)
  445 + || ! (stepName in recipe[blockName]))
  446 + {
  447 + result = escapeHtmlSpecialChars(subject);
  448 + }
  449 + else
  450 + {
  451 + result = cook(subject, recipe, blockName, stepName);
  452 + }
  453 + return result;
  454 + }
  455 +
  456 + /**
  457 + * Returns the result of applying the given detected action to the given
  458 + * subject
  459 + *
  460 + * @param {String} subject
  461 + * @param {Object} detected
  462 + *
  463 + * @return String
  464 + */
  465 + function applyAction( subject, detected )
  466 + {
  467 + var result = '';
  468 + var action = detected.action;
  469 + switch (action)
  470 + {
  471 + case 'applyRecipe':
  472 + result = applyRecipe(subject, detected);
  473 + break;
  474 + case 'applyBlock':
  475 + result = applyBlock(subject, detected);
  476 + break;
  477 + case 'applyStep':
  478 + result = applyStep(subject, detected);
  479 + break;
  480 + default:
  481 + //nothing to do
  482 + break;
  483 + }
  484 + return result;
  485 + }
  486 +
  487 + /**
  488 + * Returns the result of applying the given detected action to the given
  489 + * subject
  490 + *
  491 + * @param {String} subject
  492 + * @param {Object} detected
  493 + *
  494 + * @return String
  495 + */
  496 + function applyDeferred( subject, detected )
  497 + {
  498 + // dynamic setups come here too
  499 + var path = getRecipePath(detected.recipeName);
  500 + if (! $.chili.queue[ path ])
  501 + {
  502 + downloadRecipe(path, replaceElement);
  503 + }
  504 + var cue = 'chili_' + unique();
  505 + $.chili.queue[ path ].push( {
  506 + selector: '#' + cue,
  507 + subject: subject,
  508 + module: detected.module,
  509 + context: detected.context
  510 + } );
  511 + result = '<span id="' + cue + '">' + result + '</span>';
  512 + return result;
  513 + }
  514 +
  515 + /**
  516 + * Returns the result of applying the given module to the given subject
  517 + * into the given context
  518 + *
  519 + * @param {String} subject
  520 + * @param {String} module
  521 + * @param {Object} context
  522 + *
  523 + * @return String
  524 + */
  525 + function applyModule( subject, module, context )
  526 + {
  527 + var result = '';
  528 + var detected = detectAction(module, context);
  529 + if (typeof detected == 'undefined')
  530 + {
  531 + result = escapeHtmlSpecialChars(subject);
  532 + }
  533 + else if (detected.recipe)
  534 + {
  535 + result = applyAction(subject, detected);
  536 + }
  537 + else if ( $.chili.dynamic.active )
  538 + {
  539 + result = applyDeferred(subject, detected);
  540 + }
  541 + else
  542 + {
  543 + result = escapeHtmlSpecialChars(subject);
  544 + }
  545 + return result;
  546 + }
  547 +
  548 + /**
  549 + * Returns a unique number. If the given text is not undefined the
  550 + * return value is guaranteed to be unique inside text
  551 + *
  552 + * @param {String} text
  553 + *
  554 + * @return Integer
  555 + */
  556 + function unique( text )
  557 + {
  558 + var result = (new Date()).valueOf();
  559 + while( text && text.indexOf( result ) > -1 );
  560 + {
  561 + result = (new Date()).valueOf();
  562 + }
  563 + return result;
  564 + }
  565 +
  566 +
  567 + /**
  568 + * Returns all the steps of the given blockName of the given recipe
  569 + *
  570 + * @param {String} recipe
  571 + * @param {String} blockName
  572 + *
  573 + * @return Array
  574 + */
  575 + function prepareBlock( recipe, blockName )
  576 + {
  577 + var steps = [];
  578 + var block = recipe[ blockName ];
  579 + for( var stepName in block )
  580 + {
  581 + var prepared = prepareStep( recipe, blockName, stepName );
  582 + steps.push( prepared );
  583 + }
  584 + return steps;
  585 + }
  586 +
  587 + /**
  588 + * Returns the number of sub matches in the given regular expression (as
  589 + * a string)
  590 + *
  591 + * @param {String} re
  592 + *
  593 + * @return integer
  594 + */
  595 + function numberOfSubmatches( re )
  596 + {
  597 + var submatches = re
  598 + .replace( /\\./g, "%" ) // disable any escaped character
  599 + .replace( /\[.*?\]/g, "%" ) // disable any character class
  600 + .match( /\((?!\?)/g ) // match any open parenthesis, not followed by a ?
  601 + ;
  602 + var result = (submatches || []).length;
  603 + return result;
  604 + }
  605 +
  606 + /**
  607 + * Returns a step built from the given stepName of the given blockName
  608 + * of the given recipe
  609 + *
  610 + * @param {String} recipe
  611 + * @param {String} blockName
  612 + * @param {String} stepName
  613 + *
  614 + * @return Object
  615 + */
  616 + function prepareStep( recipe, blockName, stepName )
  617 + {
  618 + var step = recipe[ blockName ][ stepName ];
  619 + var exp = ( typeof step._match == "string" )
  620 + ? step._match
  621 + : step._match.source;
  622 + var replacement = step._replace
  623 + ? step._replace
  624 + : '<span class="$0">$$</span>';
  625 + var result = {
  626 + recipe: recipe,
  627 + blockName: blockName,
  628 + stepName: stepName,
  629 + exp: '(' + exp + ')', // new exp will have 1 more submatch
  630 + length: numberOfSubmatches( exp ) + 1,
  631 + replacement: replacement
  632 + };
  633 + return result;
  634 + }
  635 +
  636 + /**
  637 + * Returns the given steps, with back references in the regular
  638 + * expression of each step renumbered according to the number of back
  639 + * references found in any previous step
  640 + *
  641 + * @param {Array} steps
  642 + *
  643 + * @return Array
  644 + */
  645 + function adjustBackReferences( steps )
  646 + {
  647 + var prevLength = 1;
  648 + var exps = [];
  649 + for (var i = 0, iTop = steps.length; i < iTop; i++) {
  650 + var exp = steps[ i ].exp;
  651 + exp = exp.replace( /\\\\|\\(\d+)/g,
  652 + function( m, aNum )
  653 + {
  654 + return !aNum ? m : "\\" + ( prevLength + 1 + parseInt( aNum, 10 ) );
  655 + }
  656 + );
  657 + exps.push( exp );
  658 + prevLength += steps[ i ].length;
  659 + }
  660 + return exps;
  661 + }
  662 +
  663 + /**
  664 + * Returns a regular expression built from all the given steps
  665 + *
  666 + * @param {Array} steps
  667 + *
  668 + * @return RegExp
  669 + */
  670 + function knowHow( steps, flags )
  671 + {
  672 + var prolog = '((?:\\s|\\S)*?)';
  673 + var epilog = '((?:\\s|\\S)+)';
  674 + var exps = adjustBackReferences( steps );
  675 + var source = '(?:' + exps.join( '|' ) + ')';
  676 + source = prolog + source + '|' + epilog;
  677 + return new RegExp( source, flags );
  678 + }
  679 +
  680 + /**
  681 + * Returns the given replacement, after adding the given prefix to all
  682 + * classes of all SPANs
  683 + *
  684 + * @param {String} prefix
  685 + * @param {String} replacement
  686 + *
  687 + * @return String
  688 + */
  689 + function addPrefix( prefix, replacement )
  690 + {
  691 + var lookFor = /(<span\s+class\s*=\s*(["']))((?:(?!__)\w)+\2\s*>)/ig;
  692 + var replaceWith = '$1' + prefix + '__$3';
  693 + var aux = replacement.replace( lookFor, replaceWith );
  694 + return aux;
  695 + }
  696 +
  697 + /**
  698 + * Returns the step in the given steps and its matches in the given
  699 + * allMatches
  700 + *
  701 + * @param {Object} steps the steps of a recipe
  702 + * @param {Array} allMatches the corresponding matches
  703 + *
  704 + * @return Object
  705 + */
  706 + function locateStepMatches( steps, allMatches )
  707 + {
  708 + var matchesIndex = 2;
  709 + for (var i = 0, iTop = steps.length; i < iTop; i++)
  710 + {
  711 + var step = steps[ i ];
  712 + var stepMatches = allMatches[ matchesIndex ];
  713 + if (stepMatches) break;
  714 + matchesIndex += step.length;
  715 + }
  716 + var matches = allMatches.slice(matchesIndex, matchesIndex + step.length);
  717 + matches.push( allMatches.index );
  718 + matches.push( allMatches.input );
  719 + return {step: step, matches: matches};
  720 + }
  721 +
  722 + /**
  723 + * Returns the replacement for the given stepMatches, based on the
  724 + * function in stepMatches.step.replacement
  725 + *
  726 + * @param {Object} stepMatches
  727 + *
  728 + * @return String
  729 + */
  730 + function functionReplacement( stepMatches )
  731 + {
  732 + var that =
  733 + {
  734 + x: function( subject, module )
  735 + {
  736 + var result = applyModule( subject, module, stepMatches.step );
  737 + return result;
  738 + }
  739 + };
  740 + var result = stepMatches.step.replacement.apply(that, stepMatches.matches);
  741 + return result;
  742 + }
  743 +
  744 + /**
  745 + * Returns the replacement for the given stepMatches, based on the
  746 + * template in stepMatches.step.replacement
  747 + *
  748 + * @param {Object} stepMatches
  749 + *
  750 + * @return String
  751 + */
  752 + function templateReplacement( stepMatches )
  753 + {
  754 + var re = /(\\\$)|(?:\$\$)|(?:\$(\d+))/g;
  755 + var substitution = function( m, escaped, K )
  756 + {
  757 + var result = '';
  758 + if ( escaped ) /* \$ */
  759 + {
  760 + result = "$";
  761 + }
  762 + else if ( !K ) /* $$ */
  763 + {
  764 + result = escapeHtmlSpecialChars( stepMatches.matches[ 0 ] ); //stepMatches
  765 + }
  766 + else if ( K == "0" ) /* $0 */
  767 + {
  768 + result = stepMatches.step.stepName;
  769 + }
  770 + else /* $K */
  771 + {
  772 + result = escapeHtmlSpecialChars( stepMatches.matches[ K ] );
  773 + }
  774 + return result;
  775 + };
  776 + var result = stepMatches.step.replacement.replace(re, substitution);
  777 + return result;
  778 + }
  779 +
  780 + /**
  781 + * Returns the replacement for any match found. This is a callback
  782 + * function passed to String.replace()
  783 + *
  784 + * @return String
  785 + */
  786 + function chef( steps, replaceArgs )
  787 + {
  788 + var result = '';
  789 + var anyMatch = replaceArgs[ 0 ];
  790 + if (! anyMatch) return result;
  791 +
  792 + var epilog = replaceArgs[ replaceArgs.length - 1 ];
  793 + if (epilog) {
  794 + result = escapeHtmlSpecialChars( epilog );
  795 + return result;
  796 + }
  797 + var stepMatches = locateStepMatches( steps, replaceArgs );
  798 + result = $.isFunction(stepMatches.step.replacement)
  799 + ? functionReplacement(stepMatches)
  800 + : templateReplacement(stepMatches)
  801 + ;
  802 + var prolog = replaceArgs[ 1 ];
  803 + prolog = escapeHtmlSpecialChars( prolog );
  804 + result = addPrefix( stepMatches.step.recipe._name, result );
  805 + result = prolog + result;
  806 + return result;
  807 + }
  808 +
  809 + /**
  810 + * Returns the given subject, after replacing all the matches of the
  811 + * given steps, of the given recipe
  812 + *
  813 + * @param {String} subject
  814 + * @param {Object} recipe
  815 + * @param {Array} steps
  816 + *
  817 + * @return String
  818 + */
  819 + function applySteps( subject, recipe, steps )
  820 + {
  821 + var flags = recipe._case
  822 + ? "g"
  823 + : "gi";
  824 + var expr = knowHow( steps, flags );
  825 + var result = [];
  826 + var matches;
  827 + while ((matches = expr.exec(subject)) != null && matches[0] != '')
  828 + {
  829 + var element = chef(steps, matches);
  830 + result.push(element);
  831 + }
  832 + result = result.join('');
  833 + return result;
  834 + }
  835 +
  836 + /**
  837 + * Returns the given ingredients, after applying the given steName of
  838 + * the given blockName of the given recipe to it
  839 + *
  840 + * @param {String} ingredients
  841 + * @param {Object} recipe
  842 + * @param {String} blockName
  843 + * @param {String} stepName
  844 + *
  845 + * @return String
  846 + */
  847 + function cook( ingredients, recipe, blockName, stepName )
  848 + {
  849 + if (stepName)
  850 + {
  851 + var step = prepareStep(recipe, blockName, stepName);
  852 + var steps = [step];
  853 + }
  854 + else
  855 + {
  856 + if (! blockName)
  857 + {
  858 + blockName = '_main';
  859 + checkSpices( recipe );
  860 + }
  861 + if (! blockName in recipe)
  862 + {
  863 + return escapeHtmlSpecialChars( ingredients );
  864 + }
  865 + var steps = prepareBlock(recipe, blockName);
  866 + }
  867 + var result = applySteps(ingredients, recipe, steps);
  868 + return result;
  869 + }
  870 +
  871 +
  872 + /**
  873 + * Returns a CSS class definition with the given className and the given
  874 + * classStyle
  875 + *
  876 + * @param {String} className
  877 + * @param {String} classStyle
  878 + *
  879 + * @return String
  880 + */
  881 + function cssClassDefinition( className, classStyle )
  882 + {
  883 + var result = ''
  884 + + '.' + className + '\n'
  885 + + '{\n'
  886 + + '\t' + classStyle + '\n'
  887 + + '}\n'
  888 + ;
  889 + return result;
  890 + }
  891 +
  892 + /**
  893 + * Returns the style sheet of the given recipe
  894 + *
  895 + * @param {Object} recipe
  896 + *
  897 + * @return string
  898 + */
  899 + function makeStylesheet( recipe )
  900 + {
  901 + var name = recipe._name;
  902 + var content = ['/* Chili -- ' + name + ' */'];
  903 + for (var blockName in recipe)
  904 + {
  905 + if ( blockName.search( /^_(?!main\b)/ ) >= 0 )
  906 + continue; // if _bar but not _main nor foo
  907 + var block = recipe[ blockName ];
  908 + for (var stepName in block)
  909 + {
  910 + var step = block[ stepName ];
  911 + if (! '_style' in step)
  912 + continue;
  913 + var style_def = step[ '_style' ];
  914 + if ( typeof style_def == 'string' )
  915 + {
  916 + var oStyle = {};
  917 + oStyle[ stepName ] = style_def;
  918 + style_def = oStyle;
  919 + }
  920 + for (var className in style_def)
  921 + {
  922 + var stepClass = name + '__' + className;
  923 + var stepStyle = style_def[ className ];
  924 + var def = cssClassDefinition( stepClass, stepStyle );
  925 + content.push(def);
  926 + }
  927 + }
  928 + }
  929 + var result = content.join('\n');
  930 + return result;
  931 + }
  932 +
  933 + /**
  934 + * If needed, generates and loads the style sheet of the given recipe
  935 + * into the current page
  936 + *
  937 + * @param {Object} recipe
  938 + */
  939 + function checkSpices( recipe )
  940 + {
  941 + var name = recipe._name;
  942 + if ( ! $.chili.queue[ name ] )
  943 + {
  944 + var stylesheet = makeStylesheet(recipe);
  945 + $.chili.loadStylesheetInline(stylesheet);
  946 + $.chili.queue[ name ] = true;
  947 + }
  948 + }
  949 +
  950 +
  951 + /**
  952 + * Returns the given sting padded to itself the given times
  953 + *
  954 + * @param {String} string
  955 + * @param {Number} times
  956 + */
  957 + function repeat( string, times )
  958 + {
  959 + var result = '';
  960 + for (var i = 0; i < times; i++)
  961 + {
  962 + result += string;
  963 + }
  964 + return result;
  965 + }
  966 +
  967 + /**
  968 + * Returns the given text, with all &, <, and > replaced by their HTML
  969 + * entities
  970 + *
  971 + * @param {String} text
  972 + *
  973 + * @return String
  974 + */
  975 + function escapeHtmlSpecialChars( text )
  976 + {
  977 + var result = text
  978 + .replace( /&/g, "&amp;" )
  979 + .replace( /</g, "&lt;" )
  980 + .replace( />/g, "&gt;" )
  981 + ;
  982 + return result;
  983 + }
  984 +
  985 + /**
  986 + * Returns the given text, with all &, <, and > replaced to their HTML
  987 + * entities
  988 + *
  989 + * @param {String} text
  990 + *
  991 + * @return String
  992 + */
  993 + function unescapeHtmlSpecialChars( text )
  994 + {
  995 + var result = text
  996 + .replace( /&amp;/g, "&" )
  997 + .replace( /&lt;/g, "<" )
  998 + .replace( /&gt;/g, ">" )
  999 + ;
  1000 + return result;
  1001 + }
  1002 +
  1003 + /**
  1004 + * Scans the given subject and calls the given callback, passing along
  1005 + * the given args, for each piece of text or html tag it finds
  1006 + *
  1007 + * @param {String} subject
  1008 + * @param {Function} callback
  1009 + * @param {Array} args
  1010 + */
  1011 + function scan( subject, callback, args )
  1012 + {
  1013 + args = args || [];
  1014 + var expr = /([\w\W]*?)(?:(<\w+[^>]*\/>)|(<\w+[^>]*>)|(<\/\w+[^>]*>))|([\w\W]+)/ig;
  1015 + var func = function(all, prolog, tag_empty, tag_open, tag_close, epilog)
  1016 + {
  1017 + var realOffset = matches.index;
  1018 + var token;
  1019 + if (epilog)
  1020 + {
  1021 + token = tokenMake('text', epilog, realOffset);
  1022 + callback.apply(token, args);
  1023 + }
  1024 + else
  1025 + {
  1026 + token = tokenMake('text', prolog, realOffset);
  1027 + callback.apply(token, args);
  1028 +
  1029 + realOffset += prolog.length;
  1030 + if (tag_empty)
  1031 + {
  1032 + token = tokenMake('empty', tag_empty, realOffset);
  1033 + }
  1034 + else if(tag_open)
  1035 + {
  1036 + token = tokenMake('open', tag_open, realOffset);
  1037 + }
  1038 + else if(tag_close)
  1039 + {
  1040 + token = tokenMake('close', tag_close, realOffset);
  1041 + }
  1042 + callback.apply(token, args);
  1043 + }
  1044 + };
  1045 + var matches;
  1046 + while ((matches = expr.exec(subject)) != null && matches[0] != '')
  1047 + {
  1048 + func.apply({}, matches);
  1049 + }
  1050 + }
  1051 +
  1052 + /**
  1053 + * Returns the given text, with all spaces replaced by the writingSpace
  1054 + * string
  1055 + *
  1056 + * @param {String} text
  1057 + *
  1058 + * @return String
  1059 + */
  1060 + function escapeSpaces( text )
  1061 + {
  1062 + var writingSpace = $.chili.whiteSpace.writingSpace;
  1063 + var result = text.replace(/ /g, writingSpace);
  1064 + return result;
  1065 + }
  1066 +
  1067 + /**
  1068 + * Returns the given text, with all tabs replaced by the writingTab
  1069 + * string
  1070 + *
  1071 + * @param {String} text
  1072 + *
  1073 + * @return String
  1074 + */
  1075 + function escapeTabs( text )
  1076 + {
  1077 + var writingTab = $.chili.whiteSpace.writingTab;
  1078 + var result = text.replace(/\t/g, writingTab);
  1079 + return result;
  1080 + }
  1081 +
  1082 + /**
  1083 + * Returns the given text, with all '\n' replaced by the browser new
  1084 + * line string
  1085 + *
  1086 + * @param {String} text
  1087 + *
  1088 + * @return String
  1089 + */
  1090 + function lineFeedsToNewLines( text )
  1091 + {
  1092 + var writingNewLine = $.chili.whiteSpace.writingNewLine;
  1093 + var result = text.replace(/\n/g, writingNewLine);
  1094 + return result;
  1095 + }
  1096 +
  1097 + /**
  1098 + * Returns the given text, with all the browser new line strings
  1099 + * replaced by '\n'
  1100 + *
  1101 + * @param {String} text
  1102 + *
  1103 + * @return String
  1104 + */
  1105 + function newLinesToLineFeeds( text )
  1106 + {
  1107 + var result = text;
  1108 + result = result.replace(/&nbsp;<BR>/ig, '\n');
  1109 + result = result.replace(/\r\n?/g, '\n');
  1110 + return result;
  1111 + }
  1112 +
  1113 + /**
  1114 + * Sets white space constants into $.chili
  1115 + *
  1116 + * @param {String} html
  1117 + */
  1118 + function setWhiteSpaceConstants( html )
  1119 + {
  1120 + $.chili.whiteSpace.writingSpace = '&#160;';
  1121 + $.chili.whiteSpace.writingTab = repeat('&#160;', $.chili.whiteSpace.tabWidth);
  1122 + $.chili.whiteSpace.writingNewLine = '\n';
  1123 + if (/\r\n?/.test(html))
  1124 + {
  1125 + if ($.browser.msie)
  1126 + {
  1127 + $.chili.whiteSpace.writingNewLine = '&#160;<br>';
  1128 + }
  1129 + else
  1130 + {
  1131 + $.chili.whiteSpace.writingNewLine = /\r\n/.test(html)
  1132 + ? '\r\n'
  1133 + : '\r';
  1134 + }
  1135 + }
  1136 + }
  1137 +
  1138 + /**
  1139 + * Returns the given text after making new lines uniform across
  1140 + * all browsers
  1141 + *
  1142 + * @param {String} text
  1143 + *
  1144 + * @return String
  1145 + */
  1146 + function fixWhiteSpaceAfterReading( html )
  1147 + {
  1148 + setWhiteSpaceConstants(html);
  1149 + var result = newLinesToLineFeeds(html);
  1150 + if ( $.chili.whiteSpace.no1stLine )
  1151 + {
  1152 + result = result.replace(/^\n/, '');
  1153 + }
  1154 + return result;
  1155 + }
  1156 +
  1157 + /**
  1158 + * Returns the given text after making new lines uniform across
  1159 + * all browsers
  1160 + *
  1161 + * @param {String} html
  1162 + *
  1163 + * @return String
  1164 + */
  1165 + function fixWhiteSpaceBeforeWriting( html )
  1166 + {
  1167 + var result = [];
  1168 + scan(html, function ()
  1169 + {
  1170 + var value = this.value;
  1171 + if (this.type == 'text')
  1172 + {
  1173 + value = escapeSpaces( value );
  1174 + value = escapeTabs( value );
  1175 + value = lineFeedsToNewLines( value );
  1176 + }
  1177 + result.push(value);
  1178 + });
  1179 + result = result.join('');
  1180 + return result;
  1181 + }
  1182 +
  1183 +
  1184 + /**
  1185 + * Wraps a given line into well formed open and close tags, based on the
  1186 + * given open stack
  1187 + *
  1188 + * @param {String} line
  1189 + * @param {Array} open
  1190 + *
  1191 + * @return Object
  1192 + */
  1193 + function well_form( line, open )
  1194 + {
  1195 + var close = [];
  1196 + var open_start = open.join('');
  1197 + scan(line, function()
  1198 + {
  1199 + if (this.type == 'open')
  1200 + {
  1201 + open.push(this.value);
  1202 + }
  1203 + else if (this.type == 'close')
  1204 + {
  1205 + open.pop();
  1206 + }
  1207 + });
  1208 + for (var i = 0, iTop = open.length; i < iTop; i++)
  1209 + {
  1210 + var tag_open = open[i];
  1211 + var tag_close = tag_open.replace(/^<(\w+)[^>]*>$/, '</$1>');
  1212 + close.unshift(tag_close);
  1213 + }
  1214 + var close_end = close.join('');
  1215 + line = open_start + line + close_end;
  1216 + return {
  1217 + line: line,
  1218 + open: open
  1219 + };
  1220 + }
  1221 +
  1222 + /**
  1223 + * Converts lines inside the given dom_element to list items into an
  1224 + * ordered list element
  1225 + *
  1226 + * @param {Element} dom_element
  1227 + *
  1228 + * @return String
  1229 + */
  1230 + function makeOrderedList( html )
  1231 + {
  1232 + var open = [];
  1233 + var expr = /(.*)\n/g;
  1234 + var func = function ( all, line )
  1235 + {
  1236 + var well_formed = well_form(line, open);
  1237 + open = well_formed.open;
  1238 + line = well_formed.line
  1239 + ? '<li>' + well_formed.line + '</li>'
  1240 + : '<li> </li>'; //leave a space in empty lines
  1241 + return line;
  1242 + };
  1243 + var result = html.replace(expr, func);
  1244 + result = '<ol>' + result + '</ol>';
  1245 + return result;
  1246 + }
  1247 +
  1248 + /**
  1249 + * Sets the start of the ol tag of the current DOM element
  1250 + *
  1251 + * @param {String} groupStart
  1252 + * @param {String} groupId
  1253 + * @param {String} start
  1254 + */
  1255 + function setLineNumbersStart( all, groupStart, groupId )
  1256 + {
  1257 + var start = parseInt( groupStart, 10 );
  1258 + if ( groupId )
  1259 + {
  1260 + var $pieces = $( '.' + all );
  1261 + var pos = $pieces.index( this );
  1262 + $pieces
  1263 + .slice( 0, pos )
  1264 + .each(
  1265 + function()
  1266 + {
  1267 + start += $( this ).find( 'li' ).length;
  1268 + }
  1269 + )
  1270 + ;
  1271 + }
  1272 + $(this).find( 'ol' ).attr('start', start);
  1273 + // refresh the window
  1274 + $('body')
  1275 + .width( $('body').width() - 1 )
  1276 + .width( $('body').width() + 1 )
  1277 + ;
  1278 + }
  1279 +
  1280 + /**
  1281 + * Make line numbers appear into the given dom_element
  1282 + *
  1283 + * @param {Element} dom_element
  1284 + */
  1285 + function addLineNumbers( dom_element )
  1286 + {
  1287 + var html = $(dom_element).html();
  1288 + html = fixWhiteSpaceAfterReading(html);
  1289 + html = makeOrderedList( html );
  1290 + html = fixWhiteSpaceBeforeWriting(html);
  1291 + dom_element.innerHTML = html;
  1292 + }
  1293 +
  1294 + /**
  1295 + * If needed, adds line numbers with a proper start to the given
  1296 + * dom_element
  1297 + *
  1298 + * @param {Element} dom_element
  1299 + */
  1300 + function checkLineNumbers( dom_element )
  1301 + {
  1302 + var ln = $.chili.codeLineNumbers(dom_element);
  1303 + if (ln)
  1304 + {
  1305 + addLineNumbers(dom_element);
  1306 + setLineNumbersStart.apply(dom_element, ln);
  1307 + }
  1308 + else if ($.chili.decoration.lineNumbers)
  1309 + {
  1310 + addLineNumbers(dom_element);
  1311 + }
  1312 + }
  1313 +
  1314 +
  1315 + /**
  1316 + * Makes filters from tags into that.subject, adds those filters to that
  1317 + * and cleans up that.subject
  1318 + *
  1319 + * @param {Object} that
  1320 + */
  1321 + function filtersPrepare( that )
  1322 + {
  1323 + var subject = that.subject;
  1324 + if (! /{:\w+\(/.test(subject))
  1325 + {
  1326 + return;
  1327 + }
  1328 + var format = 0;
  1329 + var expr = /({:(\w+)\((|(?:(['"])[^\4\n]*(?:\\.[^\4\n]*)*\4)(?:\s*,\s*((['"])[^\6\n]*(?:\\.[^\6\n]*)*\6))*)\)\[)((?:.|\n)*?)(\]\2:})/g;
  1330 + var func = function(all, tag_open, callback, args, ignore4, ignore5, ignore6, target, tag_close, offset)
  1331 + {
  1332 + eval('args = [' + args + '];');
  1333 + var filter = {
  1334 + original: target,
  1335 + start: offset - format,
  1336 + count: target.length,
  1337 + callback: callback,
  1338 + args: args
  1339 + };
  1340 + format += tag_open.length + tag_close.length;
  1341 + if ($.isArray(that.filters))
  1342 + {
  1343 + that.filters.push(filter);
  1344 + }
  1345 + else
  1346 + {
  1347 + that.filters = [filter];
  1348 + }
  1349 + return target;
  1350 + };
  1351 + subject = escapeHtmlSpecialChars(subject);
  1352 + subject = subject.replace(expr, func);
  1353 + subject = unescapeHtmlSpecialChars(subject);
  1354 + that.subject = subject;
  1355 + }
  1356 +
  1357 + /**
  1358 + * Makes up a token object based on the given type, value and start
  1359 + *
  1360 + * @param {String} type
  1361 + * @param {String} value
  1362 + * @param {Integer} start
  1363 + *
  1364 + * @return Object
  1365 + */
  1366 + function tokenMake( type, value, start )
  1367 + {
  1368 + var result = {
  1369 + type: type,
  1370 + value: value,
  1371 + start: start
  1372 + };
  1373 + return result;
  1374 + }
  1375 +
  1376 + /**
  1377 + * Splits the given html into its tags and texts
  1378 + *
  1379 + * @param {String} html
  1380 + *
  1381 + * @return Array
  1382 + */
  1383 + function tokenSplit( html )
  1384 + {
  1385 + var result = [];
  1386 + var format = 0;
  1387 + scan(html, function()
  1388 + {
  1389 + switch (this.type)
  1390 + {
  1391 + case 'empty':
  1392 + case 'open':
  1393 + case 'close':
  1394 + format += this.value.length;
  1395 + break;
  1396 + case 'text':
  1397 + this.start -= format;
  1398 + this.end = this.start + this.value.length;
  1399 + break;
  1400 + default:
  1401 + throw "no type case for '" + this.type + "'";
  1402 + break;
  1403 + }
  1404 + result.push(this);
  1405 + });
  1406 + return result;
  1407 + }
  1408 +
  1409 + /**
  1410 + * Strips empty span tags from the given html
  1411 + *
  1412 + * @param {String} html
  1413 + *
  1414 + * @return String
  1415 + */
  1416 + function stripEmpties( html )
  1417 + {
  1418 + var result = html.replace(/<span[^>]+><\/span>/g, '');
  1419 + return result;
  1420 + }
  1421 +
  1422 + /**
  1423 + * Joins values of all tokens
  1424 + *
  1425 + * @param {Array} tokens
  1426 + *
  1427 + * @return String
  1428 + */
  1429 + function tokenJoin( tokens )
  1430 + {
  1431 + var result = [];
  1432 + for (var i = 0, iTop = tokens.length; i < iTop; i++)
  1433 + {
  1434 + result.push(tokens[i].value);
  1435 + }
  1436 + result = result.join('');
  1437 + result = stripEmpties(result);
  1438 + return result;
  1439 + }
  1440 +
  1441 + /**
  1442 + * Finds beginning and ending tokens in the given tokens that contain the
  1443 + * begin and end of the string that starts at the given start and whose
  1444 + * length is the given count
  1445 + *
  1446 + * @param {Array} tokens
  1447 + * @param {Integer} start
  1448 + * @param {Integer} count
  1449 + *
  1450 + * @return {Object}
  1451 + */
  1452 + function tokenFind( tokens, start, count )
  1453 + {
  1454 + var end = start + count;
  1455 + var firstPos = -1;
  1456 + var lastPos = -1;
  1457 + var previousSpan = '';
  1458 + var firstSpan = '';
  1459 + var lastSpan = '';
  1460 + for (var i = 0, iTop = tokens.length; i < iTop; i++)
  1461 + {
  1462 + var token = tokens[i];
  1463 + if (token.type == 'open')
  1464 + {
  1465 + previousSpan = token.value;
  1466 + }
  1467 + else if (token.type == 'close')
  1468 + {
  1469 + previousSpan = '';
  1470 + }
  1471 + else
  1472 + {
  1473 + if (token.start <= start && start < token.end)
  1474 + {
  1475 + firstPos = i;
  1476 + firstSpan = previousSpan;
  1477 + }
  1478 + if (token.start <= end && end < token.end)
  1479 + {
  1480 + lastPos = i;
  1481 + lastSpan = previousSpan;
  1482 + }
  1483 + if (firstPos != -1 && lastPos != -1)
  1484 + {
  1485 + break;
  1486 + }
  1487 + }
  1488 + }
  1489 + var result = {
  1490 + first: {
  1491 + position: firstPos,
  1492 + span: firstSpan
  1493 + },
  1494 + last: {
  1495 + position: lastPos,
  1496 + span: lastSpan
  1497 + }
  1498 + };
  1499 + return result;
  1500 + }
  1501 +
  1502 + /**
  1503 + * Returns the tokens that result from breaking in two given token at the
  1504 + * given position; if the given span is not empty, two additional tokens are
  1505 + * returned to leave the sequence well formed
  1506 + *
  1507 + * @param {Object} token
  1508 + * @param {Integer} position
  1509 + * @param {String} span
  1510 + *
  1511 + * @return {Object}
  1512 + */
  1513 + function tokenBreak( token, position, span )
  1514 + {
  1515 + var firstText = token.value.substr(0, position);
  1516 + var firstToken = tokenMake('text', firstText, token.start);
  1517 + firstToken.end = token.start + firstText.length;
  1518 +
  1519 + var secondText = token.value.substr(position);
  1520 + var secondToken = tokenMake('text', secondText, token.start + position);
  1521 + secondToken.end = token.start + position + secondText.length;
  1522 +
  1523 + var result = {
  1524 + first: [firstToken],
  1525 + second: [secondToken]
  1526 + };
  1527 + if (span)
  1528 + {
  1529 + result.first.push(tokenMake('close', '</span>'));
  1530 + result.second.unshift(tokenMake('open', span));
  1531 + }
  1532 + return result;
  1533 + }
  1534 +
  1535 + /**
  1536 + * Creates a new html token out of the given tokens and insert it at the
  1537 + * right position into them. The token contains all the string that starts
  1538 + * at the given start and whose length is the given count.
  1539 + * Resulting tokens are well formed.
  1540 + *
  1541 + * @param {Array} tokens
  1542 + * @param {Integer} start
  1543 + * @param {Integer} count
  1544 + *
  1545 + * @return {Object}
  1546 + */
  1547 + function tokenExtract( tokens, start, count )
  1548 + {
  1549 + var end = start + count;
  1550 +
  1551 + var found = tokenFind(tokens, start, count);
  1552 + var beforeTokens = tokens.slice(0, found.first.position);
  1553 + var firstToken = tokens[found.first.position];
  1554 + var middleTokens = tokens.slice(found.first.position + 1, found.last.position);
  1555 + var lastToken = tokens[found.last.position];
  1556 + var afterTokens = tokens.slice(found.last.position + 1);
  1557 +
  1558 + var firstTokens = tokenBreak(firstToken, start - firstToken.start, found.first.span);
  1559 + var lastTokens = tokenBreak(lastToken, end - lastToken.start, found.last.span);
  1560 +
  1561 + var newValue = [].concat(
  1562 + firstTokens.second,
  1563 + middleTokens,
  1564 + lastTokens.first
  1565 + );
  1566 + newValue = tokenJoin(newValue);
  1567 + var newToken = tokenMake('html', newValue, start);
  1568 +
  1569 + tokens = [].concat(
  1570 + beforeTokens,
  1571 + firstTokens.first,
  1572 + newToken,
  1573 + lastTokens.second,
  1574 + afterTokens
  1575 + );
  1576 + var result = {
  1577 + tokens: tokens,
  1578 + position: beforeTokens.length + firstTokens.first.length
  1579 + };
  1580 + return result;
  1581 + }
  1582 +
  1583 + /**
  1584 + * Applies all the filters of the given that to the given html
  1585 + *
  1586 + * @param {Object} that
  1587 + * @param {String} html
  1588 + *
  1589 + * @return String
  1590 + */
  1591 + function filtersProcess( that, html )
  1592 + {
  1593 + var result = html;
  1594 + if (! that.filters)
  1595 + {
  1596 + return result;
  1597 + }
  1598 + var tokens = [];
  1599 + for (var i = 0, iTop = that.filters.length; i < iTop; i++ )
  1600 + {
  1601 + var filter = that.filters[i];
  1602 + var callback = $.chili.filters && $.chili.filters[ filter.callback ];
  1603 + if (! (callback && $.isFunction(callback)))
  1604 + {
  1605 + continue;
  1606 + }
  1607 + if (0 == tokens.length)
  1608 + {
  1609 + tokens = tokenSplit(html);
  1610 + }
  1611 + var extraction = tokenExtract(tokens, filter.start, filter.count);
  1612 + tokens = extraction.tokens;
  1613 + var position = extraction.position;
  1614 + var filterInput = {
  1615 + text: filter.original,
  1616 + html: tokens[ position ].value
  1617 + };
  1618 + var args = filter.args;
  1619 + var filterOutput = callback.apply(filterInput, args);
  1620 + tokens[ position ].value = filterOutput;
  1621 + }
  1622 + if (0 < tokens.length)
  1623 + {
  1624 + result = tokenJoin(tokens);
  1625 + }
  1626 + return result;
  1627 + }
  1628 +
  1629 +
  1630 + /**
  1631 + * Clears anything that was selected before
  1632 + */
  1633 + function clearPreviousSelection()
  1634 + {
  1635 + if ($.browser.msie)
  1636 + {
  1637 + document.selection.empty();
  1638 + }
  1639 + else
  1640 + {
  1641 + window.getSelection().removeAllRanges();
  1642 + }
  1643 + }
  1644 +
  1645 + /**
  1646 + * Resets the currently selected element
  1647 + *
  1648 + * This is later used to check that the user selected text from
  1649 + * the same element
  1650 + */
  1651 + function resetSelectedTextElement()
  1652 + {
  1653 + element = this;
  1654 + clearPreviousSelection();
  1655 + }
  1656 +
  1657 + /**
  1658 + * Returns the text selected by the user
  1659 + */
  1660 + function getSelectedText()
  1661 + {
  1662 + var result;
  1663 + if ($.browser.msie)
  1664 + {
  1665 + result = document.selection.createRange().htmlText;
  1666 + }
  1667 + else
  1668 + {
  1669 + var selection = window.getSelection();
  1670 + var range = selection.getRangeAt(0);
  1671 + selection = selection.toString();
  1672 + range = range.toString();
  1673 + //selection works for line numbers on, range otherwise
  1674 + result = /\n/.test(selection) ? selection : range;
  1675 + }
  1676 + return result;
  1677 + }
  1678 +
  1679 + /**
  1680 + * Returns the given html after replacing any HTML break and block by a
  1681 + * new line
  1682 + *
  1683 + * @param {String} html
  1684 + *
  1685 + * @return String
  1686 + */
  1687 + function preserveNewLines( html )
  1688 + {
  1689 + var newline_flag = unique(html);
  1690 + var text = '';
  1691 + if (/<br\b/i.test(html) || /<li\b/i.test(html))
  1692 + {
  1693 + if (/<br\b/i.test(html))
  1694 + {
  1695 + html = html.replace( /\<br[^>]*?\>/ig, newline_flag );
  1696 + }
  1697 + else if (/<li\b/i.test(html))
  1698 + {
  1699 + html = html.replace( /<ol[^>]*?>|<\/ol>|<li[^>]*?>/ig, '' ).replace( /<\/li>/ig, newline_flag );
  1700 + }
  1701 + var el = $( '<pre>' ).appendTo( 'body' ).hide()[0];
  1702 + el.innerHTML = html;
  1703 + text = $( el ).text().replace( new RegExp( newline_flag, "g" ), '\r\n' );
  1704 + $( el ).remove();
  1705 + }
  1706 + return text;
  1707 + }
  1708 +
  1709 + /**
  1710 + * Returns the given text, after removing garbage characters
  1711 + */
  1712 + function cleanText( text )
  1713 + {
  1714 + var result = $.browser.msie
  1715 + ? preserveNewLines(text)
  1716 + : text
  1717 + .replace( /\r/g, '' )
  1718 + .replace( /^# ?/g, '' )
  1719 + .replace( /\n# ?/g, '\n' );
  1720 + return result;
  1721 + }
  1722 +
  1723 + /**
  1724 + * Shows a dialog containing the given text
  1725 + */
  1726 + function makeDialog( selected, event )
  1727 + {
  1728 + var boxOptions = $.chili.selection.box;
  1729 + var boxTag = $.browser.msie
  1730 + ? ('<textarea style="' + boxOptions.style + '">')
  1731 + : ('<pre style="' + boxOptions.style + '">');
  1732 +
  1733 + var boxElement = $(boxTag)
  1734 + .appendTo( 'body' )
  1735 + .text( selected )
  1736 + .attr( 'id', 'chili_selection' )
  1737 + .click( function() { $(this).remove(); } )
  1738 + ;
  1739 + var top = boxOptions.top(event.pageX, event.pageY,
  1740 + boxElement.width(), boxElement.height());
  1741 + var left = boxOptions.left(event.pageX, event.pageY,
  1742 + boxElement.width(), boxElement.height());
  1743 + boxElement.css( { top: top, left: left } );
  1744 +
  1745 + return boxElement;
  1746 + }
  1747 +
  1748 + /**
  1749 + * Selects the text in the given $container
  1750 + */
  1751 + function selectTextAgain($container)
  1752 + {
  1753 + if ($.browser.msie)
  1754 + {
  1755 + $container[0].focus();
  1756 + $container[0].select();
  1757 + }
  1758 + else
  1759 + {
  1760 + var s = window.getSelection();
  1761 + s.removeAllRanges();
  1762 + var r = document.createRange();
  1763 + r.selectNodeContents( $container[0] );
  1764 + s.addRange( r );
  1765 + }
  1766 + }
  1767 +
  1768 + /**
  1769 + * Shows a dialog containing the text selected by the user
  1770 + */
  1771 + function displaySelectedTextDialog( event )
  1772 + {
  1773 + if (! (element && element == this))
  1774 + {
  1775 + return;
  1776 + }
  1777 + element = null;
  1778 +
  1779 + var selectedText = getSelectedText();
  1780 + if ( '' == selectedText )
  1781 + {
  1782 + return;
  1783 + }
  1784 + selectedText = cleanText(selectedText);
  1785 +
  1786 + var $container = makeDialog(selectedText, event);
  1787 + selectTextAgain($container);
  1788 + }
  1789 +
  1790 + /**
  1791 + * When a user selects highlighted text, IE and FF returns a mess: this
  1792 + * function displays a minimal dialog with the selected text, cleaned up
  1793 + */
  1794 + function fixTextSelection( dom_element )
  1795 + {
  1796 + //chrome, opera, and safari select PRE text correctly
  1797 + if ($.chili.selection.active && ($.browser.msie || $.browser.mozilla))
  1798 + {
  1799 + var element = null;
  1800 + $(dom_element)
  1801 + .parents()
  1802 + .filter("pre")
  1803 + .bind("mousedown", resetSelectedTextElement)
  1804 + .bind("mouseup", displaySelectedTextDialog)
  1805 + ;
  1806 + }
  1807 + }
  1808 +
  1809 + }
  1810 +)(jQuery);
... ...
var/httpd/htdocs/js/jquery.chili.recipes.javascript.js 0 → 100644
... ... @@ -0,0 +1,65 @@
  1 +jQuery.chili.recipes.javascript =
  2 +{
  3 + _name: 'js'
  4 + , _case: true
  5 + , _main: {
  6 + ml_comment: {
  7 + _match: /\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\//
  8 + , _style: 'color: gray;'
  9 + }
  10 + , sl_comment: {
  11 + _match: /\/\/.*/
  12 + , _style: 'color: green;'
  13 + }
  14 + , string: {
  15 + _match: /(?:\'[^\'\\\n]*(?:\\.[^\'\\\n]*)*\')|(?:\"[^\"\\\n]*(?:\\.[^\"\\\n]*)*\")/
  16 + , _style: 'color: teal;'
  17 + }
  18 + , num: {
  19 + _match: /\b[+-]?(?:\d*\.?\d+|\d+\.?\d*)(?:[eE][+-]?\d+)?\b/
  20 + , _style: 'color: red;'
  21 + }
  22 + , reg_not: { //this prevents "a / b / c" to be interpreted as a reg_exp
  23 + _match: /(?:\w+\s*)\/[^\/\\\n]*(?:\\.[^\/\\\n]*)*\/[gim]*(?:\s*\w+)/
  24 + , _replace: function( all ) {
  25 + return this.x( all, '//num' );
  26 + }
  27 + }
  28 + , reg_exp: {
  29 + _match: /\/[^\/\\\n]*(?:\\.[^\/\\\n]*)*\/[gim]*/
  30 + , _style: 'color: maroon;'
  31 + }
  32 + , brace: {
  33 + _match: /[\{\}]/
  34 + , _style: 'color: red; font-weight: bold;'
  35 + }
  36 + , statement: {
  37 + _match: /\b(with|while|var|try|throw|switch|return|if|for|finally|else|do|default|continue|const|catch|case|break)\b/
  38 + , _style: 'color: navy; font-weight: bold;'
  39 + }
  40 + , error: {
  41 + _match: /\b(URIError|TypeError|SyntaxError|ReferenceError|RangeError|EvalError|Error)\b/
  42 + , _style: 'color: Coral;'
  43 + }
  44 + , object: {
  45 + _match: /\b(String|RegExp|Object|Number|Math|Function|Date|Boolean|Array)\b/
  46 + , _style: 'color: DeepPink;'
  47 + }
  48 + , property: {
  49 + _match: /\b(undefined|arguments|NaN|Infinity)\b/
  50 + , _style: 'color: Purple; font-weight: bold;'
  51 + }
  52 + , 'function': {
  53 + _match: /\b(parseInt|parseFloat|isNaN|isFinite|eval|encodeURIComponent|encodeURI|decodeURIComponent|decodeURI)\b/
  54 + , _style: 'color: olive;'
  55 + }
  56 + , operator: {
  57 + _match: /\b(void|typeof|this|new|instanceof|in|function|delete)\b/
  58 + , _style: 'color: RoyalBlue; font-weight: bold;'
  59 + }
  60 + , liveconnect: {
  61 + _match: /\b(sun|netscape|java|Packages|JavaPackage|JavaObject|JavaClass|JavaArray|JSObject|JSException)\b/
  62 + , _style: 'text-decoration: overline;'
  63 + }
  64 + }
  65 +};
0 66 \ No newline at end of file
... ...
var/httpd/htdocs/js/jquery.chili.recipes.js 0 → 100644
... ... @@ -0,0 +1,347 @@
  1 +jQuery.chili.options.dynamic.active = false;
  2 +
  3 +
  4 +
  5 +/* this recipe uses a little trick for highlighting php code
  6 + * 1: replace each php snippet with a placeholder
  7 + * 2: highlight html without php and php snippets apart
  8 + * 3: replace each placeholder with its highlighted php snippet
  9 + *
  10 + * the trick is not perfect
  11 + */
  12 +jQuery.chili.recipes.php =
  13 +{
  14 + _name: "php"
  15 + , _case: true
  16 + , _main: {
  17 + all: {
  18 + _match: /[\w\W]*/
  19 + , _replace: function( all ) {
  20 + var placeholder = String.fromCharCode(0);
  21 + var blocks = [];
  22 + var that = this;
  23 + var no_php_1 = all.replace( /<\?[^?]*\?+(?:[^>][^?]*\?+)*>/g, function( block ) {
  24 + blocks.push( that.x( block, '/block/php_1' ) );
  25 + return placeholder;
  26 + } );
  27 + var no_php_2 = no_php_1.replace( /^[^?]*\?+(?:[^>][^?]*\?+)*>|<\?[\w\W]*$/g, function( block ) {
  28 + blocks.push( that.x( block, '/block/php_2' ) );
  29 + return placeholder;
  30 + } );
  31 + if( blocks.length ) {
  32 + var html = this.x( no_php_2, 'html' );
  33 + var count = 0;
  34 + return html.replace( new RegExp( placeholder, "g" ), function() {
  35 + return blocks[ count++ ];
  36 + } );
  37 + }
  38 + else {
  39 + return this.x( all, '/php' );
  40 + }
  41 + }
  42 + }
  43 + }
  44 + , block: {
  45 + php_1: { // --- <? +++ ?> ---
  46 + _match: /(<\?(?:php\b)?)([^?]*\?+(?:[^>][^?]*\?+)*>)/
  47 + , _replace: function( all, open, content ) {
  48 + return "<span class='start'>" + this.x( open ) + "</span>"
  49 + + this.x( content.replace( /\?>$/, '' ), '/php' )
  50 + + "<span class='end'>" + this.x( '?>' ) + "</span>";
  51 + }
  52 + , _style: {
  53 + start: "color: red; font-weight: bold"
  54 + , end: "color: red;"
  55 + }
  56 + }
  57 + , php_2: { // +++ ?> --- <? +++
  58 + _match: /([^?]*\?+(?:[^>][^?]*\?+)*>)|(<\?(?:php\b)?)([\w\W]*)/
  59 + , _replace: function( all, content, open2, content2 ) {
  60 + if( open2 ) {
  61 + return "<span class='start'>" + this.x( open2 ) + "</span>"
  62 + + this.x( content2, '/php' );
  63 + }
  64 + else {
  65 + return this.x( content.replace( /\?>$/, '' ), '/php' )
  66 + + "<span class='end'>" + this.x( '?>' ) + "</span>";
  67 + }
  68 + }
  69 + , _style: {
  70 + start: "color: red; font-weight: bold"
  71 + , end: "color: red;"
  72 + }
  73 + }
  74 + }
  75 + , php: {
  76 + mlcom: {
  77 + _match: /\/\*[^*]*\*+([^\/][^*]*\*+)*\//
  78 + , _style: "color: gray;"
  79 + }
  80 + , com: {
  81 + _match: /(?:\/\/.*)|(?:[^\\]\#.*)/
  82 + , _style: "color: green;"
  83 + }
  84 + , string1: {
  85 + _match: /\'[^\'\\]*(?:\\.[^\'\\]*)*\'/
  86 + , _style: "color: purple;"
  87 + }
  88 + , string2: {
  89 + _match: /\"[^\"\\]*(?:\\.[^\"\\]*)*\"/
  90 + , _style: "color: fuchsia;"
  91 + }
  92 + , value: {
  93 + _match: /\b(?:[Nn][Uu][Ll][Ll]|[Tt][Rr][Uu][Ee]|[Ff][Aa][Ll][Ss][Ee])\b/
  94 + , _style: "color: gray; font-weight: bold;"
  95 + }
  96 + , number: {
  97 + _match: /\b[+-]?(\d*\.?\d+|\d+\.?\d*)([eE][+-]?\d+)?\b/
  98 + , _style: "color: red;"
  99 + }
  100 + , const1: {
  101 + _match: /\b(?:DEFAULT_INCLUDE_PATH|E_(?:ALL|CO(?:MPILE_(?:ERROR|WARNING)|RE_(?:ERROR|WARNING))|ERROR|NOTICE|PARSE|STRICT|USER_(?:ERROR|NOTICE|WARNING)|WARNING)|P(?:EAR_(?:EXTENSION_DIR|INSTALL_DIR)|HP_(?:BINDIR|CONFIG_FILE_(?:PATH|SCAN_DIR)|DATADIR|E(?:OL|XTENSION_DIR)|INT_(?:MAX|SIZE)|L(?:IBDIR|OCALSTATEDIR)|O(?:S|UTPUT_HANDLER_(?:CONT|END|START))|PREFIX|S(?:API|HLIB_SUFFIX|YSCONFDIR)|VERSION))|__COMPILER_HALT_OFFSET__)\b/
  102 + , _style: "color: red;"
  103 + }
  104 + , const2: {
  105 + _match: /\b(?:A(?:B(?:DAY_(?:1|2|3|4|5|6|7)|MON_(?:1(?:0|1|2|)|2|3|4|5|6|7|8|9))|LT_DIGITS|M_STR|SSERT_(?:ACTIVE|BAIL|CALLBACK|QUIET_EVAL|WARNING))|C(?:ASE_(?:LOWER|UPPER)|HAR_MAX|O(?:DESET|NNECTION_(?:ABORTED|NORMAL|TIMEOUT)|UNT_(?:NORMAL|RECURSIVE))|R(?:EDITS_(?:ALL|DOCS|FULLPAGE|G(?:ENERAL|ROUP)|MODULES|QA|SAPI)|NCYSTR|YPT_(?:BLOWFISH|EXT_DES|MD5|S(?:ALT_LENGTH|TD_DES)))|URRENCY_SYMBOL)|D(?:AY_(?:1|2|3|4|5|6|7)|ECIMAL_POINT|IRECTORY_SEPARATOR|_(?:FMT|T_FMT))|E(?:NT_(?:COMPAT|NOQUOTES|QUOTES)|RA(?:_(?:D_(?:FMT|T_FMT)|T_FMT|YEAR)|)|XTR_(?:IF_EXISTS|OVERWRITE|PREFIX_(?:ALL|I(?:F_EXISTS|NVALID)|SAME)|SKIP))|FRAC_DIGITS|GROUPING|HTML_(?:ENTITIES|SPECIALCHARS)|IN(?:FO_(?:ALL|C(?:ONFIGURATION|REDITS)|ENVIRONMENT|GENERAL|LICENSE|MODULES|VARIABLES)|I_(?:ALL|PERDIR|SYSTEM|USER)|T_(?:CURR_SYMBOL|FRAC_DIGITS))|L(?:C_(?:ALL|C(?:OLLATE|TYPE)|M(?:ESSAGES|ONETARY)|NUMERIC|TIME)|O(?:CK_(?:EX|NB|SH|UN)|G_(?:A(?:LERT|UTH(?:PRIV|))|C(?:ONS|R(?:IT|ON))|D(?:AEMON|EBUG)|E(?:MERG|RR)|INFO|KERN|L(?:OCAL(?:0|1|2|3|4|5|6|7)|PR)|MAIL|N(?:DELAY|EWS|O(?:TICE|WAIT))|ODELAY|P(?:ERROR|ID)|SYSLOG|U(?:SER|UCP)|WARNING)))|M(?:ON_(?:1(?:0|1|2|)|2|3|4|5|6|7|8|9|DECIMAL_POINT|GROUPING|THOUSANDS_SEP)|_(?:1_PI|2_(?:PI|SQRTPI)|E|L(?:N(?:10|2)|OG(?:10E|2E))|PI(?:_(?:2|4)|)|SQRT(?:1_2|2)))|N(?:EGATIVE_SIGN|O(?:EXPR|STR)|_(?:CS_PRECEDES|S(?:EP_BY_SPACE|IGN_POSN)))|P(?:ATH(?:INFO_(?:BASENAME|DIRNAME|EXTENSION)|_SEPARATOR)|M_STR|OSITIVE_SIGN|_(?:CS_PRECEDES|S(?:EP_BY_SPACE|IGN_POSN)))|RADIXCHAR|S(?:EEK_(?:CUR|END|SET)|ORT_(?:ASC|DESC|NUMERIC|REGULAR|STRING)|TR_PAD_(?:BOTH|LEFT|RIGHT))|T(?:HOUS(?:ANDS_SEP|EP)|_FMT(?:_AMPM|))|YES(?:EXPR|STR))\b/
  106 + , _style: "color: red;"
  107 + }
  108 + , global: {
  109 + _match: /(?:\$GLOBALS|\$_COOKIE|\$_ENV|\$_FILES|\$_GET|\$_POST|\$_REQUEST|\$_SERVER|\$_SESSION|\$php_errormsg)\b/
  110 + , _style: "color: red;"
  111 + }
  112 + , keyword: {
  113 + _match: /\b(?:__CLASS__|__FILE__|__FUNCTION__|__LINE__|__METHOD__|abstract|and|array|as|break|case|catch|cfunction|class|clone|const|continue|declare|default|die|do|echo|else|elseif|empty|enddeclare|endfor|endforeach|endif|endswitch|endwhile|eval|exception|exit|extends|extends|final|for|foreach|function|global|if|implements|include|include_once|interface|isset|list|new|old_function|or|php_user_filter|print|private|protected|public|require|require_once|return|static|switch|this|throw|try|unset|use|var|while|xor)\b/
  114 + , _style: "color: navy; font-weight: bold;"
  115 + }
  116 + , variable: {
  117 + _match: /\$(\w+)/
  118 + , _replace: '<span class="keyword">$</span><span class="variable">$1</span>'
  119 + , _style: "color: #4040c2;"
  120 + }
  121 + , heredoc: {
  122 + _match: /(\<\<\<\s*)(\w+)((?:(?!\2).*\n)+)(\2)\b/
  123 + , _replace: '<span class="keyword">$1</span><span class="string1">$2</span><span class="string2">$3</span><span class="string1">$4</span>'
  124 + }
  125 + }
  126 +};
  127 +
  128 +
  129 +
  130 +jQuery.chili.recipes.html =
  131 +{
  132 + _name: 'html'
  133 + , _case: false
  134 + , _main: {
  135 + doctype: {
  136 + _match: /<!DOCTYPE\b[\w\W]*?>/
  137 + , _style: "color: #CC6600;"
  138 + }
  139 + , ie_style: {
  140 + _match: /(<!--\[[^\]]*\]>)([\w\W]*?)(<!\[[^\]]*\]-->)/
  141 + , _replace: function( all, open, content, close ) {
  142 + return "<span class='ie_style'>" + this.x( open ) + "</span>"
  143 + + this.x( content, '//style' )
  144 + + "<span class='ie_style'>" + this.x( close ) + "</span>";
  145 + }
  146 + , _style: "color: DarkSlateGray; font-weight: bold;"
  147 + }
  148 + , comment: {
  149 + _match: /<!--[\w\W]*?-->/
  150 + , _style: "color: #4040c2;"
  151 + }
  152 + , script: {
  153 + _match: /(<script\s+[^>]*>)([\w\W]*?)(<\/script\s*>)/
  154 + , _replace: function( all, open, content, close ) {
  155 + return this.x( open, '//tag_start' )
  156 + + this.x( content, 'javascript' )
  157 + + this.x( close, '//tag_end' );
  158 + }
  159 + }
  160 + , style: {
  161 + _match: /(<style\s+[^>]*>)([\w\W]*?)(<\/style\s*>)/
  162 + , _replace: function( all, open, content, close ) {
  163 + return this.x( open, '//tag_start' )
  164 + + this.x( content, 'css' )
  165 + + this.x( close, '//tag_end' );
  166 + }
  167 + }
  168 + // matches a starting tag of an element (with attrs)
  169 + // like "<div ... >" or "<img ... />"
  170 + , tag_start: {
  171 + _match: /(<\w+)((?:[?%]>|[\w\W])*?)(\/>|>)/
  172 + , _replace: function( all, open, content, close ) {
  173 + return "<span class='tag_start'>" + this.x( open ) + "</span>"
  174 + + this.x( content, '/tag_attrs' )
  175 + + "<span class='tag_start'>" + this.x( close ) + "</span>";
  176 + }
  177 + , _style: "color: navy; font-weight: bold;"
  178 + }
  179 + // matches an ending tag
  180 + // like "</div>"
  181 + , tag_end: {
  182 + _match: /<\/\w+\s*>|\/>/
  183 + , _style: "color: navy;"
  184 + }
  185 + , entity: {
  186 + _match: /&\w+?;/
  187 + , _style: "color: blue;"
  188 + }
  189 + }
  190 + , tag_attrs: {
  191 + // matches a name/value pair
  192 + attr: {
  193 + // before in $1, name in $2, between in $3, value in $4
  194 + _match: /(\W*?)([\w-]+)(\s*=\s*)((?:\'[^\']*(?:\\.[^\']*)*\')|(?:\"[^\"]*(?:\\.[^\"]*)*\"))/
  195 + , _replace: "$1<span class='attr_name'>$2</span>$3<span class='attr_value'>$4</span>"
  196 + , _style: { attr_name: "color: green;", attr_value: "color: maroon;" }
  197 + }
  198 + }
  199 +};
  200 +
  201 +
  202 +
  203 +jQuery.chili.recipes.javascript =
  204 +{
  205 + _name: 'js'
  206 + , _case: true
  207 + , _main: {
  208 + ml_comment: {
  209 + _match: /\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\//
  210 + , _style: 'color: gray;'
  211 + }
  212 + , sl_comment: {
  213 + _match: /\/\/.*/
  214 + , _style: 'color: green;'
  215 + }
  216 + , string: {
  217 + _match: /(?:\'[^\'\\\n]*(?:\\.[^\'\\\n]*)*\')|(?:\"[^\"\\\n]*(?:\\.[^\"\\\n]*)*\")/
  218 + , _style: 'color: teal;'
  219 + }
  220 + , num: {
  221 + _match: /\b[+-]?(?:\d*\.?\d+|\d+\.?\d*)(?:[eE][+-]?\d+)?\b/
  222 + , _style: 'color: red;'
  223 + }
  224 + , reg_not: { //this prevents "a / b / c" to be interpreted as a reg_exp
  225 + _match: /(?:\w+\s*)\/[^\/\\\n]*(?:\\.[^\/\\\n]*)*\/[gim]*(?:\s*\w+)/
  226 + , _replace: function( all ) {
  227 + return this.x( all, '//num' );
  228 + }
  229 + }
  230 + , reg_exp: {
  231 + _match: /\/[^\/\\\n]*(?:\\.[^\/\\\n]*)*\/[gim]*/
  232 + , _style: 'color: maroon;'
  233 + }
  234 + , brace: {
  235 + _match: /[\{\}]/
  236 + , _style: 'color: red; font-weight: bold;'
  237 + }
  238 + , statement: {
  239 + _match: /\b(with|while|var|try|throw|switch|return|if|for|finally|else|do|default|continue|const|catch|case|break)\b/
  240 + , _style: 'color: navy; font-weight: bold;'
  241 + }
  242 + , error: {
  243 + _match: /\b(URIError|TypeError|SyntaxError|ReferenceError|RangeError|EvalError|Error)\b/
  244 + , _style: 'color: Coral;'
  245 + }
  246 + , object: {
  247 + _match: /\b(String|RegExp|Object|Number|Math|Function|Date|Boolean|Array)\b/
  248 + , _style: 'color: DeepPink;'
  249 + }
  250 + , property: {
  251 + _match: /\b(undefined|arguments|NaN|Infinity)\b/
  252 + , _style: 'color: Purple; font-weight: bold;'
  253 + }
  254 + , 'function': {
  255 + _match: /\b(parseInt|parseFloat|isNaN|isFinite|eval|encodeURIComponent|encodeURI|decodeURIComponent|decodeURI)\b/
  256 + , _style: 'color: olive;'
  257 + }
  258 + , operator: {
  259 + _match: /\b(void|typeof|this|new|instanceof|in|function|delete)\b/
  260 + , _style: 'color: RoyalBlue; font-weight: bold;'
  261 + }
  262 + , liveconnect: {
  263 + _match: /\b(sun|netscape|java|Packages|JavaPackage|JavaObject|JavaClass|JavaArray|JSObject|JSException)\b/
  264 + , _style: 'text-decoration: overline;'
  265 + }
  266 + }
  267 +};
  268 +
  269 +
  270 +
  271 +jQuery.chili.recipes.css =
  272 +{
  273 + _name: 'css'
  274 + , _case: true
  275 + , _main: {
  276 + comment: {
  277 + _match: /\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\//
  278 + , _style: "color: olive;"
  279 + }
  280 + , directive: {
  281 + _match: /@\w+/
  282 + , _style: "color: fuchsia;"
  283 + }
  284 + , url: {
  285 + _match: /\b(url\s*\()([^)]+)(\))/
  286 + , _replace: "<span class='url'>$1</span>$2<span class='url'>$3</span>"
  287 + , _style: "color: fuchsia;"
  288 + }
  289 + , block: {
  290 + _match: /\{([\w\W]*?)\}/
  291 + , _replace: function( all, pairs ) {
  292 + return '{' + this.x( pairs, '/definition' ) + '}';
  293 + }
  294 + }
  295 + , 'class': {
  296 + _match: /\.\w+/
  297 + , _style: "color: #CC0066; font-weight: bold;"
  298 + }
  299 + , id: {
  300 + _match: /#\w+/
  301 + , _style: "color: IndianRed; font-weight: bold;"
  302 + }
  303 + , pseudo: {
  304 + _match: /:\w+/
  305 + , _style: "color: #CC9900;"
  306 + }
  307 + , element: {
  308 + _match: /\w+/
  309 + , _style: "color: Purple; font-weight: bold;"
  310 + }
  311 + }
  312 + , definition: {
  313 + comment: {
  314 + _match: /\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\//
  315 + }
  316 + , property: {
  317 + _match: /\b(?:zoom|z-index|writing-mode|word-wrap|word-spacing|word-break|width|widows|white-space|volume|voice-family|visibility|vertical-align|unicode-bidi|top|text-underline-position|text-transform|text-shadow|text-overflow|text-kashida-space|text-justify|text-indent|text-decoration|text-autospace|text-align-last|text-align|table-layout|stress|speech-rate|speak-punctuation|speak-numeral|speak-header|speak|size|scrollbar-track-color|scrollbar-shadow-color|scrollbar-highlight-color|scrollbar-face-color|scrollbar-dark-shadow-color|scrollbar-base-color|scrollbar-arrow-color|scrollbar-3d-light-color|ruby-position|ruby-overhang|ruby-align|right|richness|quotes|position|play-during|pitch-range|pitch|pause-before|pause-after|pause|page-break-inside|page-break-before|page-break-after|page|padding-top|padding-right|padding-left|padding-bottom|padding|overflow-Y|overflow-X|overflow|outline-width|outline-style|outline-color|outline|orphans|min-width|min-height|max-width|max-height|marks|marker-offset|margin-top|margin-right|margin-left|margin-bottom|margin|list-style-type|list-style-position|list-style-image|list-style|line-height|line-break|letter-spacing|left|layout-grid-type|layout-grid-mode|layout-grid-line|layout-grid-char-spacing|layout-grid-char|layout-grid|layout-flow|layer-background-image|layer-background-color|include-source|ime-mode|height|font-weight|font-variant|font-style|font-stretch|font-size-adjust|font-size|font-family|font|float|filter|empty-cells|elevation|display|direction|cursor|cue-before|cue-after|cue|counter-reset|counter-increment|content|color|clip|clear|caption-side|bottom|border-width|border-top-width|border-top-style|border-top-color|border-top|border-style|border-spacing|border-right-width|border-right-style|border-right-color|border-right|border-left-width|border-left-style|border-left-color|border-left|border-color|border-collapse|border-bottom-width|border-bottom-style|border-bottom-color|border-bottom|border|behavior|background-repeat|background-position-y|background-position-x|background-position|background-image|background-color|background-attachment|background|azimuth|accelerator)\s*:/
  318 + , _style: "color: #330066;"
  319 + }
  320 + , special: {
  321 + _match: /\b(?:-use-link-source|-set-link-source|-replace|-moz-user-select|-moz-user-modify|-moz-user-input|-moz-user-focus|-moz-outline-width|-moz-outline-style|-moz-outline-color|-moz-outline|-moz-opacity|-moz-border-top-colors|-moz-border-right-colors|-moz-border-radius-topright|-moz-border-radius-topleft|-moz-border-radius-bottomright|-moz-border-radius-bottomleft|-moz-border-radius|-moz-border-left-colors|-moz-border-bottom-colors|-moz-binding)\s*:/
  322 + , _style: "color: #330066; text-decoration: underline;"
  323 + }
  324 + , url: {
  325 + _match: /\b(url\s*\()([^)]+)(\))/
  326 + , _replace: "<span class='url'>$1</span>$2<span class='url'>$3</span>"
  327 + }
  328 + , value: {
  329 + _match: /\b(?:xx-small|xx-large|x-soft|x-small|x-slow|x-low|x-loud|x-large|x-high|x-fast|wider|wait|w-resize|visible|url|uppercase|upper-roman|upper-latin|upper-alpha|underline|ultra-expanded|ultra-condensed|tv|tty|transparent|top|thin|thick|text-top|text-bottom|table-row-group|table-row|table-header-group|table-footer-group|table-column-group|table-column|table-cell|table-caption|sw-resize|super|sub|status-bar|static|square|spell-out|speech|solid|soft|smaller|small-caption|small-caps|small|slower|slow|silent|show|separate|semi-expanded|semi-condensed|se-resize|scroll|screen|s-resize|run-in|rtl|rightwards|right-side|right|ridge|rgb|repeat-y|repeat-x|repeat|relative|projection|print|pre|portrait|pointer|overline|outside|outset|open-quote|once|oblique|nw-resize|nowrap|normal|none|no-repeat|no-open-quote|no-close-quote|ne-resize|narrower|n-resize|move|mix|middle|message-box|medium|marker|ltr|lowercase|lower-roman|lower-latin|lower-greek|lower-alpha|lower|low|loud|local|list-item|line-through|lighter|level|leftwards|left-side|left|larger|large|landscape|justify|italic|invert|inside|inset|inline-table|inline|icon|higher|high|hide|hidden|help|hebrew|handheld|groove|format|fixed|faster|fast|far-right|far-left|fantasy|extra-expanded|extra-condensed|expanded|embossed|embed|e-resize|double|dotted|disc|digits|default|decimal-leading-zero|decimal|dashed|cursive|crosshair|cross|crop|counters|counter|continuous|condensed|compact|collapse|code|close-quote|circle|center-right|center-left|center|caption|capitalize|braille|bottom|both|bolder|bold|block|blink|bidi-override|below|behind|baseline|avoid|auto|aural|attr|armenian|always|all|absolute|above)\b/
  330 + , _style: "color: #3366FF;"
  331 + }
  332 + , string: {
  333 + _match: /(?:\'[^\'\\\n]*(?:\\.[^\'\\\n]*)*\')|(?:\"[^\"\\\n]*(?:\\.[^\"\\\n]*)*\")/
  334 + , _style: "color: teal;"
  335 + }
  336 + , number: {
  337 + _match: /(?:\b[+-]?(?:\d*\.?\d+|\d+\.?\d*))(?:%|(?:(?:px|pt|em|)\b))/
  338 + , _style: "color: red;"
  339 + }
  340 + , color : {
  341 + _match: /(?:\#[a-fA-F0-9]{3,6})|\b(?:yellow|white|teal|silver|red|purple|olive|navy|maroon|lime|green|gray|fuchsia|blue|black|aqua|YellowGreen|Yellow|WhiteSmoke|White|Wheat|Violet|Turquoise|Tomato|Thistle|Teal|Tan|SteelBlue|SpringGreen|Snow|SlateGrey|SlateGray|SlateBlue|SkyBlue|Silver|Sienna|SeaShell|SeaGreen|SandyBrown|Salmon|SaddleBrown|RoyalBlue|RosyBrown|Red|Purple|PowderBlue|Plum|Pink|Peru|PeachPuff|PapayaWhip|PaleVioletRed|PaleTurquoise|PaleGreen|PaleGoldenRod|Orchid|OrangeRed|Orange|OliveDrab|Olive|OldLace|Navy|NavajoWhite|Moccasin|MistyRose|MintCream|MidnightBlue|MediumVioletRed|MediumTurquoise|MediumSpringGreen|MediumSlateBlue|MediumSeaGreen|MediumPurple|MediumOrchid|MediumBlue|MediumAquaMarine|Maroon|Magenta|Linen|LimeGreen|Lime|LightYellow|LightSteelBlue|LightSlateGrey|LightSlateGray|LightSkyBlue|LightSeaGreen|LightSalmon|LightPink|LightGrey|LightGreen|LightGray|LightGoldenRodYellow|LightCyan|LightCoral|LightBlue|LemonChiffon|LawnGreen|LavenderBlush|Lavender|Khaki|Ivory|Indigo|IndianRed|HotPink|HoneyDew|Grey|GreenYellow|Green|Gray|GoldenRod|Gold|GhostWhite|Gainsboro|Fuchsia|ForestGreen|FloralWhite|FireBrick|DodgerBlue|DimGrey|DimGray|DeepSkyBlue|DeepPink|Darkorange|DarkViolet|DarkTurquoise|DarkSlateGrey|DarkSlateGray|DarkSlateBlue|DarkSeaGreen|DarkSalmon|DarkRed|DarkOrchid|DarkOliveGreen|DarkMagenta|DarkKhaki|DarkGrey|DarkGreen|DarkGray|DarkGoldenRod|DarkCyan|DarkBlue|Cyan|Crimson|Cornsilk|CornflowerBlue|Coral|Chocolate|Chartreuse|CadetBlue|BurlyWood|Brown|BlueViolet|Blue|BlanchedAlmond|Black|Bisque|Beige|Azure|Aquamarine|Aqua|AntiqueWhite|AliceBlue)\b/
  342 + , _style: "color: green;"
  343 + }
  344 + }
  345 +};
  346 +
  347 +
... ...
var/httpd/htdocs/js/jquery.jsonview.js 0 → 100755
... ... @@ -0,0 +1,284 @@
  1 +
  2 +/*!
  3 +jQuery JSONView.
  4 +Licensed under the MIT License.
  5 + */
  6 +(function(jQuery) {
  7 + var $, Collapser, JSONFormatter, JSONView;
  8 + JSONFormatter = (function() {
  9 + function JSONFormatter(options) {
  10 + if (options == null) {
  11 + options = {};
  12 + }
  13 + this.options = options;
  14 + }
  15 +
  16 + JSONFormatter.prototype.htmlEncode = function(html) {
  17 + if (html !== null) {
  18 + return html.toString().replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
  19 + } else {
  20 + return '';
  21 + }
  22 + };
  23 +
  24 + JSONFormatter.prototype.jsString = function(s) {
  25 + s = JSON.stringify(s).slice(1, -1);
  26 + return this.htmlEncode(s);
  27 + };
  28 +
  29 + JSONFormatter.prototype.decorateWithSpan = function(value, className) {
  30 + return "<span class=\"" + className + "\">" + (this.htmlEncode(value)) + "</span>";
  31 + };
  32 +
  33 + JSONFormatter.prototype.valueToHTML = function(value, level) {
  34 + var valueType;
  35 + if (level == null) {
  36 + level = 0;
  37 + }
  38 + valueType = Object.prototype.toString.call(value).match(/\s(.+)]/)[1].toLowerCase();
  39 + return this["" + valueType + "ToHTML"].call(this, value, level);
  40 + };
  41 +
  42 + JSONFormatter.prototype.nullToHTML = function(value) {
  43 + return this.decorateWithSpan('null', 'null');
  44 + };
  45 +
  46 + JSONFormatter.prototype.numberToHTML = function(value) {
  47 + return this.decorateWithSpan(value, 'num');
  48 + };
  49 +
  50 + JSONFormatter.prototype.stringToHTML = function(value) {
  51 + var multilineClass, newLinePattern;
  52 + if (/^(http|https|file):\/\/[^\s]+$/i.test(value)) {
  53 + return "<a href=\"" + (this.htmlEncode(value)) + "\"><span class=\"q\">\"</span>" + (this.jsString(value)) + "<span class=\"q\">\"</span></a>";
  54 + } else {
  55 + multilineClass = '';
  56 + value = this.jsString(value);
  57 + if (this.options.nl2br) {
  58 + newLinePattern = /([^>\\r\\n]?)(\\r\\n|\\n\\r|\\r|\\n)/g;
  59 + if (newLinePattern.test(value)) {
  60 + multilineClass = ' multiline';
  61 + value = (value + '').replace(newLinePattern, '$1' + '<br />');
  62 + }
  63 + }
  64 + return "<span class=\"string" + multilineClass + "\">\"" + value + "\"</span>";
  65 + }
  66 + };
  67 +
  68 + JSONFormatter.prototype.booleanToHTML = function(value) {
  69 + return this.decorateWithSpan(value, 'bool');
  70 + };
  71 +
  72 + JSONFormatter.prototype.arrayToHTML = function(array, level) {
  73 + var collapsible, hasContents, index, numProps, output, value, _i, _len;
  74 + if (level == null) {
  75 + level = 0;
  76 + }
  77 + hasContents = false;
  78 + output = '';
  79 + numProps = array.length;
  80 + for (index = _i = 0, _len = array.length; _i < _len; index = ++_i) {
  81 + value = array[index];
  82 + hasContents = true;
  83 + output += '<li>' + this.valueToHTML(value, level + 1);
  84 + if (numProps > 1) {
  85 + output += ',';
  86 + }
  87 + output += '</li>';
  88 + numProps--;
  89 + }
  90 + if (hasContents) {
  91 + collapsible = level === 0 ? '' : ' collapsible';
  92 + return "[<ul class=\"array level" + level + collapsible + "\">" + output + "</ul>]";
  93 + } else {
  94 + return '[ ]';
  95 + }
  96 + };
  97 +
  98 + JSONFormatter.prototype.objectToHTML = function(object, level) {
  99 + var collapsible, hasContents, key, numProps, output, prop, value;
  100 + if (level == null) {
  101 + level = 0;
  102 + }
  103 + hasContents = false;
  104 + output = '';
  105 + numProps = 0;
  106 + for (prop in object) {
  107 + numProps++;
  108 + }
  109 + for (prop in object) {
  110 + value = object[prop];
  111 + hasContents = true;
  112 + key = this.options.escape ? this.jsString(prop) : prop;
  113 + output += "<li><span class=\"prop\"><span class=\"q\">\"</span>" + key + "<span class=\"q\">\"</span></span>: " + (this.valueToHTML(value, level + 1));
  114 + if (numProps > 1) {
  115 + output += ',';
  116 + }
  117 + output += '</li>';
  118 + numProps--;
  119 + }
  120 + if (hasContents) {
  121 + collapsible = level === 0 ? '' : ' collapsible';
  122 + return "{<ul class=\"obj level" + level + collapsible + "\">" + output + "</ul>}";
  123 + } else {
  124 + return '{ }';
  125 + }
  126 + };
  127 +
  128 + JSONFormatter.prototype.jsonToHTML = function(json) {
  129 + return "<div class=\"jsonview\">" + (this.valueToHTML(json)) + "</div>";
  130 + };
  131 +
  132 + return JSONFormatter;
  133 +
  134 + })();
  135 + (typeof module !== "undefined" && module !== null) && (module.exports = JSONFormatter);
  136 + Collapser = (function() {
  137 + function Collapser() {}
  138 +
  139 + Collapser.bindEvent = function(item, options) {
  140 + var collapser;
  141 + collapser = document.createElement('div');
  142 + collapser.className = 'collapser';
  143 + collapser.innerHTML = options.collapsed ? '+' : '-';
  144 + collapser.addEventListener('click', (function(_this) {
  145 + return function(event) {
  146 + return _this.toggle(event.target, options);
  147 + };
  148 + })(this));
  149 + item.insertBefore(collapser, item.firstChild);
  150 + if (options.collapsed) {
  151 + return this.collapse(collapser);
  152 + }
  153 + };
  154 +
  155 + Collapser.expand = function(collapser) {
  156 + var ellipsis, target;
  157 + target = this.collapseTarget(collapser);
  158 + if (target.style.display === '') {
  159 + return;
  160 + }
  161 + ellipsis = target.parentNode.getElementsByClassName('ellipsis')[0];
  162 + target.parentNode.removeChild(ellipsis);
  163 + target.style.display = '';
  164 + return collapser.innerHTML = '-';
  165 + };
  166 +
  167 + Collapser.collapse = function(collapser) {
  168 + var ellipsis, target;
  169 + target = this.collapseTarget(collapser);
  170 + if (target.style.display === 'none') {
  171 + return;
  172 + }
  173 + target.style.display = 'none';
  174 + ellipsis = document.createElement('span');
  175 + ellipsis.className = 'ellipsis';
  176 + ellipsis.innerHTML = ' &hellip; ';
  177 + target.parentNode.insertBefore(ellipsis, target);
  178 + return collapser.innerHTML = '+';
  179 + };
  180 +
  181 + Collapser.toggle = function(collapser, options) {
  182 + var action, collapsers, target, _i, _len, _results;
  183 + if (options == null) {
  184 + options = {};
  185 + }
  186 + target = this.collapseTarget(collapser);
  187 + action = target.style.display === 'none' ? 'expand' : 'collapse';
  188 + if (options.recursive_collapser) {
  189 + collapsers = collapser.parentNode.getElementsByClassName('collapser');
  190 + _results = [];
  191 + for (_i = 0, _len = collapsers.length; _i < _len; _i++) {
  192 + collapser = collapsers[_i];
  193 + _results.push(this[action](collapser));
  194 + }
  195 + return _results;
  196 + } else {
  197 + return this[action](collapser);
  198 + }
  199 + };
  200 +
  201 + Collapser.collapseTarget = function(collapser) {
  202 + var target, targets;
  203 + targets = collapser.parentNode.getElementsByClassName('collapsible');
  204 + if (!targets.length) {
  205 + return;
  206 + }
  207 + return target = targets[0];
  208 + };
  209 +
  210 + return Collapser;
  211 +
  212 + })();
  213 + $ = jQuery;
  214 + JSONView = {
  215 + collapse: function(el) {
  216 + if (el.innerHTML === '-') {
  217 + return Collapser.collapse(el);
  218 + }
  219 + },
  220 + expand: function(el) {
  221 + if (el.innerHTML === '+') {
  222 + return Collapser.expand(el);
  223 + }
  224 + },
  225 + toggle: function(el) {
  226 + return Collapser.toggle(el);
  227 + }
  228 + };
  229 + return $.fn.JSONView = function() {
  230 + var args, defaultOptions, formatter, json, method, options, outputDoc;
  231 + args = arguments;
  232 + if (JSONView[args[0]] != null) {
  233 + method = args[0];
  234 + return this.each(function() {
  235 + var $this, level;
  236 + $this = $(this);
  237 + if (args[1] != null) {
  238 + level = args[1];
  239 + return $this.find(".jsonview .collapsible.level" + level).siblings('.collapser').each(function() {
  240 + return JSONView[method](this);
  241 + });
  242 + } else {
  243 + return $this.find('.jsonview > ul > li .collapsible').siblings('.collapser').each(function() {
  244 + return JSONView[method](this);
  245 + });
  246 + }
  247 + });
  248 + } else {
  249 + json = args[0];
  250 + options = args[1] || {};
  251 + defaultOptions = {
  252 + collapsed: false,
  253 + nl2br: false,
  254 + recursive_collapser: false,
  255 + escape: true
  256 + };
  257 + options = $.extend(defaultOptions, options);
  258 + formatter = new JSONFormatter({
  259 + nl2br: options.nl2br,
  260 + escape: options.escape
  261 + });
  262 + if (Object.prototype.toString.call(json) === '[object String]') {
  263 + json = JSON.parse(json);
  264 + }
  265 + outputDoc = formatter.jsonToHTML(json);
  266 + return this.each(function() {
  267 + var $this, item, items, _i, _len, _results;
  268 + $this = $(this);
  269 + $this.html(outputDoc);
  270 + items = $this[0].getElementsByClassName('collapsible');
  271 + _results = [];
  272 + for (_i = 0, _len = items.length; _i < _len; _i++) {
  273 + item = items[_i];
  274 + if (item.parentNode.nodeName === 'LI') {
  275 + _results.push(Collapser.bindEvent(item.parentNode, options));
  276 + } else {
  277 + _results.push(void 0);
  278 + }
  279 + }
  280 + return _results;
  281 + });
  282 + }
  283 + };
  284 +})(jQuery);
... ...
var/httpd/htdocs/js/thirdparty/alpaca/alpaca-full.min.js
... ... @@ -22736,19 +22736,19 @@ this[&quot;HandlebarsPrecompiled&quot;][&quot;web-edit&quot;][&quot;wizard&quot;] = Handlebars.template({&quot;1&quot;:f
22736 22736  
22737 22737 if (self.view.type !== "display")
22738 22738 {
22739   - if ($.fn.datetimepicker)
  22739 + if ($.fn.datepicker)
22740 22740 {
22741   - self.getControlEl().datetimepicker(self.options.picker);
  22741 + self.picker = self.getControlEl().datepicker(self.options.picker);
22742 22742  
22743   - self.picker = self.getControlEl().data("DateTimePicker");
  22743 + //self.picker = self.getControlEl().data("DateTimePicker");
22744 22744 if (self.picker && self.options.dateFormat)
22745 22745 {
22746   - self.picker.format(self.options.dateFormat);
22747   - }
22748   - if (self.picker)
22749   - {
22750   - self.options.dateFormat = self.picker.format();
  22746 + self.picker.datepicker( "option", "dateFormat", self.options.dateFormat );
22751 22747 }
  22748 + //if (self.picker)
  22749 + //{
  22750 + // self.options.dateFormat = self.picker.format();
  22751 + //}
22752 22752  
22753 22753 // with date-time picker, trigger change using plugin
22754 22754 self.getFieldEl().on("dp.change", function(e) {
... ... @@ -29572,7 +29572,7 @@ this[&quot;HandlebarsPrecompiled&quot;][&quot;web-edit&quot;][&quot;wizard&quot;] = Handlebars.template({&quot;1&quot;:f
29572 29572 "parent": "jqueryui-edit",
29573 29573 "type": "create",
29574 29574 "title": "Create view for jQuery UI",
29575   - "displayReadonly": false
  29575 + "displayReadonly": true
29576 29576 });
29577 29577  
29578 29578 Alpaca.registerView({
... ...
var/httpd/htdocs/skins/Agent/default/css/jquery.jsonview.css 0 → 100755
... ... @@ -0,0 +1,52 @@
  1 +@charset "UTF-8";
  2 +.jsonview {
  3 + font-family: monospace;
  4 + font-size: 1.1em;
  5 + white-space: pre-wrap; }
  6 + .jsonview .prop {
  7 + font-weight: bold; }
  8 + .jsonview .null {
  9 + color: red; }
  10 + .jsonview .bool {
  11 + color: blue; }
  12 + .jsonview .num {
  13 + color: blue; }
  14 + .jsonview .string {
  15 + color: green;
  16 + white-space: pre-wrap; }
  17 + .jsonview .string.multiline {
  18 + display: inline-block;
  19 + vertical-align: text-top; }
  20 + .jsonview .collapser {
  21 + position: absolute;
  22 + left: -1em;
  23 + cursor: pointer; }
  24 + .jsonview .collapsible {
  25 + transition: height 1.2s;
  26 + transition: width 1.2s; }
  27 + .jsonview .collapsible.collapsed {
  28 + height: .8em;
  29 + width: 1em;
  30 + display: inline-block;
  31 + overflow: hidden;
  32 + margin: 0; }
  33 + .jsonview .collapsible.collapsed:before {
  34 + content: "…";
  35 + width: 1em;
  36 + margin-left: .2em; }
  37 + .jsonview .collapser.collapsed {
  38 + transform: rotate(0deg); }
  39 + .jsonview .q {
  40 + display: inline-block;
  41 + width: 0px;
  42 + color: transparent; }
  43 + .jsonview li {
  44 + position: relative; }
  45 + .jsonview ul {
  46 + list-style: none;
  47 + margin: 0 0 0 2em;
  48 + padding: 0; }
  49 + .jsonview h1 {
  50 + font-size: 1.2em; }
  51 +
  52 +/*# sourceMappingURL=jquery.jsonview.css.map */
... ...