Главная > CSS, JavaScript, Программирование > jQuery UI ThemeRoller Developer Tool

jQuery UI ThemeRoller Developer Tool

Еще одна небольшая статья на сегодня... Я тут ради нее даже обновил шкурку wordpress'a и jQueryUI

Сегодня днем, когда качал новую тему для jQueryUI, заметил каку-то рекламку, меня она немного насторожила, я присмотрелся, и не зря мне предложили enlarge your penis size naturally only for 20$. Там было написано "Bring ThemeRoller into any page: Get the ThemeRoller Firefox Bookmarklet!", и что вы себе думаете это работает всего за 20$ я увеличил свой член на 4 сантиметра, но только в FireFox'e. После добавления в закладки и запуска, эта штука создает небольшой поп-апчик, в котором можно менять настройки текущей темы или даже саму тему.

Результат можно посмотреть прямо на этой странице, добавьте этот линк в закладки и запустите, а вот календарик для просмотра эффекта

Но меня как всегда волнует вопрос "как это работает?". Начинаем препарировать:



(function() {
    if (!/Firefox[\/\s](\d+\.\d+)/.test(navigator.userAgent)) {
        alert('Sorry, due to security restrictions, this tool only works in Firefox');
        return false;
    }
    ;
    if (window.jquitr) {
        jquitr.addThemeRoller();
    } else {
        jquitr = {};
        jquitr.s = document.createElement('script');
        jquitr.s.src = 'http://jqueryui.com/themeroller/developertool/developertool.js.php';
        document.getElementsByTagName('head')[0].appendChild(jquitr.s);
    }
})();


Сам линк простой как три копейки: если фаерфокс то создает на странице новый скрипт. Какой?



if(!window.jquitr){jquitr = {};}
jquitr.trString = '';
jquitr.s1 =document.createElement('script');
jquitr.s2 =document.createElement('script');
jquitr.s1.setAttribute('src','http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js');
jquitr.s2.setAttribute('src','http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.1/jquery-ui.min.js');
document.getElementsByTagName('head')[0].appendChild(jquitr.s1);
document.getElementsByTagName('head')[0].appendChild(jquitr.s2);
//once jq and ui are loaded...
jquitr.s1.onload = function(){
	jquitr.s2.onload = function(){
		jquitr.addThemeRoller();
	}
}
//add dev tool to page
jquitr.addThemeRoller = function(){
	if(jQuery('#inline_themeroller').size() > 0){
		jQuery('#inline_themeroller').fadeIn();
	}
	else {
		jQuery('<div id="inline_themeroller" style="display: none; position: fixed; background: #111; top: 25px; right: 25px; padding: 22px 0 15px 4px;width: 245px;height:400px; -webkit-border-radius: 6px; -moz-border-radius: 6px; z-index: 9999999;">'+
			'<a href="#" class="closeTR" style="font-family: Verdana, sans-serif; font-size: 10px; display: block; position: absolute; right: 0; top: 2px; text-align: right; background: url(http://jqueryui.com/themeroller/developertool/icon_bookmarklet_close.gif) 0 2px no-repeat; width: 16px;height: 16px; color: #fff; text-decoration: none;" title="Close ThemeRoller"></a>'+
			'<iframe name="trApp" src="http://jqueryui.com/themeroller/developertool/appinterface.php" style="background: transparent; overflow: auto; width: 240px;height:100%;border: 0;" frameborder="0" ></iframe>'+
			'</div>')
			.appendTo('body')
			.draggable({
				start: function(){
					jQuery('<div id="div_cover" />').appendTo('#inline_themeroller').css({width: jQuery(this).width(), height: jQuery(this).height(), position: 'absolute', top: 0, left:0});
				},
				stop: function(){
					jQuery('#div_cover').remove();
				},
				opacity: 0.6,
				cursor: 'move'
			})
			.resizable({
				start: function(){
					jQuery(this).find('iframe').hide();
				},
				stop: function(){
					jQuery(this).find('iframe').show();
				},
				handles: 's'
			})
			.find('a.closeTR').click(function(){
				jquitr.closeThemeRoller();
			})
			.end()
			.find('.ui-resizable-s').css({
				background: 'url(http://jqueryui.com/themeroller/developertool/icon_bookmarklet_dragger.gif) 50% 50% no-repeat',
				border: 'none',
				height: '14px',
				dipslay: 'block',
				cursor: 'resize-s',
				bottom: '-3px'
			})
			.end()
			.css('cursor', 'move')
			.fadeIn();
		}
		jquitr.reloadCSS();		
}
//close dev tool
jquitr.closeThemeRoller = function(){
	jQuery('#inline_themeroller').fadeOut();
};
//get current url hash
jquitr.getHash = function(){
	var currSrc = window.location.hash;
	if(currSrc.indexOf('#') > -1){currSrc = currSrc.split('#')[1];}
	return currSrc;
};
//recursive reload call
jquitr.reloadCSS = function(){
	var currSrc = jquitr.getHash();
	if(jquitr.trString != currSrc && currSrc != ''){
		jquitr.trString = currSrc;
		var cssLink = '<link href="http://jqueryui.com/themeroller/css/parseTheme.css.php?'+ currSrc +'" type="text/css" rel="Stylesheet" />';
		//works for both 1.6 final and early rc's
		if( jQuery("link[href*=parseTheme.css.php], link[href=ui.theme.css]").size() > 0){
			jQuery("link[href*=parseTheme.css.php]:last, link[href=ui.theme.css]:last").eq(0).after(cssLink);
		}
		else {
			jQuery("head").append(cssLink);
		}
		if( jQuery("link[href*=parseTheme.css.php]").size() > 3){
			jQuery("link[href*=parseTheme.css.php]:first").remove();
		}
	}
	setTimeout(jquitr.reloadCSS, 1000);
}


В двух словах он загружает jQuery и jQueryUI (нах они, ведь и так есть, наверное). Большая половина кода загружает iframe с красивенькими табами и еще одной копией jQuery и jQueryUI (фак, их уже три!!!), так же она управляет самим поп-апом (ресайз, драг, анимация). Удивляет то что iframe имеет расширение .php , хотя может это для маскировки.

Теперь вернемся к скрипту, оставшаяся меньшая половина делает магию. Как вы знаете iframe не имеет доступа к странице, то есть напрямую ей управлять не может, он имеет доступ только к window.location.hash, это та часть URL которая называется якорь (anchor). Так вот когда я в iframe выбираю тему или меняю какой-то параметр текущей, он записывает в урл моего сайта нечто вроде


#ffDefault=Segoe+UI%2C+Arial%2C+sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=6px&bgColorHeader=333333&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=25&borderColorHeader=333333&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=000000&bgTextureContent=05_inset_soft.png&bgImgOpacityContent=25&borderColorContent=666666&fcContent=ffffff&iconColorContent=cccccc&bgColorDefault=555555&bgTextureDefault=02_glass.png&bgImgOpacityDefault=20&borderColorDefault=666666&fcDefault=eeeeee&iconColorDefault=cccccc&bgColorHover=0078a3&bgTextureHover=02_glass.png&bgImgOpacityHover=40&borderColorHover=59b4d4&fcHover=ffffff&iconColorHover=ffffff&bgColorActive=f58400&bgTextureActive=05_inset_soft.png&bgImgOpacityActive=30&borderColorActive=ffaf0f&fcActive=ffffff&iconColorActive=222222&bgColorHighlight=eeeeee&bgTextureHighlight=03_highlight_soft.png&bgImgOpacityHighlight=80&borderColorHighlight=cccccc&fcHighlight=2e7db2&iconColorHighlight=4b8e0b&bgColorError=ffc73d&bgTextureError=02_glass.png&bgImgOpacityError=40&borderColorError=ffb73d&fcError=111111&iconColorError=a83300&bgColorOverlay=5c5c5c&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=50&opacityOverlay=80&bgColorShadow=cccccc&bgTextureShadow=01_flat.png&bgImgOpacityShadow=30&opacityShadow=60&thicknessShadow=7px&offsetTopShadow=-7px&offsetLeftShadow=-7px&cornerRadiusShadow=8px

Тут уже его мониторит скрипт который по setTimeout каждую секунду проверяет не изменился ли window.location.hash и если да, то передает всю эту строку другому скрипту, который знает как из этой каши сделать новую тему.

Новая тема добавляется в header страницы перекрывая прошлую. Единственное маленькое НО, если вы как я вставляли CSS файлы в средину страницы, непосредственно перед их использованием, то это нихера работать не будет. Надо чтобы старые файлы находились выше по коду чем новые. Именно поэтому мне сегодня пришлось поправить десяток статей и обновить шкурку вордпресса, так что если найдете какие-нибудь баги, не стесняйтесь пишите в каменты.

Непонятным осталось только одно - зачем эта штука хранить 3 последние загруженные темы ?! Что-то я не заметил механизма отката изменений...

  1. Пока что нет комментариев.
  1. Пока что нет уведомлений.