# This code was forked from the LiveJournal project owned and operated # by Live Journal, Inc. The code has been modified and expanded by # Dreamwidth Studios, LLC. These files were originally licensed under # the terms of the license supplied by Live Journal, Inc, which can # currently be found at: # # http://code.livejournal.org/trac/livejournal/browser/trunk/LICENSE-LiveJournal.txt # # In accordance with the original license, this code and all its # modifications are provided under the GNU General Public License. # A copy of that license can be found in the LICENSE file included as # part of this distribution. package LJ::Widget::ThemeNav; use strict; use base qw(LJ::Widget); use Carp qw(croak); use LJ::Customize; sub ajax { 1 } sub can_fake_ajax_post { 1 } sub authas { 1 } sub need_res { qw( stc/widgets/themenav.css js/6alib/inputcomplete.js ) } sub render_body { my $class = shift; my %opts = @_; my $u = $class->get_effective_remote(); die "Invalid user." unless LJ::isu($u); my $theme_chooser_id = defined $opts{theme_chooser_id} ? $opts{theme_chooser_id} : 0; my $headextra = $opts{headextra}; my $remote = LJ::get_remote(); my $getextra = $u->user ne $remote->user ? "?authas=" . $u->user : ""; my $getsep = $getextra ? "&" : "?"; # filter criteria my $cat = defined $opts{cat} ? $opts{cat} : ""; my $layoutid = defined $opts{layoutid} ? $opts{layoutid} : 0; my $designer = defined $opts{designer} ? $opts{designer} : ""; my $search = defined $opts{search} ? $opts{search} : ""; my $page = defined $opts{page} ? $opts{page} : 1; my $show = defined $opts{show} ? $opts{show} : 12; my $showarg = $show != 12 ? "show=$opts{show}" : ""; # we want to have "All" selected if we're filtering by layout or designer, or if we're searching my $viewing_all = $layoutid || $designer || $search; my $theme_chooser = LJ::Widget::ThemeChooser->new( id => $theme_chooser_id ); $theme_chooser_id = $theme_chooser->{id} unless $theme_chooser_id; $$headextra .= $theme_chooser->wrapped_js( page_js_obj => "Customize" ) if $headextra; # sort cats by specificed order key, then alphabetical order my %cats = LJ::Customize->get_cats($u); my @cats_sorted = sort { $cats{$a}->{order} <=> $cats{$b}->{order} } sort { lc $cats{$a}->{text} cmp lc $cats{$b}->{text} } keys %cats; # pull the main cats out of the full list my @main_cats_sorted; for ( my $i = 0 ; $i < @cats_sorted ; $i++ ) { my $c = $cats_sorted[$i]; if ( defined $cats{$c}->{main} ) { my $el = splice( @cats_sorted, $i, 1 ); push @main_cats_sorted, $el; $i--; # we just removed an element from @cats_sorted } } my @keywords = LJ::Customize->get_search_keywords_for_js($u); my $keywords_string = join( ",", @keywords ); my $upsell = LJ::Hooks::run_hook( 'customize_advanced_area_upsell', $u ) || ''; my $main_cat_list = $class->print_cat_list( user => $u, selected_cat => $cat, viewing_all => $viewing_all, cat_list => \@main_cats_sorted, getextra => $getextra, showarg => $showarg, ); my $cat_list = $class->print_cat_list( user => $u, selected_cat => $cat, viewing_all => $viewing_all, cat_list => \@cats_sorted, getextra => $getextra, showarg => $showarg, ); my $themechooser_html = $theme_chooser->render( 'cat' => $cat, 'layoutid' => $layoutid, 'designer' => $designer, 'search' => $search, 'page' => $page, 'show' => $show ); my $vars = { cat => $cat, layoutid => $layoutid, designer => $designer, search => $search, page => $page, show => $show, themechooser_html => $themechooser_html, keywords_string => $keywords_string, upsell => $upsell, cats_sorted => \@cats_sorted, main_cat_list => $main_cat_list, cat_list => $cat_list }; return DW::Template->template_string( 'widget/themenav.tt', $vars ); } sub print_cat_list { my $class = shift; my %opts = @_; my $u = $opts{user}; my $cat_list = $opts{cat_list}; my %cats = LJ::Customize->get_cats($u); my @special_themes = LJ::S2Theme->load_by_cat("special"); my $special_themes_exist = 0; foreach my $special_theme (@special_themes) { my $layout_is_active = LJ::Hooks::run_hook( "layer_is_active", $special_theme->layout_uniq ); my $theme_is_active = LJ::Hooks::run_hook( "layer_is_active", $special_theme->uniq ); if ( $layout_is_active && $theme_is_active ) { $special_themes_exist = 1; last; } } my @custom_themes = LJ::S2Theme->load_by_user( $opts{user} ); my $ret; for ( my $i = 0 ; $i < @$cat_list ; $i++ ) { my $c = $cat_list->[$i]; next if $c eq "special" && !$special_themes_exist; next if $c eq "custom" && !@custom_themes; my $li_class = ""; $li_class .= " on" if ( $c eq $opts{selected_cat} ) || ( $c eq "featured" && !$opts{selected_cat} && !$opts{viewing_all} ) || ( $c eq "all" && $opts{viewing_all} ); $li_class .= " first" if $i == 0; $li_class .= " last" if $i == @$cat_list - 1; $li_class =~ s/^\s//; # remove the first space $li_class = " class='$li_class'" if $li_class; my $arg = ""; $arg = "cat=$c" unless $c eq "featured"; if ( $arg || $opts{showarg} ) { my $allargs = $arg; $allargs .= "&" if $allargs && $opts{showarg}; $allargs .= $opts{showarg}; $arg = $opts{getextra} ? "&$allargs" : "?$allargs"; } $ret .= "$cats{$c}->{text}"; } return $ret; } sub handle_post { my $class = shift; my $post = shift; my %opts = @_; my $q_string = BML::get_query_string(); $q_string =~ s/&?page=\d+//g; my $url = "$LJ::SITEROOT/customize/"; if ( $post->{filter} ) { $q_string = "?$q_string" if $q_string; my $q_sep = $q_string ? "&" : "?"; $url .= $q_string; } elsif ( $post->{page} ) { $q_string = "?$q_string" if $q_string; my $q_sep = $q_string ? "&" : "?"; $post->{page} = LJ::eurl( $post->{page} ); if ( $post->{page} != 1 ) { $url .= "$q_string${q_sep}page=$post->{page}"; } else { $url .= $q_string; } } elsif ( $post->{show} ) { $q_string =~ s/&?show=\w+//g; $q_string = "?$q_string" if $q_string; my $q_sep = $q_string ? "&" : "?"; $post->{show} = LJ::eurl( $post->{show} ); if ( $post->{show} != 12 ) { $url .= "$q_string${q_sep}show=$post->{show}"; } else { $url .= $q_string; } } elsif ( $post->{search} ) { my $show = ( $q_string =~ /&?show=(\w+)/ ) ? "&show=$1" : ""; my $authas = ( $q_string =~ /&?authas=(\w+)/ ) ? "&authas=$1" : ""; $q_string = ""; $post->{search} = LJ::eurl( $post->{search} ); $url .= "?search=$post->{search}$authas$show"; } return BML::redirect($url); } sub js { q [ initWidget: function () { var self = this; if ($('search_box')) { var keywords = new InputCompleteData(Customize.ThemeNav.searchwords, "ignorecase"); var ic = new InputComplete($('search_box'), keywords); var text = "theme, layout, or designer"; var color = "#999"; $('search_box').style.color = color; $('search_box').value = text; DOM.addEventListener($('search_box'), "focus", function (evt) { if ($('search_box').value == text) { $('search_box').style.color = ""; $('search_box').value = ""; } }); DOM.addEventListener($('search_box'), "blur", function (evt) { if ($('search_box').value == "") { $('search_box').style.color = color; $('search_box').value = text; } }); } // add event listener to the search form DOM.addEventListener($('search_form'), "submit", function (evt) { self.filterThemes(evt, "search", $('search_box').value) }); var filter_links = DOM.getElementsByClassName(document, "theme-nav-cat"); // add event listeners to all of the category links filter_links.forEach(function (filter_link) { var evt_listener_added = 0; var getArgs = LiveJournal.parseGetArgs(filter_link.href); for (var arg in getArgs) { if (!getArgs.hasOwnProperty(arg)) continue; if (arg == "authas" || arg == "show") continue; DOM.addEventListener(filter_link, "click", function (evt) { self.filterThemes(evt, arg, unescape( getArgs[arg] ) ) }); evt_listener_added = 1; break; } // if there was no listener added to a link, add it without any args (for the 'featured' category) if (!evt_listener_added) { DOM.addEventListener(filter_link, "click", function (evt) { self.filterThemes(evt, "", "") }); } }); }, filterThemes: function (evt, key, value) { if (key == "show") { // need to go back to page 1 if the show amount was switched because // the current page may no longer have any themes to show on it Customize.page = 1; } else if (key != "page") { Customize.resetFilters(); } // do not do anything with a layoutid of 0 if (key == "layoutid" && value == 0) { Event.stop(evt); return; } if (key == "cat") Customize.cat = value; if (key == "layoutid") Customize.layoutid = value; if (key == "designer") Customize.designer = value; if (key == "search") Customize.search = value; if (key == "page") Customize.page = value; if (key == "show") Customize.show = value; this.updateContent({ method: "GET", cat: Customize.cat, layoutid: Customize.layoutid, designer: Customize.designer, search: Customize.search, page: Customize.page, show: Customize.show, theme_chooser_id: $('theme_chooser_id').value }); Event.stop(evt); if (key == "search") { $("search_btn").disabled = true; } else if (key == "page" || key == "show") { $("paging_msg_area_top").innerHTML = "Please wait..."; $("paging_msg_area_bottom").innerHTML = "Please wait..."; } else { Customize.cursorHourglass(evt); } }, onData: function (data) { Customize.CurrentTheme.updateContent({ show: Customize.show }); Customize.hideHourglass(); }, onRefresh: function (data) { this.initWidget(); Customize.ThemeChooser.initWidget(); } ]; } 1;