4 * Youmin Ha <youmin.ha@samsung.com>
7 ( function ($, Globalize, window, undefined) {
10 libFileName : "tizen-web-ui-fw(.min)?.js",
13 rootDir: '/usr/lib/tizen-web-ui-fw',
22 loadScriptSync : function ( scriptPath, successCB, errorCB ) {
29 error: function ( jqXHR, textStatus, errorThrown ) {
31 errorCB( jqXHR, textStatus, errorThrown );
33 var ignoreStatusList = [ 404 ]; // 404: not found
34 if ( -1 == $.inArray( jqXHR.status, ignoreStatusList ) ) {
35 window.alert( 'Error while loading ' + scriptPath + '\n' + jqXHR.status + ':' + jqXHR.statusText );
37 console.log( 'Error while loading ' + scriptPath + '\n' + jqXHR.status + ':' + jqXHR.statusText );
43 getScaleFactor: function ( ) {
44 var factor = navigator.scale,
49 width = screen.width < screen.height ? screen.width : screen.height;
50 factor = width / defaultWidth;
52 // NOTE: some targets(e.g iPad) need to set scale equal or less than 1.0
56 console.log( "ScaleFactor: " + factor );
59 isMobileBrowser: function ( ) {
60 var mobileIdx = window.navigator.appVersion.indexOf("Mobile"),
61 isMobile = -1 < mobileIdx;
67 cacheBust: ( document.location.href.match( /debug=true/ ) ) ?
68 '?cacheBust=' + ( new Date( ) ).getTime( ) :
70 addElementToHead : function ( elem ) {
71 var head = document.getElementsByTagName( 'head' )[0];
73 $( head ).prepend( elem );
76 makeLink : function ( href ) {
77 var cssLink = document.createElement( 'link' );
78 cssLink.setAttribute( 'rel', 'stylesheet' );
79 cssLink.setAttribute( 'href', href );
80 cssLink.setAttribute( 'name', 'tizen-theme' );
83 load: function ( path ) {
84 var head = document.getElementsByTagName( 'head' )[0],
85 cssLinks = head.getElementsByTagName( 'link' ),
88 // Find css link element
89 for ( idx = 0; idx < cssLinks.length; idx++ ) {
90 if( cssLinks[idx].getAttribute( 'name' ) == "tizen-theme" ) {
95 if ( l ) { // Found the link element!
96 l.setAttribute( 'href', path );
98 this.addElementToHead( this.makeLink( path ) );
103 getParams: function ( ) {
104 /* Get data-* params from <script> tag, and set tizen.frameworkData.* values
105 * Returns true if proper <script> tag is found, or false if not.
107 // Find current <script> tag element
108 var scriptElems = document.getElementsByTagName( 'script' ),
110 foundScriptTag = false,
117 function getTizenTheme( ) {
118 var t = navigator.theme ? navigator.theme.split( ':' )[0] : null;
120 t = t.replace('-hd', '');
121 if( ! t.match( /^tizen-/ ) ) {
128 for ( idx in scriptElems ) {
129 elem = scriptElems[idx];
130 src = elem.src ? elem.getAttribute( 'src' ) : undefined;
131 if (src && src.match( this.libFileName )) {
132 // Set framework data, only when they are given.
133 tokens = src.split(/[\/\\]/);
135 this.frameworkData.rootDir = elem.getAttribute( 'data-framework-root' )
136 || tokens.slice( 0, tokens.length + version_idx ).join( '/' )
137 || this.frameworkData.rootDir;
138 this.frameworkData.version = elem.getAttribute( 'data-framework-version' )
139 || tokens[ tokens.length + version_idx ]
140 || this.frameworkData.version;
141 this.frameworkData.theme = elem.getAttribute( 'data-framework-theme' )
143 || this.frameworkData.theme;
144 this.frameworkData.viewportScale = "true" === elem.getAttribute( 'data-framework-viewport-scale' ) ? true : this.frameworkData.viewportScale;
145 this.frameworkData.minified = src.search(/\.min\.js$/) > -1 ? true : false;
146 foundScriptTag = true;
150 return foundScriptTag;
153 loadTheme: function ( theme ) {
154 var themePath, cssPath, jsPath;
157 theme = tizen.frameworkData.theme;
160 tizen.frameworkData.rootDir,
161 tizen.frameworkData.version,
166 jsPath = [themePath, 'theme.js'].join( '/' );
168 if( tizen.frameworkData.minified ) {
169 cssPath = [themePath, 'tizen-web-ui-fw-theme.min.css'].join( '/' );
171 cssPath = [themePath, 'tizen-web-ui-fw-theme.css'].join( '/' );
173 tizen.css.load( cssPath );
174 tizen.util.loadScriptSync( jsPath );
177 /** Load Globalize culture file, and set default culture.
178 * @param[in] language (optional) Language code. ex) en-US, en, ko-KR, ko
179 * If language is not given, read language from html 'lang' attribute,
180 * or from system setting.
181 * @param[in] cultureDic (optional) Dictionary having language code->
183 loadGlobalizeCulture: function ( language, cultureDic ) {
189 function getLang ( language ) {
191 || $( 'html' ).attr( 'lang' )
192 || window.navigator.language.split( '.' )[0] // Webkit, Safari + workaround for Tizen
193 || window.navigator.userLanguage // IE
196 countryCodeIdx = lang.lastIndexOf('-'),
197 ignoreCodes = ['Cyrl', 'Latn', 'Mong']; // Not country code!
198 if ( countryCodeIdx != -1 ) { // Found country code!
199 countryCode = lang.substr( countryCodeIdx + 1 );
200 if ( ignoreCodes.join( '-' ).indexOf( countryCode ) < 0 ) {
201 // countryCode is not found from ignoreCodes.
202 // Make countryCode to uppercase.
203 lang = [ lang.substr( 0, countryCodeIdx ), countryCode.toUpperCase( ) ].join( '-' );
206 // NOTE: 'en' to 'en-US', because globalize has no 'en' culture file.
207 lang = lang == 'en' ? 'en-US' : lang;
211 function getNeutralLang ( lang ) {
212 var neutralLangIdx = lang.lastIndexOf( '-' ),
214 if ( neutralLangIdx != -1 ) {
215 neutralLang = lang.substr( 0, neutralLangIdx );
220 function getCultureFilePath ( lang, cFDic ) {
221 var cFPath = null; // error value
223 if ( "string" != typeof lang ) {
227 if ( cFDic[lang] ) cFPath = cFDic[lang];
229 // Default Globalize culture file path
231 self.frameworkData.rootDir,
232 self.frameworkData.version,
235 ['globalize.culture.', lang, '.js'].join( '' ),
241 function printLoadError( cFPath, jqXHR ) {
242 console.log( "Error " + jqXHR.status + ": " + jqXHR.statusText );
243 console.log( "::Culture file (" + cFPath + ") is failed to load.");
246 function loadCultureFile ( cFPath, errCB ) {
247 function _successCB ( ) {
248 console.log( "Culture file (" + cFPath + ") is loaded successfully.");
250 function _errCB ( jqXHR, textStatus, err ) {
252 errCB( jqXHR, textStatus, err );
255 printLoadError( cFPath, jqXHR );
259 if( ! cFPath ) { // Invalid cFPath -> Regard it as '404 Not Found' error.
262 statusText: "Not Found"
264 _errCB( mockJSXHR, null, null );
277 lang = getLang( language );
278 cFPath = getCultureFilePath( lang, cultureDic );
279 loadCultureFile( cFPath,
280 function ( jqXHR, textStatus, err ) {
281 if( jqXHR.status == 404 ) {
282 // If culture file is not found, try once more with neutral lang.
283 var nLang = getNeutralLang( lang ),
284 cFPath = getCultureFilePath( nLang, cultureDic );
285 loadCultureFile( cFPath, null );
287 printLoadError( cFPath, jqXHR );
293 setGlobalize: function ( ) {
294 var lang = this.loadGlobalizeCulture( );
297 // NOTE: It is not needed to set with neutral lang.
298 // Globalize automatically deals with it.
299 Globalize.culture( lang );
302 * Load custom globalize culture file
303 * Find current system language, and load appropriate culture file from given colture file list.
305 * @param[in] cultureDic collection of 'language':'culture file path' key-val pair.
308 * "en" : "culture/en.js",
309 * "fr" : "culture/fr.js",
310 * "ko-KR" : "culture/ko-KR.js"
312 * loadCultomGlobalizeCulture( myCultures );
315 * -------------------------------
316 * Globalize.addCultureInfo( "fr", {
318 * "hello" : "bonjour",
319 * "translate" : "traduire"
322 * -------------------------------
324 loadCustomGlobalizeCulture: function ( cultureDic ) {
325 tizen.loadGlobalizeCulture( null, cultureDic );
328 /** Set viewport meta tag for mobile devices.
330 * @param[in] viewportWidth Viewport width. 'device-dpi' is also allowed.
331 * @param[in] useAutoScale If true, cculate & use scale factor. otherwise, scale factor is 1.
332 * @param[in] useDeviceDpi If true, add 'target-densityDpi=device-dpi' to viewport meta content.
334 setViewport: function ( viewportWidth, useAutoScale, useDeviceDpi ) {
342 screenWidth = screen.width;
344 // Do nothing if viewport setting code is already in the code.
345 $( "meta[name=viewport]" ).each( function ( ) {
346 console.log( "User set viewport... framework viewport will not be applied." );
351 content = $( meta ).prop( "content" );
352 if ( content.indexOf( "device-width" ) > 0
353 && content.indexOf( "device-dpi" ) > 0 ) {
354 ratio = screenWidth > standardWidth ? ( screenWidth/standardWidth) : 1;
355 $.vmouse.moveDistanceThreshold = threshold * ratio;
356 $.vmouse.clickDistanceThreshold = threshold * ratio;
358 return; // Ignore viewport setting, when viewport is already set.
362 meta = document.createElement( "meta" );
364 scale = useAutoScale ? this.util.getScaleFactor( ) : scale;
365 meta.name = "viewport";
366 meta.content = "width=" + viewportWidth + ", initial-scale=" + scale + ", maximum-scale=" + scale + ", user-scalable=0";
367 if ( useDeviceDpi ) {
368 meta.content += ", target-densityDpi=device-dpi";
370 console.log( meta.content );
371 head = document.getElementsByTagName( 'head' ).item( 0 );
372 head.insertBefore( meta, head.firstChild );
374 // TODO : change threshold when scaleFactor is changed. Reference line 354-356
378 /** Read body's font-size, scale it, and reset it.
379 * param[in] desired font-size / base font-size.
381 scaleBaseFontSize: function ( themeDefaultFontSize, ratio ) {
382 var scaledFontSize = Math.round( themeDefaultFontSize * ratio );
384 $( 'html.ui-mobile' ).css( { 'font-size': scaledFontSize + "px" } );
385 console.log('html:font size is set to ' + scaledFontSize );
386 $( document ).ready( function ( ) {
387 $( '.ui-mobile').children( 'body' ).css( { 'font-size': scaledFontSize + "px" } );
391 setScaling: function ( ) {
392 var baseWidth = 720, // Winset GUI Guide is 720 HD.
394 themeDefaultFontSize;
396 themeDefaultFontSize = this.frameworkData.defaultFontSize;
398 $( 'body' ).attr( 'data-tizen-theme-default-font-size', themeDefaultFontSize );
400 if ( this.frameworkData.viewportScale ) {
401 // Use viewport scaling with base font-size
402 // NOTE: No font-size setting is needed.
403 this.setViewport( baseWidth, true, true );
405 // Fixed viewport scale(=1.0) with scaled font size
406 this.setViewport( "device-width", false, undefined );
407 this.scaleBaseFontSize( themeDefaultFontSize, parseFloat( standardWidth / baseWidth ) );
412 function export2TizenNS ( $, tizen ) {
413 if ( undefined == typeof $.tizen ) {
417 $.tizen.frameworkData = tizen.frameworkData;
418 $.tizen.loadCustomGlobalizeCulture = tizen.loadCustomGlobalizeCulture;
419 $.tizen.loadTheme = tizen.loadTheme;
421 $.tizen.__tizen__ = tizen; // for unit-test
424 export2TizenNS( $, tizen );
428 tizen.setScaling( ); // Run after loadTheme(), for the default font size.
429 tizen.setGlobalize( );
431 // Turn off JQM's auto initialization option.
432 // NOTE: This job must be done before domready.
433 $.mobile.autoInitializePage = false;
435 $(document).ready( function ( ) {
436 $.mobile.initializePage( );
439 } ( jQuery, window.Globalize, window ) );