1 From 372d8508f064dc0a28b44707baf4c0832e75e2ad Mon Sep 17 00:00:00 2001
2 From: Minkyu Kang <mk7.kang@samsung.com>
3 Date: Thu, 16 Feb 2012 18:00:47 +0900
4 Subject: [PATCH 1/2] JQM: Change header/footer code to meet Tizen GUI
7 .../js/jquery.mobile.fixHeaderFooter.js | 364 ++++++++++++++++----
8 1 files changed, 299 insertions(+), 65 deletions(-)
10 diff --git a/libs/js/jquery-mobile-1.0.1pre/js/jquery.mobile.fixHeaderFooter.js b/libs/js/jquery-mobile-1.0.1pre/js/jquery.mobile.fixHeaderFooter.js
11 index 3bb5613..2aa10b5 100644
12 --- a/libs/js/jquery-mobile-1.0.1pre/js/jquery.mobile.fixHeaderFooter.js
13 +++ b/libs/js/jquery-mobile-1.0.1pre/js/jquery.mobile.fixHeaderFooter.js
16 -* "fixHeaderFooter" plugin - on-demand positioning for headers,footers
18 +* Header/Footer can be created using the
19 +* data-role="header", data-role="footer" attribute to an element.
21 +* Every page in SLP theme have Header&Footer and default footer contains back button
22 +* Framework automatically generate footer even though web developer does not define footer
23 +* For more detail footer usage, refer Page(page.section.js) guideline
26 +* data-position : default value is fixed, automatically generated footer has fixed position,
27 + in header, web dev. defines header fix or not.
31 +* HTML markup for creating header :
32 +* <div data-role="header" data-position="fixed">
36 +* HTML markup for creating 1 button title ( button is available 1~3 )
37 +* <div data-role="header" data-position="fixed">
39 +* <h1>Title Area</h1>
42 +* HTML markup for creating 2 button and groupControl title ( Groupcontrol is available 2~4 )
43 +* <div data-role="header" data-position="fixed">
45 +* <h1>Title Extend 2 Button </h1>
47 +* <div data-role="fieldcontain">
48 +* <fieldset data-role="controlgroup" data-type="horizontal">
49 +* <input type="radio" name="radio-view-8" data-icon="segment-titlestyle-segonly" id="segment1" value="on" checked="checked" />
50 +* <label for="segment1">All</label>
51 +* <input type="radio" name="radio-view-8" data-icon="segment-titlestyle-segonly" id="segment2" value="off" />
52 +* <label for="segment2">Call</label>
57 +* HTML markup for creating footer
58 +* <div data-role="footer" data-position="fixed">
62 (function( $, undefined ) {
63 @@ -50,7 +91,8 @@ $.mobile.fixedToolbars = (function() {
64 touchStopEvent = supportTouch ? "touchend" : "mouseup",
66 scrollTriggered = false,
67 - touchToggleEnabled = true;
68 + touchToggleEnabled = true,
69 + defaultFooterHeight = 114;
71 function showEventCallback( event ) {
72 // An event that affects the dimensions of the visual viewport has
73 @@ -62,12 +104,36 @@ $.mobile.fixedToolbars = (function() {
75 // If we are in autoHideMode, we don't do anything because we know the scroll
76 // callbacks for the plugin will fire off a show when the scrolling has stopped.
79 + /* resize test : Jinhyuk */
81 + if( $( document ).find( ".ui-page-active" ).length )
82 + footer_filter = $( document ).find( ".ui-page-active" ).find( ":jqmData(role='footer')" );
84 + footer_filter = $( document ).find( ":jqmData(role='footer')" ).eq( 0 );
86 + var footerNavbar = footer_filter.find(".ui-navbar");
88 + if(footer_filter.height()< defaultFooterHeight)
89 + footer_filter.css("height", defaultFooterHeight);
91 + .css("top",window.innerHeight - footer_filter.height())
93 + if(footerNavbar.jqmData("style") == "toolbar"){
95 + .css("width", window.innerWidth - footerNavbar.siblings(".ui-btn").width());
97 + /* resize test : Jinhyuk */
99 if ( !autoHideMode && currentstate === "overlay" ) {
101 - $.mobile.fixedToolbars.hide( true );
102 + /* Fixed header modify for theme-s : Jinhyuk */
103 + if(!($( event.target).find( ":jqmData(role='header')" ).is(":jqmData(position='fixed')")&&
104 + $( event.target).find( ":jqmData(role='header')" ).is(".ui-bar-s")))
105 + $.mobile.fixedToolbars.hide( true );
108 - $.mobile.fixedToolbars.startShowTimer();
109 + $.mobile.fixedToolbars.startShowTimer();
113 @@ -107,31 +173,34 @@ $.mobile.fixedToolbars = (function() {
115 ( ( $document.scrollTop() === 0 ) ? $window : $document )
116 .bind( "scrollstart", function( event ) {
118 - scrollTriggered = true;
120 - if ( stateBefore === null ) {
121 - stateBefore = currentstate;
124 - // We only enter autoHideMode if the headers/footers are in
125 - // an overlay state or the show timer was started. If the
126 - // show timer is set, clear it so the headers/footers don't
127 - // show up until after we're done scrolling.
128 - var isOverlayState = stateBefore == "overlay";
130 - autoHideMode = isOverlayState || !!delayTimer;
132 - if ( autoHideMode ) {
133 - $.mobile.fixedToolbars.clearShowTimer();
135 - if ( isOverlayState ) {
136 - $.mobile.fixedToolbars.hide( true );
137 + /* Fixed header modify for theme-s : Jinhyuk */
138 + if(!$( event.target).find( ":jqmData(role='header')" ).is(":jqmData(position='fixed')"))
140 + scrollTriggered = true;
142 + if ( stateBefore === null ) {
143 + stateBefore = currentstate;
146 + // We only enter autoHideMode if the headers/footers are in
147 + // an overlay state or the show timer was started. If the
148 + // show timer is set, clear it so the headers/footers don't
149 + // show up until after we're done scrolling.
150 + var isOverlayState = stateBefore == "overlay";
152 + autoHideMode = isOverlayState || !!delayTimer;
154 + if ( autoHideMode ) {
155 + $.mobile.fixedToolbars.clearShowTimer();
157 + if ( isOverlayState ) {
158 + $.mobile.fixedToolbars.hide( true );
163 - .bind( "scrollstop", function( event ) {
165 + .bind( "scrollstop", function( event ) {
166 if ( $( event.target ).closest( ignoreTargets ).length ) {
169 @@ -145,40 +214,201 @@ $.mobile.fixedToolbars = (function() {
173 - $window.bind( "resize updatelayout", showEventCallback );
174 + $window.bind( "resize", showEventCallback );
177 // 1. Before page is shown, check for duplicate footer
178 // 2. After page is shown, append footer to new page
180 - .live( "pagebeforeshow", function( event, ui ) {
181 + $( ".ui-page" ) /* Fixed header modify for theme-s : Jinhyuk */
182 + .live( "pagebeforeshow", function( event, ui ) {
183 + var s_theme_header = $( event.target ).find( ":jqmData(role='header')" );
184 + var s_theme_fieldcontain = s_theme_header.find( ":jqmData(role='fieldcontain')" );
185 + var s_theme_content = $( event.target ).find( ".ui-content" );
186 + var title_style = "normal";
187 + if( s_theme_fieldcontain.length != 0 )
188 + title_style = "extended";
190 + if( s_theme_header.jqmData("position") == "fixed" || s_theme_header.css("position") == "fixed" ){
192 + .css( "position", "fixed" )
193 + .css( "top", "0px" );
194 + if( s_theme_header.children().is(".ui-navbar") ) {
195 + s_theme_header.addClass( "ui-title-controlbar-height" );
196 + $( event.target ).find( ".ui-content" ).addClass( "ui-title-content-controlbar-height" );
198 + $( event.target ).find( ".ui-content" ).addClass( "ui-title-content-" + title_style + "-height" );
201 + if( s_theme_header.children().is(".ui-option-header") ){
202 + s_theme_content.removeClass( "ui-title-content-" + title_style + "-height" );
203 + if( s_theme_header.children().is(".input-search-bar") ){
204 + s_theme_content.addClass( "ui-title-content-optionheader-search" );
206 + if( $.tizen.optionheader.prototype.options.collapseOnInit == true )
207 + s_theme_content.addClass( "ui-title-content-option-header-collapsed-1line-height" );
209 + s_theme_content.addClass( "ui-title-content-option-header-expanded-1line-height" );
211 + } else if( s_theme_header.find("input").jqmData("type") == "search" ){ /* In case searchbar in header : Jinhyuk */
213 + .removeClass( "ui-title-content-" + title_style + "-height" )
214 + .addClass( "ui-title-content-search" );
217 + if(s_theme_header.children().is("a") || s_theme_header.children().find(".ui-radio").length != 0){
218 + if(title_style == "normal"){
219 + if(s_theme_header.children("a").length == 1 || s_theme_header.children("a").length == 2){}
220 + else if( s_theme_header.children("a").length == 3 ){
221 + s_theme_header.find( "a" ).eq( 1 )
222 + .removeClass( "ui-btn-right" )
223 + .addClass( "ui-title-normal-3btn" );
224 + s_theme_header.find( "a" ).eq( 2 )
225 + .addClass( "ui-btn-right" );
226 + } else {/* Need to implement new layout */}
228 + var group_length = s_theme_fieldcontain.find( ".ui-radio" ).length;
230 + s_theme_header.addClass( "ui-title-extended-height" );
231 + s_theme_fieldcontain.find( ".ui-controlgroup" ).addClass( "ui-title-extended-controlgroup" );
232 + s_theme_fieldcontain.find( ".ui-controlgroup" ).addClass( "ui-extended-controlgroup" );
233 + s_theme_fieldcontain.addClass( "ui-title-extended-segment-style" );
235 + if( group_length == 2 || group_length == 3 || group_length == 4 )
236 + s_theme_fieldcontain.addClass( "ui-title-extended-controlgroup-" + group_length + "btn" );
237 + else { /* Need to implement new layout */}
239 + s_theme_content.addClass( "ui-title-content-" + title_style + "-height" );
242 + /* resize footer : Jinhyuk */
243 + var footer_filter = $(document).find(":jqmData(role='footer')");
244 + if( footer_filter.find(".ui-navbar").is(".ui-controlbar-s") ){
246 + .css( "top", window.innerHeight - footer_filter.height() )
249 + /* resize footer : Jinhyuk */
250 + if( footer_filter.children().find(".ui-radio").length != 0 ){
251 + var footerGroup = footer_filter.find( ":jqmData(role='fieldcontain')" );
252 + var groupLength = footerGroup.find( ".ui-radio" ).length;
253 + footerGroup.find( ".ui-controlgroup" )
254 + .addClass( "ui-extended-controlgroup" )
255 + .addClass( "ui-footer-extended-controlgroup" )
256 + .css( "display", "inline" );
257 + /* Groupcontrol cannot initialize inline property at first page */
258 + footerGroup.addClass( "ui-title-extended-controlgroup-" + groupLength + "btn" );
260 + footerButton = footer_filter.children( "a" );
261 + footerButton.each(function(i){
262 + if( footerButton.eq(i).is(".ui-btn") && !footerButton.eq(i).is(".ui-btn-back") ){
263 + footerButton.eq( i )
264 + .removeClass( "ui-btn-left" )
265 + .addClass( "ui-btn-footer-right" );
270 var page = $( event.target ),
271 - footer = page.find( ":jqmData(role='footer')" ),
272 - id = footer.data( "id" ),
273 - prevPage = ui.prevPage,
274 - prevFooter = prevPage && prevPage.find( ":jqmData(role='footer')" ),
275 - prevFooterMatches = prevFooter.length && prevFooter.jqmData( "id" ) === id;
276 + footer = page.find( ":jqmData(role='footer')" ),
277 + id = footer.data( "id" ),
278 + prevPage = ui.prevPage,
279 + prevFooter = prevPage && prevPage.find( ":jqmData(role='footer')" ),
280 + prevFooterMatches = prevFooter.length && prevFooter.jqmData( "id" ) === id;
282 if ( id && prevFooterMatches ) {
283 stickyFooter = footer;
284 - setTop( stickyFooter.removeClass( "fade in out" ).appendTo( $.mobile.pageContainer ) );
285 + stickyFooter.removeClass( "fade in out" ).appendTo( $.mobile.pageContainer );
287 + .css("position", "fixed")
288 + .css("top", $(".ui-page").find(":jqmData(role='footer')").eq(0).css("top"));
291 + if( footer.is(".ui-footer-fixed") ){
292 + footer.css( "top", window.innerHeight - footer.height() );
295 + /* Increase Content size with dummy <div> because of footer height */
296 + if( footer.length != 0 && $( event.target ).find(".dummy-div").length == 0 ){
297 + $( event.target ).find( ":jqmData(role='content')" ).append( '<div class="dummy-div"></div>' );
299 + .css( "width", footer.width() )
300 + .css( "height", footer.height() );
301 + if( $(".dummy-div").height() < defaultFooterHeight )
302 + $( ".dummy-div" ).css( "height", defaultFooterHeight );
305 + /* Header position fix(remove transition) : Jinhyuk */
306 + var next_id = $( event.target ).attr( "id" );
307 + $( "#"+next_id ).find( ":jqmData(role='header')" ).removeClass( "fade in out" ).appendTo( $.mobile.pageContainer );
310 .live( "pageshow", function( event, ui ) {
311 + /* Fixed header modify for theme-s : Jinhyuk */
312 + var s_theme_header = $( event.target ).find( ":jqmData(role='header')" );
313 + if( s_theme_header.is(".ui-header-fixed") && s_theme_header.is(".ui-bar-s") ){
314 + $( event.target ).find( ":jqmData(role='header')" )
315 + .css( "position", "fixed" )
316 + .css("top", "0px");
317 + (( $( document ).scrollTop() === 0 ) ? $( window ) : $( document ) )
318 + .unbind( "scrollstart")
319 + .unbind( "silentscroll")
320 + .unbind( "scrollstop");
323 var $this = $( this );
325 if ( stickyFooter && stickyFooter.length ) {
327 setTimeout(function() {
328 setTop( stickyFooter.appendTo( $this ).addClass( "fade" ) );
333 - $.mobile.fixedToolbars.show( true, this );
334 + $.mobile.fixedToolbars.show( true, this );
336 + /* Header position fix(remove transition) : Jinhyuk */
337 + $("body").children(":jqmData(role='header')").insertBefore($(event.target).find(":jqmData(role='content')").eq(0));
340 + .live( "vclick", function( event, ui ) {
342 + var previous_index = $(".ui-page-active").find(":jqmData(role='footer')" ).find(".ui-state-persist").parents("li").index();
343 + var active_index = $(event.target).parents("li").index();
344 + var navbar_filter = $(".ui-page-active").find(":jqmData(role='footer')" ).find(":jqmData(role='navbar')");
345 + var element_count = navbar_filter.find('li').length;
346 + var style = navbar_filter.jqmData( "style" );
347 + var list_width = $(".ui-page-active").find('.ui-navbar').width()/element_count;
349 + var next_link = $(event.target).parents("a").attr("href");
352 + $(".ui-page-active").addClass("ui-btn-hide-style");
355 + if(navbar_filter.find(".ui-btn-animation").length == 0 && style != "toolbar"){
356 + $('<div class="ani-focus"></div>').appendTo(navbar_filter.children());
358 + .addClass("ui-btn-animation")
359 + .removeClass("ui-btn-ani-verticalendposition")
360 + .removeClass("ui-btn-ani-endposition");
364 + .css("width", navbar_filter.width()/element_count )
365 + .css("height",navbar_filter.css("height"))
366 + .css("left", previous_index * list_width);
369 + $(".ui-btn-ani-startposition").css("-webkit-transform","translateX("+previous_index *list_width+")");
370 + $(".ani-focus").addClass("ui-btn-ani-startposition");
372 + var t=setTimeout("",10);
373 + $(".ui-btn-ani-endposition").css("-webkit-transform","translateX("+active_index *list_width+")");
374 + $(".ani-focus").removeClass("ui-btn-ani-startposition");
375 + $(".ani-focus").addClass("ui-btn-ani-endposition");
380 // When a collapsiable is hidden or shown we need to trigger the fixed toolbar to reposition itself (#1635)
381 $( ".ui-collapsible-contain" ).live( "collapse expand", showEventCallback );
382 @@ -215,30 +445,34 @@ $.mobile.fixedToolbars = (function() {
385 function setTop( el ) {
386 - var fromTop = $(window).scrollTop(),
387 - thisTop = getOffsetTop( el[ 0 ] ), // el.offset().top returns the wrong value on iPad iOS 3.2.1, call our workaround instead.
388 - thisCSStop = el.css( "top" ) == "auto" ? 0 : parseFloat(el.css( "top" )),
389 - screenHeight = window.innerHeight,
390 - thisHeight = el.outerHeight(),
391 - useRelative = el.parents( ".ui-page:not(.ui-page-fullscreen)" ).length,
394 - if ( el.is( ".ui-header-fixed" ) ) {
396 - relval = fromTop - thisTop + thisCSStop;
398 - if ( relval < thisTop ) {
400 + if(!(el.parents(".ui-page").find( ":jqmData(role='header')" ).is(".ui-header-fixed")&&
401 + el.parents(".ui-page").find( ":jqmData(role='header')" ).is(".ui-bar-s"))){
402 + var fromTop = $(window).scrollTop(),
403 + thisTop = getOffsetTop( el[ 0 ] ), // el.offset().top returns the wrong value on iPad iOS 3.2.1, call our workaround instead.
404 + thisCSStop = el.css( "top" ) == "auto" ? 0 : parseFloat(el.css( "top" )),
405 + screenHeight = window.innerHeight,
406 + thisHeight = el.outerHeight(),
407 + useRelative = el.parents( ".ui-page:not(.ui-page-fullscreen)" ).length,
410 + if ( el.is( ".ui-header-fixed" ) ) {
412 + relval = fromTop - thisTop + thisCSStop;
414 + if ( relval < thisTop ) {
418 + return el.css( "top", useRelative ? relval : fromTop );
420 + // relval = -1 * (thisTop - (fromTop + screenHeight) + thisCSStop + thisHeight);
421 + // if ( relval > thisTop ) { relval = 0; }
422 + relval = fromTop + screenHeight - thisHeight - (thisTop - thisCSStop );
424 + return el.css( "top", useRelative ? relval : fromTop + screenHeight - thisHeight );
427 - return el.css( "top", useRelative ? relval : fromTop );
429 - // relval = -1 * (thisTop - (fromTop + screenHeight) + thisCSStop + thisHeight);
430 - // if ( relval > thisTop ) { relval = 0; }
431 - relval = fromTop + screenHeight - thisHeight - (thisTop - thisCSStop );
433 - return el.css( "top", useRelative ? relval : fromTop + screenHeight - thisHeight );
439 @@ -264,16 +498,16 @@ $.mobile.fixedToolbars = (function() {
440 thisHeight = el.outerHeight(),
441 alreadyVisible = ( el.is( ".ui-header-fixed" ) && fromTop <= thisTop + thisHeight ) ||
442 ( el.is( ".ui-footer-fixed" ) && thisTop <= fromTop + screenHeight );
444 +// block blink code in title : Jinhyuk
446 - el.addClass( "ui-fixed-overlay" ).removeClass( "ui-fixed-inline" );
447 +// el.addClass( "ui-fixed-overlay" ).removeClass( "ui-fixed-inline" );
449 - if ( !alreadyVisible && !immediately ) {
450 +/* if ( !alreadyVisible && !immediately ) {
451 el.animationComplete(function() {
452 el.removeClass( "in" );