1 /**
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements.  See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership.  The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License.  You may obtain a copy of the License at
9 *
10 *     http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18 
19 package org.apache.hadoop.yarn.webapp.view;
20 
21 import static org.apache.commons.lang.StringEscapeUtils.escapeJavaScript;
22 import static org.apache.hadoop.yarn.util.StringHelper.djoin;
23 import static org.apache.hadoop.yarn.util.StringHelper.join;
24 import static org.apache.hadoop.yarn.util.StringHelper.split;
25 
26 import java.util.List;
27 
28 import org.apache.hadoop.classification.InterfaceAudience;
29 import org.apache.hadoop.yarn.webapp.hamlet.HamletSpec.HTML;
30 
31 import com.google.common.collect.Lists;
32 
33 @InterfaceAudience.LimitedPrivate({"YARN", "MapReduce"})
34 public class JQueryUI extends HtmlBlock {
35 
36   // UI params
37   public static final String ACCORDION = "ui.accordion";
38   public static final String ACCORDION_ID = ACCORDION +".id";
39   public static final String DATATABLES = "ui.dataTables";
40   public static final String DATATABLES_ID = DATATABLES +".id";
41   public static final String DATATABLES_SELECTOR = DATATABLES +".selector";
42   public static final String DIALOG = "ui.dialog";
43   public static final String DIALOG_ID = DIALOG +".id";
44   public static final String DIALOG_SELECTOR = DIALOG +".selector";
45   public static final String PROGRESSBAR = "ui.progressbar";
46   public static final String PROGRESSBAR_ID = PROGRESSBAR +".id";
47 
48   // common CSS classes
49   public static final String _PROGRESSBAR =
50       ".ui-progressbar.ui-widget.ui-widget-content.ui-corner-all";
51   public static final String C_PROGRESSBAR =
52       _PROGRESSBAR.replace('.', ' ').trim();
53   public static final String _PROGRESSBAR_VALUE =
54       ".ui-progressbar-value.ui-widget-header.ui-corner-left";
55   public static final String C_PROGRESSBAR_VALUE =
56       _PROGRESSBAR_VALUE.replace('.', ' ').trim();
57   public static final String _INFO_WRAP =
58       ".info-wrap.ui-widget-content.ui-corner-bottom";
59   public static final String _TH = ".ui-state-default";
60   public static final String C_TH = _TH.replace('.', ' ').trim();
61   public static final String C_TABLE = "table";
62   public static final String _INFO = ".info";
63   public static final String _ODD = ".odd";
64   public static final String _EVEN = ".even";
65 
66   @Override
render(Block html)67   protected void render(Block html) {
68     html.
69       link(root_url("static/jquery/themes-1.9.1/base/jquery-ui.css")).
70       link(root_url("static/dt-1.9.4/css/jui-dt.css")).
71       script(root_url("static/jquery/jquery-1.8.2.min.js")).
72       script(root_url("static/jquery/jquery-ui-1.9.1.custom.min.js")).
73       script(root_url("static/dt-1.9.4/js/jquery.dataTables.min.js")).
74       script(root_url("static/yarn.dt.plugins.js")).
75       style("#jsnotice { padding: 0.2em; text-align: center; }",
76             ".ui-progressbar { height: 1em; min-width: 5em }"); // required
77 
78     List<String> list = Lists.newArrayList();
79     initAccordions(list);
80     initDataTables(list);
81     initDialogs(list);
82     initProgressBars(list);
83 
84     if (!list.isEmpty()) {
85       html.
86         script().$type("text/javascript").
87           _("$(function() {")._(list.toArray())._("});")._();
88     }
89   }
90 
jsnotice(HTML html)91   public static void jsnotice(HTML html) {
92     html.
93       div("#jsnotice.ui-state-error").
94           _("This page will not function without javascript enabled."
95             + " Please enable javascript on your browser.")._();
96     html.
97       script().$type("text/javascript").
98         _("$('#jsnotice').hide();")._();
99   }
100 
initAccordions(List<String> list)101   protected void initAccordions(List<String> list) {
102     for (String id : split($(ACCORDION_ID))) {
103       if (Html.isValidId(id)) {
104         String init = $(initID(ACCORDION, id));
105         if (init.isEmpty()) {
106           init = "{autoHeight: false}";
107         }
108         list.add(join("  $('#", id, "').accordion(", init, ");"));
109       }
110     }
111   }
112 
initDataTables(List<String> list)113   protected void initDataTables(List<String> list) {
114     String defaultInit = "{bJQueryUI: true, sPaginationType: 'full_numbers'}";
115     String stateSaveInit = "bStateSave : true, " +
116         "\"fnStateSave\": function (oSettings, oData) { " +
117               " data = oData.aoSearchCols;"
118               + "for(i =0 ; i < data.length; i ++) {"
119               + "data[i].sSearch = \"\""
120               + "}"
121         + " sessionStorage.setItem( oSettings.sTableId, JSON.stringify(oData) ); }, " +
122           "\"fnStateLoad\": function (oSettings) { " +
123               "return JSON.parse( sessionStorage.getItem(oSettings.sTableId) );}, ";
124 
125     for (String id : split($(DATATABLES_ID))) {
126       if (Html.isValidId(id)) {
127         String init = $(initID(DATATABLES, id));
128         if (init.isEmpty()) {
129           init = defaultInit;
130         }
131         // for inserting stateSaveInit
132         int pos = init.indexOf('{') + 1;
133         init = new StringBuffer(init).insert(pos, stateSaveInit).toString();
134         list.add(join(id,"DataTable =  $('#", id, "').dataTable(", init,
135                       ").fnSetFilteringDelay(188);"));
136         String postInit = $(postInitID(DATATABLES, id));
137         if(!postInit.isEmpty()) {
138           list.add(postInit);
139         }
140       }
141     }
142     String selector = $(DATATABLES_SELECTOR);
143     if (!selector.isEmpty()) {
144       String init = $(initSelector(DATATABLES));
145       if (init.isEmpty()) {
146         init = defaultInit;
147       }
148       int pos = init.indexOf('{') + 1;
149       init = new StringBuffer(init).insert(pos, stateSaveInit).toString();
150       list.add(join("  $('", escapeJavaScript(selector), "').dataTable(", init,
151                ").fnSetFilteringDelay(288);"));
152 
153     }
154   }
155 
initDialogs(List<String> list)156   protected void initDialogs(List<String> list) {
157     String defaultInit = "{autoOpen: false, show: transfer, hide: explode}";
158     for (String id : split($(DIALOG_ID))) {
159       if (Html.isValidId(id)) {
160         String init = $(initID(DIALOG, id));
161         if (init.isEmpty()) {
162           init = defaultInit;
163         }
164         String opener = $(djoin(DIALOG, id, "opener"));
165         list.add(join("  $('#", id, "').dialog(", init, ");"));
166         if (!opener.isEmpty() && Html.isValidId(opener)) {
167           list.add(join("  $('#", opener, "').click(function() { ",
168                    "$('#", id, "').dialog('open'); return false; });"));
169         }
170       }
171     }
172     String selector = $(DIALOG_SELECTOR);
173     if (!selector.isEmpty()) {
174       String init = $(initSelector(DIALOG));
175       if (init.isEmpty()) {
176         init = defaultInit;
177       }
178       list.add(join("  $('", escapeJavaScript(selector),
179                "').click(function() { $(this).children('.dialog').dialog(",
180                init, "); return false; });"));
181     }
182   }
183 
initProgressBars(List<String> list)184   protected void initProgressBars(List<String> list) {
185     for (String id : split($(PROGRESSBAR_ID))) {
186       if (Html.isValidId(id)) {
187         String init = $(initID(PROGRESSBAR, id));
188         list.add(join("  $('#", id, "').progressbar(", init, ");"));
189       }
190     }
191   }
192 
initID(String name, String id)193   public static String initID(String name, String id) {
194     return djoin(name, id, "init");
195   }
196 
postInitID(String name, String id)197   public static String postInitID(String name, String id) {
198     return djoin(name, id, "postinit");
199   }
200 
initSelector(String name)201   public static String initSelector(String name) {
202     return djoin(name, "selector.init");
203   }
204 
tableInit()205   public static StringBuilder tableInit() {
206     return new StringBuilder("{bJQueryUI:true, ").
207         append("sPaginationType: 'full_numbers', iDisplayLength:20, ").
208         append("aLengthMenu:[20, 40, 60, 80, 100]");
209   }
210 }
211