1var ThemeChooser = { 2 init: function(){ 3 var selected_theme = arguments[0]; 4 var me = this; 5 this.hidden = true; 6 this.descriptions = []; 7 if (typeof(themeDescriptions) !== 'undefined') 8 this.descriptions = themeDescriptions; 9 this.element = $('#theme-chooser'); 10 if (this.element.length === 0) this.element = $('#themes-container'); 11 this.$selected = this.element.find('.selected'); 12 if(!selected_theme) 13 selected_theme = this.$selected.attr('data-theme'); 14 this.selected = selected_theme; 15 this.active = selected_theme; 16 this.header = $('#theme-chooser-header'); 17 this.tabBar = $('ul#theme-tabs'); 18 this.tabs = $('ul#theme-tabs li.theme-tab'); 19 this.sections = $('#themes-container section.themes'); 20 this.activateButton = this.element.find('.activate-theme'); 21 this.activateButton.hide(); 22 this.editButton = this.element.find('.edit_theme'); 23 this.customizeButton = this.element.find('.customize_theme'); 24 this.closeButton = this.header.find('.close_dialog'); 25 this.themesContainer = $('#themes-container'); 26 /* DEPRECATED START */ 27 this.previewContainer = $('#theme-preview-container'); 28 this.previewPage = this.previewContainer.find('.theme_page'); 29 this.previewTitle = this.previewContainer.find('.theme-details h3'); 30 this.previewDescription = 31 this.previewContainer.find('p.theme-description'); 32 this.previewButton = this.previewContainer.find('.preview_theme'); 33 /*DEPRECATED END */ 34 35 this.bookFormThemeTab = $('#book-data #theme,#print-data #theme'); 36 this.bookFormThemeContainer = 37 this.bookFormThemeTab.find('.theme-container'); 38 this.bookFormTheme = this.bookFormThemeContainer.find('.theme'); 39 this.bookFormThemeTitle = 40 this.bookFormThemeTab.find('.theme-name'); 41 this.bookFormThemeDescription = 42 this.bookFormThemeTab.find('.theme-description'); 43 this.bookFormThemeActions = 44 this.bookFormThemeContainer.find('.theme-action'); 45 this.bookFormThemeActions = 46 this.bookFormThemeActions. 47 add(this.bookFormThemeTab.find('#theme-actions button')); 48 this.isPrintProduct = 49 (this.bookFormThemeTab.parents('#print-data').length > 0); 50 this.previewButtons = this.element.find('.preview-button'); 51 this.activeLabel = this.previewContainer.find('.active-label'); 52 this.pagePreviewContainer = $('#theme-container'); 53 this.pagePreviewImage = this.pagePreviewContainer.find('.theme'); 54 this.pagePreviewTitle = this.pagePreviewContainer.find('.theme-name'); 55 this.newThemesButton = this.tabBar.find('.new-theme'); 56 this.newThemeDialog = $('#new-theme-dialog'); 57 this.themes = this.themesContainer.find('.theme-container'); 58 this.themes.click(function(){ 59 var $this = $(this); 60 var theme_id = $this.attr('data-theme'); 61 me.selectTheme(theme_id, $this); 62 }); 63 this.closeButton.click(function(){ 64 me.hide(); 65 }); 66 var getClickHandler = function (targetButton) { 67 return function (e) { 68 var $this = $(this); 69 var $theme = $this.parents('.theme-container'); 70 if ($theme.length) { 71 var theme_id = $theme.attr('data-theme'); 72 me.selectTheme(theme_id, $theme); 73 var btn = targetButton; 74 if (typeof(btn) === 'function') 75 btn = targetButton($theme); 76 btn.click(); 77 } 78 } 79 }; 80 this.element.find('.activate-button'). 81 click(getClickHandler(this.activateButton)); 82 this.element.find('.edit-button').click(getClickHandler(function ($t) { 83 var is_user = $t.data('userTheme'); 84 return (is_user ? me.editButton : me.customizeButton); 85 })); 86 this.element.find('.info-button').click(function () { 87 //var $this = $(this); 88 //var $theme = $this.parents('.theme-container'); 89 var $details = me.previewContainer; 90 $details.transitionShow({fade:true, duration:300}); 91 }); 92 this.previewContainer.find('.close_dialog').click(function(){ 93 me.previewContainer.transitionHide({fade:true, duration:300}); 94 }); 95 this.activateButton.click(function () { 96 if (me.isActivating) return; 97 var $this = $(this); 98 me.activateButton.hide(); 99 var theme = me.selected; 100 if (!theme) return; 101 if (me.isPrintProduct) { 102 PrintProductForm.save('theme', theme, me.activateButton, 103 function (res) { 104 try { 105 res = res.theme || {}; 106 if (theme == res.id) { 107 me.onThemeActivated(theme, res); 108 } 109 } catch (e) { 110 console.error(e); 111 } 112 }); 113 return; 114 } 115 var bookID = me.getBookID(); 116 var url = '/ajax/ebook/:id/set_theme/:theme_name'; 117 url = url.ajaxUrl({ 118 id: bookID, 119 theme_name: theme 120 }); 121 me.isActivating = true; 122 $.get(url, '', function(res,xhr,code){ 123 me.isActivating = false;
124 if (code.status == 200) { 125 try { 126 res = parseBackTypoResponse(res); 127 if (theme == res.id) { 128 me.onThemeActivated(theme, res); 129 } 130 } catch (e) { 131 console.error(e); 132 } 133 } else { 134 alert('Error'); 135 console.log(res); 136 $this.show(); 137 } 138 }); 139 }); 140 this.previewButton.click(function(){ 141 var themeName = me.selected; 142 var url = '/ajax/theme/:theme_name/screenshots'.ajaxUrl({ 143 theme_name: themeName 144 }); 145 openScreenshotsViewer(url); 146 }); 147 this.previewButtons.click(function(evt){ 148 evt.preventDefault(); 149 evt.stopPropagation(); 150 var tpl = $(this).parents('.theme-container').data('theme'); 151 var url = '/ajax/theme/:theme_name/screenshots'.ajaxUrl({ 152 theme_name: tpl 153 }); 154 openScreenshotsViewer(url); 155 }); 156 this.editButton.click(function () { 157 var theme = me.selected; 158 if(!theme) return; 159 var elem = me.getThemeElement(theme); 160 var url = elem.data('url'); 161 if (url) { 162 location.href = url; 163 } 164 }); 165 this.customizeButton.click(function () { 166 var theme = me.selected; 167 if(!theme) return; 168 me.openNewThemeDialog({parent: theme}); 169 }); 170 var safariMatch = navigator.userAgent.match(/Safari/i); 171 var chromeMatch = navigator.userAgent.match(/Chrome/i); 172 this.isSafari = (safariMatch != null && 173 safariMatch.length > 0 && !chromeMatch); 174 this.safariBugged = $('#theme-chooser-header,#theme-preview-container'); 175 var currentTab = this.tabs.filter('.current'); 176 this.currentSection = currentTab.data('section'); 177 this.tabs.click(function () { 178 var $tab = $(this); 179 var section = $tab.data('section'); 180 if (section) { 181 me.changeSection(section, $tab); 182 } 183 }); 184 var noThumbThemes = this.themes.filter('.no-thumb'); 185 if (noThumbThemes.length) { 186 noThumbThemes.each(function () { 187 var $theme = $(this); 188 updateThemeThumbnail($theme); 189 }); 190 } 191 this.newThemesButton.click(function () { 192 me.openNewThemeDialog(); 193 }); 194 this.initNewThemeDialog(); 195 /*this.element.scroll(function(evt){ 196 evt.stopImmediatePropagation(); 197 evt.stopPropagation(); 198 });*/ 199 }, 200 onThemeActivated: function (theme_id, theme) { 201 this.active = theme_id; 202 this.themesContainer.find('.active'). 203 removeClass('active'); 204 var elem = this.getThemeElement(theme_id); 205 elem.addClass('active'); 206 this.selectTheme(theme_id); 207 var thumb = theme.thumb; 208 var themeclass = theme_id + '_theme'; 209 var do_update = false; 210 if (thumb) { 211 thumb = 'url(' + thumb + ')'; 212 } else { 213 thumb = 'none'; 214 themeclass += ' no-thumb'; 215 do_update = true; 216 } 217 this.bookFormThemeContainer. 218 data('theme', theme_id). 219 attr('data-theme', theme_id); 220 var themeName = theme.name; 221 if (!themeName) { 222 themeName = theme_id.replace(/_/g, ' '); 223 themeName = themeName.capitalize(); 224 } 225 this.bookFormThemeTitle.text(themeName); 226 var descr = this.descriptions[theme_id] || ''; 227 this.bookFormThemeDescription.text(descr); 228 this.activeLabel.show(); 229 $('#bundler-dialog .current-theme span').text(themeName); 230 var is_custom = theme.user_theme; 231 var editBtn = null; 232 var editLbl = null; 233 if (is_custom) { 234 editBtn = $('#customize-theme'); 235 if (editBtn.length) { 236 editBtn.attr('id', 'edit-theme'); 237 } else { 238 editBtn = $('#edit-theme'); 239 } 240 editLbl = 'edit_theme';
241 } else { 242 editBtn = $('#edit-theme'); 243 if (editBtn.length) { 244 editBtn.attr('id', 'customize-theme'); 245 } else { 246 editBtn = $('#customize-theme'); 247 } 248 editLbl = 'customize_theme'; 249 } 250 if (editBtn && editBtn.length) { 251 editLbl = BackTypoLocalizedString(editLbl); 252 editBtn.data('theme-id', theme_id). 253 attr('data-theme-id', theme_id). 254 find('span'). 255 text(editLbl.capitalize()); 256 257 } 258 this.bookFormThemeActions. 259 attr('data-theme-id', theme_id); 260 editBtn = 261 this.bookFormThemeActions.filter('.edit-button'); 262 editBtn.attr('data-action', 263 (is_custom ? 'edit' : 'customize')); 264 if (do_update) 265 updateThemeThumbnail(this.bookFormTheme); 266 else 267 this.bookFormTheme.css('background-image', thumb); 268 }, 269 changeSection: function (section) { 270 var $tab = arguments[1]; 271 if (!$tab) 272 $tab = this.tabBar.find('li[data-section="' + section + '"]'); 273 if (section == this.currentSection) return; 274 this.tabs.removeClass('current'); 275 this.sections.removeClass('current'); 276 $tab.addClass('current'); 277 $('section#' + section + '-themes').addClass('current'); 278 this.currentSection = section; 279 }, 280 openNewThemeDialog: function () { 281 var opts = arguments[0] || {}; 282 var parentTheme = opts.parent; 283 var dialog = this.newThemeDialog; 284 if (parentTheme) { 285 var parentSelector = dialog.find('select[name="parent-theme"]'); 286 parentSelector.val(parentTheme); 287 } 288 dialog.data('book-id', opts.bookID); 289 dialog.css('display','flex').transition({opacity: 1, duration: 400}); 290 setTimeout(function () { 291 var nameField = dialog.find('#new-theme-name'); 292 nameField.focus(); 293 }, 410); 294 }, 295 closeNewThemeDialog: function () { 296 var dialog = this.newThemeDialog; 297 dialog.transition({opacity: 0, duration: 400}); 298 setTimeout(function () { 299 dialog.hide(); 300 }, 410); 301 }, 302 initNewThemeDialog: function () { 303 var me = this; 304 var dialog = this.newThemeDialog; 305 dialog.css('opacity', 0); 306 var closeBtn = dialog.find('.close_dialog'); 307 closeBtn.click(function () { 308 me.closeNewThemeDialog(); 309 }); 310 var nameField = dialog.find('#new-theme-name'); 311 var parentSelector = dialog.find('select[name="parent-theme"]'); 312 var createBtn = dialog.find('.create-button'); 313 var createTheme = function () { 314 if (me.isCreatingNewTheme) return; 315 var name = nameField.val(); 316 if (!name) { 317 nameField.addClass('required'); 318 nameField.focus(); 319 return; 320 } 321 nameField.removeClass('required'); 322 me.isCreatingNewTheme = true; 323 var par = parentSelector.val(); 324 var newTheme = { 325 name: name, 326 parent: par, 327 book_model: me.element.data('model') 328 }; 329 var bookID = dialog.data('book-id'); 330 if (bookID) newTheme.book_id = bookID; 331 var url = '/ajax/user_themes'; 332 $.post(url, JSON.stringify(newTheme), function (r) { 333 try { 334 me.isCreatingNewTheme = false; 335 r = parseBackTypoResponse(r); 336 if (r.error) { 337 var errmsg = LocalizedString[r.error] || 338 r.error.replace('_', ' ').capitalize(); 339 displayErrorDialog(errmsg); 340 return; 341 } 342 var themeUrl = r.url; 343 if (!themeUrl) { 344 // TODO: Handle 345 return; 346 }
347 //TODO: Add new theme to theme chooser UI 348 location.href = themeUrl; 349 } catch (e) { 350 // TODO: Handle 351 var errmsg = e.toString(); 352 var btErr = e.backtypoError; 353 if (btErr) errmsg = btErr.error; 354 if (btErr == 'authentication_failed') { 355 onAjaxAuthenticationFailure(e); 356 } 357 errmsg = LocalizedString[errmsg] || 358 errmsg.replace(/_/g, ' ').capitalize() 359 displayErrorDialog(errmsg || 'error'); 360 } 361 }); 362 }; 363 createBtn.click(createTheme); 364 nameField.keypress(function(e){ 365 if(e.which == 13){ 366 createTheme(); 367 } 368 }); 369 370 }, 371 selectTheme: function(theme_id){ 372 this.selected = theme_id; 373 var sel = this.element.find('.selected') 374 sel.removeClass('selected'); 375 var elem = arguments[1]; 376 if (!elem) { 377 elem = this.getThemeElement(theme_id); 378 } 379 elem.addClass('selected'); 380 var bgimg = 'url(/images/' + theme_id + '.example.png)'; 381 var themeName = elem.data('name'); 382 var isUserTheme = elem.data('user-theme'); 383 var section = elem.data('section'); 384 if (section) this.changeSection(section); 385 themeName = themeName || theme_id.replace(/_/g, ' '); 386 this.previewPage.css('background-image', bgimg); 387 this.previewTitle.text(themeName.capitalizeAll()); 388 this.previewDescription.text(this.descriptions[theme_id] || ''); 389 this.$selected = elem; 390 if(!this.isActivating){ 391 if(this.active != theme_id){ 392 this.activateButton.show(); 393 this.previewButton.show(); 394 this.activeLabel.hide(); 395 } 396 else { 397 this.previewButton.show(); 398 this.activateButton.hide(); 399 this.activeLabel.show(); 400 } 401 } else { 402 this.activateButton.hide(); 403 this.activeLabel.hide(); 404 } 405 if (isUserTheme) { 406 this.customizeButton.hide(); 407 this.editButton.show(); 408 } else { 409 this.customizeButton.show(); 410 this.editButton.hide(); 411 } 412 }, 413 getThemeElement: function (themeId) { 414 return $('#' + themeId.replace(/:/g, '-') +'-theme'); 415 }, 416 getBookID: function(){ 417 if(!this.bookID){ 418 if(typeof(BookForm) != 'undefined'){ 419 this.bookID = BookForm.bookID; 420 } 421 else if(typeof(authoringTool) != 'undefined'){ 422 this.bookID = authoringTool.bookID; 423 } 424 } 425 return this.bookID; 426 }, 427 show: function(){ 428 var opts = arguments[0] || {}; 429 var $el = this.element; 430 disableWindowScroll(); 431 if(opts.animate === false){ 432 $el.css('translate', '0,0'); 433 $el.show(); 434 return; 435 } 436 if(this.isSafari) this.safariBugged.css('opacity',0); 437 var redactorDisabler = $('#redactor-disabler'); 438 if(redactorDisabler.length > 0){ 439 this.redactorDisabledZIndex = redactorDisabler.css('z-index'); 440 redactorDisabler.css('z-index', 1); 441 } 442 $el.css('translate', '0,-100%'); 443 $el.show(); 444 $el.transition({x: 0, y: 0, duration: 400}); 445 var _this = this; 446 // Workaround for Webkit and mouse-over after translate 447 _this.element.find('.selected').removeClass('selected'); 448 setTimeout(function(){ 449 $el.css('transform',''); 450 if(_this.isSafari) 451 _this.safariBugged.transition({opacity: 1, duration:100}); 452 // Workaround for Webkit and mouse-over after translate 453 _this.selectTheme(_this.selected,_this.$selected); 454 $('#ebook-data, #main, body').css('overflow-y', 'hidden'); 455 $el.removeClass('hidden'); 456 }, 450); 457 this.hidden = false;
458 $('#choose_theme').addClass('active'); 459 }, 460 hide: function(){ 461 var $el = this.element; 462 if(this.isSafari) 463 this.safariBugged.css({opacity: 0}); 464 if(this.redactorDisabledZIndex){ 465 var redactorDisabler = $('#redactor-disabler'); 466 redactorDisabler.css('z-index', this.redactorDisabledZIndex); 467 } 468 $el.transition({x: 0, y: '-100%', duration: 400}); 469 setTimeout(function(){ 470 $el.hide(); 471 $('#ebook-data, #main, body').css('overflow-y', ''); 472 $el.addClass('hidden'); 473 },430); 474 this.hidden = true; 475 $('#choose_theme').removeClass('active'); 476 enableWindowScroll(); 477 } 478}; 479 480$(document).ready(function(){ 481 ThemeChooser.init(); 482 var params = parseQueryString() || {}; 483 if(params.choose_theme){ 484 ThemeChooser.show({animate: false}); 485 } 486});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.