Igor Gariev (gariev) wrote in changelog,
Igor Gariev
gariev
changelog

[livejournal] r20555: LJSUP-10420: S1 Comments ?\226?\128?\148...

Committer: gariev
LJSUP-10420: S1 Comments ?\226?\128?\148?\194?\160v.2 (update from trunk)
U   branches/commenting-form/bin/upgrading/s2layers/disjointed/layout.s2
U   branches/commenting-form/cgi-bin/Apache/LiveJournal.pm
U   branches/commenting-form/cgi-bin/LJ/Customize.pm
U   branches/commenting-form/cgi-bin/LJ/DelayedEntry.pm
U   branches/commenting-form/cgi-bin/LJ/Entry.pm
U   branches/commenting-form/cgi-bin/LJ/S2/DayPage.pm
U   branches/commenting-form/cgi-bin/LJ/S2.pm
U   branches/commenting-form/cgi-bin/LJ/Session.pm
U   branches/commenting-form/cgi-bin/LJ/Talk.pm
U   branches/commenting-form/htdocs/community/members.bml
U   branches/commenting-form/htdocs/delcomment.bml
U   branches/commenting-form/htdocs/go.bml
U   branches/commenting-form/htdocs/js/ck/contents.css
A   branches/commenting-form/htdocs/js/ck/images/ljcut.png
U   branches/commenting-form/htdocs/js/ck/plugins/livejournal/plugin.js
U   branches/commenting-form/htdocs/js/rte.js
U   branches/commenting-form/htdocs/talkmulti.bml
U   branches/commenting-form/htdocs/talkscreen.bml
Modified: branches/commenting-form/bin/upgrading/s2layers/disjointed/layout.s2
===================================================================
--- branches/commenting-form/bin/upgrading/s2layers/disjointed/layout.s2	2011-11-17 10:30:32 UTC (rev 20554)
+++ branches/commenting-form/bin/upgrading/s2layers/disjointed/layout.s2	2011-11-17 10:31:58 UTC (rev 20555)
@@ -907,11 +907,15 @@
   }
   if($this isa Entry) {
     var Entry en = $this as Entry;
-
-    if ($en.delayed) { "$en.delayed_icon "; }
-    if ($en.sticky) { "$en.sticky_icon "; }
-    if ($en.security) { "$en.security_icon "; }
-
+    if ($en.delayed) {
+        $icon = $en.delayed_icon + " ";
+        }
+    if ($en.sticky) {
+        $icon = $en.sticky_icon + " ";
+    }
+    if ($en.security) {
+        $icon = $en.security_icon + " ";
+    }
   }
   return $icon;
 }
@@ -1534,8 +1538,8 @@
     if ($p.view != "entry" and not $subject->contains("<a ")) {
         $subject = """<a name="$id" id="$id"></a>$icon<a href="$e.permalink_url" class="subj subj-link">$subject</a>""";
     } else {
-       $subject = """<a name="$id" id="$id"></a>$icon$subject""";
-}
+        $subject = """<a name="$id" id="$id"></a>$icon$subject""";
+    }
 
 
   if ($e isa Comment) {

Modified: branches/commenting-form/cgi-bin/Apache/LiveJournal.pm
===================================================================
--- branches/commenting-form/cgi-bin/Apache/LiveJournal.pm	2011-11-17 10:30:32 UTC (rev 20554)
+++ branches/commenting-form/cgi-bin/Apache/LiveJournal.pm	2011-11-17 10:31:58 UTC (rev 20555)
@@ -2388,7 +2388,7 @@
         ##
         warn "LJ::XMLRPC::$method died: $@"
             if $@ !~ /^\d+?\s*:/
-            and $@ =~ m/\s*:\s+Account not validated./
+            and $@ !~ m/\s*:\s*Account not validated./
             and $@ ne "Unknown username.";
 
         die $@;

Modified: branches/commenting-form/cgi-bin/LJ/Customize.pm
===================================================================
--- branches/commenting-form/cgi-bin/LJ/Customize.pm	2011-11-17 10:30:32 UTC (rev 20554)
+++ branches/commenting-form/cgi-bin/LJ/Customize.pm	2011-11-17 10:31:58 UTC (rev 20555)
@@ -544,12 +544,14 @@
             $prop = S2::get_property($lyr_core->{'s2lid'}, $prop);
             next unless ref $prop;
         }
-        
-        if ($prop->{'name'} eq 'sticky_subject' ||
-            $prop->{'name'} eq 'sticky_post' ) {
-            my $value = $class->get_s2_prop_values('sticky_post', $u, $style);
-            if (!$value) {
-                next;
+       
+        if (LJ::is_enabled("delayed_entries")) { 
+            if ($prop->{'name'} eq 'sticky_subject' ||
+                $prop->{'name'} eq 'sticky_post' ) {
+                my $value = $class->get_s2_prop_values('sticky_post', $u, $style);
+                if (!$value) {
+                    next;
+                }
             }
         }
 

Modified: branches/commenting-form/cgi-bin/LJ/DelayedEntry.pm
===================================================================
--- branches/commenting-form/cgi-bin/LJ/DelayedEntry.pm	2011-11-17 10:30:32 UTC (rev 20554)
+++ branches/commenting-form/cgi-bin/LJ/DelayedEntry.pm	2011-11-17 10:31:58 UTC (rev 20555)
@@ -951,6 +951,60 @@
                                      "ORDER BY is_sticky DESC, revptime $sql_limit");
 }
 
+sub get_first_entry {
+    my ( $journal, $userid ) = @_;
+    __assert($journal, "no journal");
+
+    my $dbcr = LJ::get_cluster_def_reader($journal)
+        or die "get cluster for journal failed";
+
+    my $u;
+    my $sql_poster = '';
+
+    unless ($userid) {
+        $u = LJ::get_remote();
+    } else {
+        $u = LJ::want_user($userid);
+    }
+
+    return 0 unless $u;
+    if (!__delayed_entry_can_see( $journal, $u ) ){
+        $sql_poster = 'AND posterid = ' . $u->userid . " ";
+    }
+
+    my ($id) = $dbcr->selectrow_array("SELECT delayedid " .
+                                      "FROM delayedlog2 WHERE journalid=?  $sql_poster".
+                                      "ORDER BY is_sticky ASC, revptime DESC LIMIT 1", undef, $journal->userid);
+    return $id || 0;
+}
+
+sub get_last_entry {
+    my ( $journal, $userid ) = @_;
+    __assert($journal, "no journal");
+
+    my $dbcr = LJ::get_cluster_def_reader($journal)
+        or die "get cluster for journal failed";
+
+    my $u;
+    my $sql_poster = '';
+    unless ($userid) {
+        $u = LJ::get_remote();
+    } else {
+        $u = LJ::want_user($userid);
+    }
+
+    return 0 unless $u;
+    if (!__delayed_entry_can_see( $journal, $u ) ){
+        $sql_poster = 'AND posterid = ' . $u->userid . " ";
+    }
+
+    my ($id) = $dbcr->selectrow_array("SELECT delayedid " .
+                                      "FROM delayedlog2 WHERE journalid=?  $sql_poster".
+                                      "ORDER BY is_sticky DESC, revptime ASC LIMIT 1", undef, $journal->userid);
+    return $id || 0;
+}
+
+
 sub get_daycount_query {
     my ($class, $journal, $list, $secwhere) = @_;
     my $dbcr = LJ::get_cluster_def_reader($journal);
@@ -1148,12 +1202,16 @@
 
 sub get_itemid_near2 {
     my ($u, $delayedid, $after_before) = @_;
-    
-    my ($order, $cmp1, $cmp2, $cmp3, $cmp4);
+
+    my $jid    = $u->userid;
+    my $remote = LJ::get_remote();
+    return 0 unless $remote;
+
+    my ($order, $order_sticky, $cmp1, $cmp2, $cmp3, $cmp4);
     if ($after_before eq "after") {
-        ($order, $cmp1, $cmp2, $cmp3, $cmp4) = ("DESC", "<=", ">", sub {$a->[0] <=> $b->[0]}, sub {$b->[1] <=> $a->[1]} );
+        ($order, $order_sticky, $cmp1, $cmp2, $cmp3, $cmp4) = ("DESC", "ASC", "<=", ">", sub {$a->[0] <=> $b->[0]}, sub {$b->[1] <=> $a->[1]} );
     } elsif ($after_before eq "before") {
-        ($order, $cmp1, $cmp2, $cmp3, $cmp4) = ("ASC",  ">=", "<", sub {$b->[0] <=> $a->[0]}, sub {$a->[1] <=> $b->[1]} );
+        ($order, $order_sticky, $cmp1, $cmp2, $cmp3, $cmp4) = ("ASC", "DESC",">=", "<", sub {$b->[0] <=> $a->[0]}, sub {$a->[1] <=> $b->[1]} );
     } else {
         return 0;
     }
@@ -1163,77 +1221,43 @@
         warn "Can't connect to cluster reader. Cluster: " . $u->clusterid;
         return 0;
     }
-
-    my $jid     = $u->userid;
-    my $field   = $u->is_person() ? "revptime" : "rlogtime";
-
-    my ($stime) = $dbr->selectrow_array(  "SELECT $field FROM delayedlog2 WHERE ".
-                                          "journalid=$jid AND delayedid=$delayedid");
+    
+    my ($stime, $is_current_sticky) = $dbr->selectrow_array( "SELECT revptime, is_sticky FROM delayedlog2 WHERE ".
+                                        "journalid=$jid AND delayedid=$delayedid");
     return 0 unless $stime;
 
-    my $secwhere = "AND security='public'";
-    my $remote   = LJ::get_remote();
-
-    if ($remote) {
-        if ($remote->userid == $jid) {
-            $secwhere = "";   # see everything
-        } elsif ($remote->is_person() || $remote->is_identity) {
-            my $gmask = LJ::get_groupmask($u, $remote);
-            $secwhere = "AND (security='public' OR (security='usemask' AND allowmask & $gmask))"
-            if $gmask;
-        }
+    my $sql_poster = '';
+    if (!__delayed_entry_can_see( $u, $remote ) ){
+        $sql_poster = 'AND posterid = ' . $remote->userid . " ";
     }
 
-    ##
-    ## We need a next/prev record in journal before/after a given time
-    ## Since several records may have the same time (time is rounded to 1 minute),
-    ## we're ordering them by jitemid. So, the SQL we need is
-    ##      SELECT * FROM log2
-    ##      WHERE journalid=? AND rlogtime>? AND jitmemid<?
-    ##      ORDER BY rlogtime, jitemid DESC
-    ##      LIMIT 1
-    ## Alas, MySQL tries to do filesort for the query.
-    ## So, we sort by rlogtime only and fetch all (2, 10, 50) records
-    ## with the same rlogtime (we skip records if rlogtime is different from the first one).
-    ## If rlogtime of all fetched records is the same, increase the LIMIT and retry.
-    ## Then we sort them in Perl by jitemid and takes just one.
-    ##
-    my $result_ref;
-    foreach my $limit (2, 10, 50, 100) {
-        $result_ref = $dbr->selectall_arrayref( "SELECT delayedid, $field FROM delayedlog2 use index (rlogtime,revptime) ".
-                                                "WHERE journalid=? AND $field $cmp1 ? AND delayedid <> ? ".
-                                                $secwhere. " ".
-                                                "ORDER BY $field $order LIMIT $limit",
-                                                undef, $jid, $stime, $delayedid
-        );
-
-        my %hash_times = ();
-        map {$hash_times{$_->[1]} = 1} @$result_ref;
-
-        # If we has one the only 'time' in $limit fetched rows,
-        # may be $limit cuts off our record. Increase the limit and repeat.
-        if (((scalar keys %hash_times) > 1) || (scalar @$result_ref) < $limit) {
-            my @result;
-
-            # Remove results with the same time but the jitemid is too high or low
-            if ($after_before eq "after") {
-                @result = grep { $_->[1] != $stime || $_->[0] > $delayedid } @$result_ref;
-            } elsif ($after_before eq "before") {
-                @result = grep { $_->[1] != $stime || $_->[0] < $delayedid } @$result_ref;
+    my $sql_item_rule = ''; 
+    if ($after_before eq "after") {
+        $sql_item_rule =  $is_current_sticky ? "(revptime $cmp1 ? AND is_sticky = 1 )" : 
+                                               "(revptime $cmp1 ? OR is_sticky = 1 )";
+    } else {
+        if ($is_current_sticky) {
+            my ($new_stime) = $dbr->selectrow_array("SELECT revptime " .
+                                                    "FROM delayedlog2 WHERE journalid=? $sql_poster AND is_sticky = 0 ".
+                                                    "ORDER BY revptime LIMIT 1", undef, $jid); 
+            if ($new_stime < $stime) {
+                $stime = $new_stime;
             }
-
-            # Sort result by jitemid and get our id from a top.
-            @result =  sort $cmp3 @result;
-
-            # Sort result by revttime
-            @result =  sort $cmp4 @result;
-
-            my $id = $result[0]->[0];
-            return 0 unless $id;
-            return $id;
+ 
+            $sql_item_rule = "(revptime $cmp1 ? )";
+        } else {
+            $sql_item_rule = "(revptime $cmp1 ? AND is_sticky = 0 )";
         }
+         
     }
-    return 0;
+
+    my $result_ref = $dbr->selectcol_arrayref(  "SELECT delayedid FROM delayedlog2 use index (rlogtime,revptime) ".
+                                                "WHERE journalid=? AND $sql_item_rule AND delayedid <> ? ".
+                                                $sql_poster. " ".
+                                                "ORDER BY is_sticky $order_sticky, revptime $order LIMIT 2",
+                                                undef, $jid, $stime, $delayedid);
+    return 0 unless $result_ref;
+    return $result_ref->[0];
 }
 
 sub handle_prefetched_props {

Modified: branches/commenting-form/cgi-bin/LJ/Entry.pm
===================================================================
--- branches/commenting-form/cgi-bin/LJ/Entry.pm	2011-11-17 10:30:32 UTC (rev 20554)
+++ branches/commenting-form/cgi-bin/LJ/Entry.pm	2011-11-17 10:31:58 UTC (rev 20555)
@@ -2198,6 +2198,152 @@
 sub get_itemid_after2  { return get_itemid_near2(@_, "after");  }
 sub get_itemid_before2 { return get_itemid_near2(@_, "before"); }
 
+sub get_latest_item {
+    my ($u, $opts) = @_;
+
+    my $dbr = LJ::get_cluster_reader($u);
+    unless ($dbr){
+        warn "Can't connect to cluster reader. Cluster: " . $u->clusterid;
+        return 0;
+    }
+
+    # Do I need to skip sticky entry?
+    my $skip_sticky_item_sql = '';
+    my $sticky_id = $u->get_sticky_entry_id;
+    if ( $opts->{'skip_sticky_item'} && $sticky_id ) {
+        #$skip_sticky_item_sql = "AND jitemid <> $sticky_id";
+    }
+
+    my $jid = $u->userid;
+    my $field = $u->is_person ? "revttime" : "rlogtime";
+
+    my $secwhere = "AND security='public'";
+    my $remote = LJ::get_remote();
+
+    if ($remote) {
+        if ($remote->userid == $u->userid) {
+            $secwhere = "";   # see everything
+        } elsif ($remote->is_person || $remote->is_identity) {
+            my $gmask = LJ::get_groupmask($u, $remote);
+            $secwhere = "AND (security='public' OR (security='usemask' AND allowmask & $gmask))"
+                if $gmask;
+        }
+    }
+
+    my $res = $dbr->selectcol_arrayref( "SELECT jitemid, anum FROM log2 use index (rlogtime,revttime) ".
+                                        "WHERE journalid=? $skip_sticky_item_sql ".
+                                        $secwhere. " ".
+                                        "ORDER BY $field LIMIT 1", undef, $jid);
+    my $itemid = $res->[0];
+    my $anum   = $res->[1];
+
+    return 0 unless $itemid;
+    return ($itemid*256 + $anum);
+}
+
+sub get_after_item_link {
+    my ($u, $opts) = @_;
+
+    my $jumpid;
+    my $sticky_id =  $u->get_sticky_entry_id;
+    my $use_sticky = $opts->{'use_sticky'};
+
+    my $itemid = $opts->{'itemid'};
+    my $delayed_id = $opts->{'delayedid'};
+
+    if ($opts->{'delayedid'}) {
+        # get next delayed entry
+        my $after_id = LJ::DelayedEntry::get_itemid_after2($u, $delayed_id);
+
+        # does entry exists ?
+        if ($after_id) {
+            # append prefix to delayed entries
+            $jumpid = 'd' . $after_id;
+        } elsif ($use_sticky && $sticky_id) {
+            my $sticky_entry = LJ::Entry->new( $u, jitemid => $sticky_id);
+            if ($sticky_entry && $sticky_entry->valid) {
+                $jumpid = $sticky_entry->ditemid;
+            }
+        }
+    } elsif ($opts->{'itemid'} && $opts->{'itemid'} != $sticky_id) {
+
+        $jumpid = get_itemid_near2( $u,
+                                    $itemid,
+                                     'after',
+                                     { 'skip_sticky' => $use_sticky } );
+        LJ::DelayedEntry::get_itemid_after2($u, 0);
+        if ( !$jumpid ) {
+            my $after_id = LJ::DelayedEntry::get_first_entry($u);
+            if ($after_id) {
+                $jumpid = 'd' . $after_id;
+            } elsif ($use_sticky && $sticky_id) {
+                my $sticky_entry = LJ::Entry->new( $u, jitemid => $sticky_id);
+                if ($sticky_entry && $sticky_entry->valid) {
+                    $jumpid = $sticky_entry->ditemid;
+                }
+            }
+        }
+    }
+    if (!$jumpid) {
+        return undef;
+    }
+    return $u->journal_base . "/$jumpid.html";
+}
+
+
+sub get_before_item_link {
+    my ($u, $opts) = @_;
+
+    my $jumpid;
+    my $sticky_id = $u->get_sticky_entry_id;
+    my $use_sticky = $opts->{'use_sticky'};
+    my $skip_sticky = { 'skip_sticky' => 1 };
+
+    my $itemid = $opts->{'itemid'};
+
+    if ($opts->{'delayedid'}) {
+        my $delayed_id = $opts->{'delayedid'};
+        my $prev_id = LJ::DelayedEntry::get_itemid_before2($u, $delayed_id);
+
+        # does delayed entry exists?
+        if ($prev_id) {
+            # append prefix to delayed entries
+            $jumpid = 'd' . $prev_id;
+        } else {
+            # select usual entry
+            $jumpid = get_latest_item( $u, $skip_sticky );
+        }
+    } elsif ($opts->{itemid}) {
+        my $item_id = $opts->{itemid};
+        if ( $use_sticky && ( $item_id == $sticky_id ) ) {
+            my $prev_id = LJ::DelayedEntry::get_last_entry($u);
+            if ($prev_id) {
+                $jumpid = 'd' . $prev_id;
+            } else {
+                $jumpid = get_latest_item( $u, $skip_sticky );
+            }
+        } else {
+            $jumpid = get_itemid_near2( $u,
+                                        $item_id,
+                                        'before',
+                                        $skip_sticky );
+        }
+
+    } else {
+        die "Error: item id is not set at all";
+    }
+
+    if (!$jumpid) {
+        return undef;
+    }
+    if (!$jumpid) {
+        return undef;
+    }
+    return $u->journal_base . "/$jumpid.html";
+}
+
+
+
 sub set_logprop {
     my ($u, $jitemid, $hashref, $logprops) = @_;  # hashref to set, hashref of what was done
 

Modified: branches/commenting-form/cgi-bin/LJ/S2/DayPage.pm
===================================================================
--- branches/commenting-form/cgi-bin/LJ/S2/DayPage.pm	2011-11-17 10:30:32 UTC (rev 20554)
+++ branches/commenting-form/cgi-bin/LJ/S2/DayPage.pm	2011-11-17 10:31:58 UTC (rev 20555)
@@ -95,6 +95,16 @@
     LJ::load_log_props2($dbcr, $u->{'userid'}, \@itemids, \%logprops);
     $logtext = LJ::get_logtext2($u, @itemids);
 
+    my @ditems = ();
+    if (LJ::is_enabled("delayed_entries")) {
+        @ditems = LJ::DelayedEntry->get_entries_for_day($u, $year, $month, $day, $dateformat, $secwhere);
+        foreach my $ditem (@ditems) {
+            if ($ditem) {
+                push @items, $ditem;
+            }
+        }
+    }
+
     my (%apu, %apu_lite);  # alt poster users; UserLite objects
     foreach (@items) {
         next unless $_->{'posterid'} != $u->{'userid'};
@@ -108,17 +118,6 @@
     # load tags
     my $tags = LJ::Tags::get_logtags($u, \@itemids);
     
-    my @ditems = ();
-    if (LJ::is_enabled("delayed_entries")) {
-        @ditems = LJ::DelayedEntry->get_entries_for_day($u, $year, $month, $day, $dateformat, $secwhere);
-
-        foreach my $ditem (@ditems) {
-            if ($ditem) {
-                push @items, $ditem;
-            }
-        }
-    }
-
     my $userlite_journal = UserLite($u);
 
   ENTRY:

Modified: branches/commenting-form/cgi-bin/LJ/S2.pm
===================================================================
--- branches/commenting-form/cgi-bin/LJ/S2.pm	2011-11-17 10:30:32 UTC (rev 20554)
+++ branches/commenting-form/cgi-bin/LJ/S2.pm	2011-11-17 10:31:58 UTC (rev 20555)
@@ -4025,16 +4025,18 @@
     }
 
     if ($key eq "nav_prev") {
-        my $jumpid;
+        my $options = { 'use_sticky' => 1,
+                        'itemid'     => int($this->{'itemid'}/256),
+                      };
+
         if ($entry->is_delayed) {
-            my $nextid = LJ::DelayedEntry::get_itemid_before2($journalu, $entry->delayedid);
-            return $null_link unless $nextid;
-            $jumpid = "d" . $nextid;
-        } else {
-            $jumpid = LJ::get_itemid_before2($journalu, int($this->{'itemid'}/256));
+            $options->{'delayedid'} = $entry->delayedid;
         }
-        if ($jumpid) {
-            return LJ::S2::Link($journalu->journal_base . "/$jumpid.html",
+
+        my $jumplink = LJ::get_before_item_link($journalu, $options);
+
+        if ($jumplink) {
+            return LJ::S2::Link($jumplink,
                             $ctx->[S2::PROPS]->{"text_entry_prev"},
                             LJ::S2::Image("$LJ::IMGPREFIX/btn_prev.gif", 24, 24));
         } else {
@@ -4043,17 +4045,18 @@
     }
 
     if ($key eq "nav_next") {
-        my $jumpid;
+        my $options = { 'use_sticky' => 1,
+                        'itemid'     => int($this->{'itemid'}/256),
+                      };
+
         if ($entry->is_delayed) {
-            my $nextid = LJ::DelayedEntry::get_itemid_after2($journalu, $entry->delayedid);
-            return $null_link unless $nextid;
-            $jumpid = "d" . $nextid;
-        } else {
-            $jumpid = LJ::get_itemid_after2($journalu, int($this->{'itemid'}/256));
+            $options->{'delayedid'} = $entry->delayedid;
         }
-        
-        if ($jumpid) {
-            return LJ::S2::Link($journalu->journal_base . "/$jumpid.html",,
+
+        my $jumplink = LJ::get_after_item_link($journalu, $options);
+
+        if ($jumplink) {
+            return LJ::S2::Link($jumplink,
                             $ctx->[S2::PROPS]->{"text_entry_next"},
                             LJ::S2::Image("$LJ::IMGPREFIX/btn_next.gif", 24, 24));
         } else {

Modified: branches/commenting-form/cgi-bin/LJ/Session.pm
===================================================================
--- branches/commenting-form/cgi-bin/LJ/Session.pm	2011-11-17 10:30:32 UTC (rev 20554)
+++ branches/commenting-form/cgi-bin/LJ/Session.pm	2011-11-17 10:31:58 UTC (rev 20555)
@@ -591,7 +591,7 @@
     my $domain_cookie = LJ::Session->domain_cookie;
 
     # foreign domain case
-    unless ( $host =~ /\.$LJ::DOMAIN(:\d+)?$/ ) {
+    unless ( $host =~ /(^|\.)$LJ::DOMAIN(:\d+)?$/ ) {
         return LJ::Session->session_from_external_cookie(\%getopts, @{ $BML::COOKIE{"$domain_cookie\[\]"} || [] });
     }
 

Modified: branches/commenting-form/cgi-bin/LJ/Talk.pm
===================================================================
--- branches/commenting-form/cgi-bin/LJ/Talk.pm	2011-11-17 10:30:32 UTC (rev 20554)
+++ branches/commenting-form/cgi-bin/LJ/Talk.pm	2011-11-17 10:31:58 UTC (rev 20555)
@@ -128,11 +128,12 @@
         $entry = LJ::Entry->new($u, ditemid => $itemid);
     }
 
+    my $itemlnk = $entry->is_delayed ? "delayedid=" . $opts->{delayedid} :
+                                       "itemid=$itemid";
+
     # << Previous
-    if (!$entry->is_delayed) {
-        push @linkele, $mlink->("$LJ::SITEROOT/go.bml?${jargent}itemid=$itemid&amp;dir=prev", "prev_entry");
-        $$headref .= "<link href='$LJ::SITEROOT/go.bml?${jargent}itemid=$itemid&amp;dir=prev' rel='Previous' />\n";
-    }
+    push @linkele, $mlink->("$LJ::SITEROOT/go.bml?${jargent}$itemlnk&amp;dir=prev", "prev_entry");
+    $$headref .= "<link href='$LJ::SITEROOT/go.bml?${jargent}$itemlnk&amp;dir=prev' rel='Previous' />\n";
 
     # memories
     unless ($LJ::DISABLED{'memories'} || $entry->is_delayed) {
@@ -181,11 +182,8 @@
     }
 
     ## Next
-    if (!$entry->is_delayed)
-    {
-        push @linkele, $mlink->("$LJ::SITEROOT/go.bml?${jargent}itemid=$itemid&amp;dir=next", "next_entry");
-        $$headref .= "<link href='$LJ::SITEROOT/go.bml?${jargent}itemid=$itemid&amp;dir=next' rel='Next' />\n";
-    }
+    push @linkele, $mlink->("$LJ::SITEROOT/go.bml?${jargent}$itemlnk&amp;dir=next", "next_entry");
+    $$headref .= "<link href='$LJ::SITEROOT/go.bml?${jargent}$itemlnk&amp;dir=next' rel='Next' />\n";
 
     if (@linkele) {
         $ret .= BML::fill_template("standout", {
@@ -2126,6 +2124,9 @@
     $controller->_user(LJ::get_remote());
     my $res = $controller->reply(\@opts);
 
+    return $res->output
+        if ref($res) eq 'LJ::Mob::Response::AuthRequired';
+
     # passing error messages
     $res->template->param(
         errors          => [map { { 'error' => $_ } } @{ $opts->{errors} }],

Modified: branches/commenting-form/htdocs/community/members.bml
===================================================================
--- branches/commenting-form/htdocs/community/members.bml	2011-11-17 10:30:32 UTC (rev 20554)
+++ branches/commenting-form/htdocs/community/members.bml	2011-11-17 10:31:58 UTC (rev 20555)
@@ -449,8 +449,6 @@
                             siteroot        => $LJ::SITEROOT,
                         });
 
-            }
-
             my $subject = LJ::Lang::get_text($lang, 'community.members.maintainer.remove.email_subject', undef,
                             { mailusercname => $mailusercname }
                             );

Modified: branches/commenting-form/htdocs/delcomment.bml
===================================================================
--- branches/commenting-form/htdocs/delcomment.bml	2011-11-17 10:30:32 UTC (rev 20554)
+++ branches/commenting-form/htdocs/delcomment.bml	2011-11-17 10:31:58 UTC (rev 20555)
@@ -10,9 +10,18 @@
     # because this BML may be called as __rpc_delcomment too
     BML::set_language_scope('/delcomment.bml');
 
+    my $check_form_auth;
     my $mode = LJ::Request->get_param('mode') || 'html';
-    $mode = 'html' unless $mode =~ /^(?:html|js|jsonp)$/;
+    $mode = 'html' unless $mode =~ /^(?:html|js|jsonp|json)$/;
 
+    if ( LJ::is_enabled('new_comments') ) {
+        my $format = $GET{'format'} || $POST{'format'};
+        $check_form_auth = 1;
+        if ( $format eq 'json' ) {
+            $mode = 'json';
+        }
+    }
+
     # helper subroutines
 
     my $site_scheme_wrap = sub {
@@ -49,9 +58,24 @@
                 'success'   => 0,
                 'error'     => $why,
             });
+        } elsif ( $mode eq 'json' ) {
+            BML::finish();
+            return LJ::JSON->to_json({
+                status  => 'error',
+                message => $why,
+            });
         }
     };
 
+    my $ok = sub {
+        if ( $mode eq 'json' ) {
+            BML::finish();
+            return LJ::JSON->to_json({
+                status  => 'ok',
+            });
+        }
+    };
+
     my $bad_input = sub {
         my ($why) = @_;
 
@@ -96,10 +120,10 @@
 
     if ( LJ::Request->did_post && LJ::Request->post_param('confirm') ) {
         return $error->( LJ::Lang::ml('error.invalidform') )
-            unless LJ::check_form_auth();
+            if $check_form_auth and not LJ::check_form_auth();
 
         $method = 'delete';
-    } elsif ( $mode eq 'jsonp' && LJ::Request->get_param('confirm') ) {
+    } elsif ( $mode =~ m!jsonp! && LJ::Request->get_param('confirm') ) {
         my %vars = (
             'auth_token' => LJ::Request->get_param('auth_token'),
             'journal'    => $journal->username,
@@ -300,6 +324,8 @@
             return "1;";
         } elsif ( $mode eq 'jsonp' ) {
             return $jsonp_wrap->({ 'success' => 1 });
+        } elsif ( $mode eq 'json' ) {
+            return $ok->();
         }
     }
 _code?>

Modified: branches/commenting-form/htdocs/go.bml
===================================================================
--- branches/commenting-form/htdocs/go.bml	2011-11-17 10:30:32 UTC (rev 20554)
+++ branches/commenting-form/htdocs/go.bml	2011-11-17 10:31:58 UTC (rev 20555)
@@ -22,7 +22,8 @@
 
  # prev/next talkread links
  my $itemid = $GET{'itemid'}+0;
- if ($GET{'journal'} && $itemid) 
+ my $delayedid = $GET{'delayedid'}+0;
+ if ($GET{'journal'} && ($itemid || $delayedid))  
  {
      my $journal = $GET{'journal'};
      my $u = LJ::load_user($journal);
@@ -36,19 +37,24 @@
 
      $itemid = int($itemid / 256);
      
-     my $jumpid = 0;
+     my $jumplink;
      $title = $ML{'.error.noentrytitle'};
+
+     my $options = { 'itemid'     => $itemid,
+                     'delayedid'  => $delayedid,
+                     'use_sticky' => 1 };
      
      if ($GET{'dir'} eq "next") {
-         $jumpid = LJ::get_itemid_after2($u, $itemid);
+         warn "itemid = " . LJ::get_itemid_after2($u, $itemid);
+         $jumplink = LJ::get_after_item_link($u, $options);
          $body = $ML{'.error.noentry.next'};
      } elsif ($GET{'dir'} eq "prev") {
-         $jumpid = LJ::get_itemid_before2($u, $itemid);
+         $jumplink = LJ::get_before_item_link($u, $options);
          $body = $ML{'.error.noentry.prev'};
      }
 
-     if ($jumpid) {
-         return BML::redirect(LJ::journal_base($u) . "/$jumpid.html");
+     if ($jumplink) {
+         return BML::redirect($jumplink);
      }
  }
 

Modified: branches/commenting-form/htdocs/js/ck/contents.css
===================================================================
--- branches/commenting-form/htdocs/js/ck/contents.css	2011-11-17 10:30:32 UTC (rev 20554)
+++ branches/commenting-form/htdocs/js/ck/contents.css	2011-11-17 10:31:58 UTC (rev 20555)
@@ -4,6 +4,12 @@
 */
 @namespace lj "livejournal";
 
+/*
+Achtung!
+Some styles can be found in stc/lj/ck/plugins/livejournal/plugin.js
+It is for ultra sonic loading of style. Styles from plugin.js moved to [style][/style], and loads before [link rel="stylesheet"/]
+*/
+
 BODY {
 	position: relative;
 	font: 13px/18px 'Arial', sans-serif;
@@ -22,13 +28,13 @@
 }
 
 /* LJ CSS */
-.lj\:template {
+lj\:template {
 	background-color: #000;
 	color: #fff;
 	display: none;
 }
 
-.lj|template {
+lj|template {
 	background-color: #000;
 	color: #fff;
 	display: none;

Copied: branches/commenting-form/htdocs/js/ck/images/ljcut.png (from rev 20553, trunk/htdocs/js/ck/images/ljcut.png)
===================================================================
(Binary files differ)

Modified: branches/commenting-form/htdocs/js/ck/plugins/livejournal/plugin.js
===================================================================
--- branches/commenting-form/htdocs/js/ck/plugins/livejournal/plugin.js	2011-11-17 10:30:32 UTC (rev 20554)
+++ branches/commenting-form/htdocs/js/ck/plugins/livejournal/plugin.js	2011-11-17 10:31:58 UTC (rev 20555)
@@ -1,22 +1,19 @@
-(function(){
+(function() {
 	var dtd = CKEDITOR.dtd;
 
-	dtd.$block['lj:template'] = 1;
-	dtd.$block['lj:raw'] = 1;
-	dtd.$block['lj:cut'] = 1;
-
-	CKEDITOR.tools.extend(dtd.div, dtd.$block);
-	CKEDITOR.tools.extend(dtd.$body, dtd.$block);
-	dtd.$nonEditable['lj:template'] = 1;
-
-	dtd['lj:template'] = {};
-	dtd['lj:raw'] = dtd.div;
-	dtd['lj:cut'] = dtd.div;
-
+	dtd.$block['lj-template'] = 1;
+	dtd.$block['lj-raw'] = 1;
+	dtd.$block['lj-cut'] = 1;
 	dtd.$block['lj-poll'] = 1;
 	dtd.$block['lj-pq'] = 1;
 	dtd.$block['lj-pi'] = 1;
+	dtd.$nonEditable['lj-template'] = 1;
 
+	dtd['lj-template'] = {};
+	dtd['lj-map'] = {};
+	dtd['lj-raw'] = dtd.div;
+	dtd['lj-cut'] = dtd.div;
+
 	dtd['lj-poll'] = {
 		'lj-pq': 1
 	};
@@ -33,6 +30,11 @@
 	dtd.$block.iframe = dtd.$inline.iframe;
 	delete dtd.$inline.iframe;
 
+	CKEDITOR.tools.extend(dtd.div, dtd.$block);
+	CKEDITOR.tools.extend(dtd.$body, dtd.$block);
+
+	delete dtd['lj-cut']['lj-cut'];
+
 	var likeButtons = [
 		{
 			label: top.CKLang.LJLike_button_facebook,
@@ -95,7 +97,7 @@
 	var ljUsers = {};
 	var execFromEditor;
 
-	function createNote(editor){
+	function createNote(editor) {
 		var timer,
 			state,
 			currentData,
@@ -103,7 +105,7 @@
 			noteNode = document.createElement('lj-note'),
 			isIE = typeof(document.body.style.opacity) != 'string';
 
-		var animate = (function(){
+		var animate = (function() {
 			var fps = 60,
 				totalTime = 100,
 				steps = totalTime * fps / 1000,
@@ -111,36 +113,36 @@
 				type,
 				parentContainer = document.getElementById('draft-container') || document.body;
 
-			function apply(){
+			function apply() {
 				var data = timeOuts.shift();
 				var currentStep = (type ? data.time / totalTime : -(data.time / totalTime - 1)).toFixed(1);
 
-				if(!timeOuts.length){
+				if (!timeOuts.length) {
 					currentStep = type ? 1 : 0;
 				}
 
-				if(isIE){
+				if (isIE) {
 					noteNode.style.filter = (currentStep >= 1) ? null : 'progid:DXImageTransform.Microsoft.Alpha(opacity=' + (currentStep * 100) + ')';
 				} else {
 					noteNode.style.opacity = currentStep;
 				}
 
-				if(currentStep == 0 && noteNode && noteNode.parentNode){
+				if (currentStep == 0 && noteNode && noteNode.parentNode) {
 					noteNode.parentNode.removeChild(noteNode);
 				}
 			}
 
-			return function(animateType){
+			return function(animateType) {
 				type = animateType;
 
-				if(type && noteNode.parentNode){
-					if(isIE){
+				if (type && noteNode.parentNode) {
+					if (isIE) {
 						noteNode.style.filter = null;
 					} else {
 						noteNode.style.opacity = 1;
 					}
 				} else {
-					for(var i = 1; i <= steps; i++){
+					for (var i = 1; i <= steps; i++) {
 						var time = Math.floor(1000 / fps) * i;
 						timeOuts.push({
 							time: time,
@@ -157,29 +159,29 @@
 
 		noteNode.className = 'note-popup';
 
-		noteNode.onmouseout = function(){
-			if(!currentData || !currentData.cmd){
+		noteNode.onmouseout = function() {
+			if (!currentData || !currentData.cmd) {
 				CKEDITOR.note.hide();
 			}
 		};
 
-		noteNode.onmouseover = function(){
-			if(timer && !state){
+		noteNode.onmouseover = function() {
+			if (timer && !state) {
 				state = 1;
 				clearTimeout(timer);
 				timer = null;
 			}
 		};
 
-		if(isIE){
+		if (isIE) {
 			noteNode.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity=0)';
 		} else {
 			noteNode.style.opacity = 0;
 		}
 
-		function callCmd(){
+		function callCmd() {
 			var cmd = this.getAttribute('lj-cmd');
-			if(currentData.hasOwnProperty(cmd)){
+			if (currentData.hasOwnProperty(cmd)) {
 				ljTagsData[cmd].node = currentData[cmd].node;
 				var selection = new CKEDITOR.dom.selection(editor.document);
 				selection.selectElement(ljTagsData[cmd].node);
@@ -190,17 +192,17 @@
 			return false;
 		}
 
-		function applyNote(){
-			if(!window.switchedRteOn){
+		function applyNote() {
+			if (!window.switchedRteOn) {
 				CKEDITOR.note.hide(true);
 			}
-			if(state){
+			if (state) {
 				currentData = tempData;
 				tempData = null;
 
 				var html = '';
-				for(var cmd in currentData){
-					if(currentData.hasOwnProperty(cmd)){
+				for (var cmd in currentData) {
+					if (currentData.hasOwnProperty(cmd)) {
 						html += '<div class="noteItem">' + currentData[cmd].content + '</div>';
 					}
 				}
@@ -208,9 +210,9 @@
 				noteNode.innerHTML = decodeURIComponent(html);
 
 				var links = noteNode.getElementsByTagName('a');
-				for(var i = 0, l = links.length; i < l; i++){
+				for (var i = 0, l = links.length; i < l; i++) {
 					var link = links[i];
-					if(ljTagsData.hasOwnProperty(link.getAttribute('lj-cmd'))){
+					if (ljTagsData.hasOwnProperty(link.getAttribute('lj-cmd'))) {
 						link.onclick = callCmd;
 					}
 				}
@@ -224,12 +226,12 @@
 		}
 
 		CKEDITOR.note = {
-			show: function(data, isNow){
-				if((!isNow && data == tempData) || window.swi){
+			show: function(data, isNow) {
+				if ((!isNow && data == tempData) || window.swi) {
 					return;
 				}
 
-				if(timer){
+				if (timer) {
 					clearTimeout(timer);
 					timer = null;
 				}
@@ -240,16 +242,16 @@
 
 				isNow === true ? applyNote() : timer = setTimeout(applyNote, 1000);
 			},
-			hide: function(isNow){
-				if(state){
+			hide: function(isNow) {
+				if (state) {
 					state = 0;
 
-					if(timer){
+					if (timer) {
 						clearTimeout(timer);
 						timer = null;
 					}
 
-					if(noteNode.parentNode){
+					if (noteNode.parentNode) {
 						isNow === true ? applyNote() : timer = setTimeout(applyNote, 500);
 					}
 				}
@@ -258,50 +260,49 @@
 	}
 
 	CKEDITOR.plugins.add('livejournal', {
-		init: function(editor){
-			editor.addCss('.lj_selected {' + 'background-color: #C4E0F7 !important;' + 'border: 1px solid #6EA9DF !important;' + '}');
-
-			function onClickFrame(evt){
-				if(this.$ != editor.document.$){
-					new CKEDITOR.dom.selection(editor.document).selectElement(this.frameElement);
+		init: function(editor) {
+			function onClickFrame(evt) {
+				if (this.$ != editor.document.$) {
+					this.frame.addClass('lj-selected');
+					new CKEDITOR.dom.selection(editor.document).selectElement(this.frame);
 				}
 
 				evt.data.getKey() == 1 && evt.data.preventDefault();
 			}
 
-			function onKeyUp(evt){
-				if(evt.data.getKey() == 46){
+			function onKeyUp(evt) {
+				if (evt.data.getKey() == 46) {
 					var ranges = new CKEDITOR.dom.selection(editor.document).getRanges();
 					var length = ranges.length;
-					while(length--){
+					while (length--) {
 						ranges[length].deleteContents();
 					}
 				}
 			}
 
-			function onLoadFrame(){
+			function onLoadFrame() {
 				var win = this.$.contentWindow;
 				var doc = win.document;
-				if(win.frameElement.getAttribute('lj-cmd') && doc.body.scrollHeight){
+				if (this.getAttribute('lj-cmd') && doc.body.scrollHeight) {
 					this.setStyle('height', doc.body.scrollHeight + 'px');
 				}
 
 				var body = new CKEDITOR.dom.element.get(doc.body);
 				body.on('dblclick', onDoubleClick);
 				body.on('click', onClickFrame);
+				body.on('keyup', onKeyUp);
 
 				doc = new CKEDITOR.dom.element.get(doc);
-				doc.on('keyup', onKeyUp);
 
-				doc.frameElement = body.frameElement = this;
+				doc.frame = body.frame = this;
 			}
 
-			function updateFrames(){
+			function updateFrames() {
 				execFromEditor = false;
 				var frames = editor.document.getElementsByTag('iframe');
 				var length = frames.count();
 
-				while(length--){
+				while (length--) {
 					var iFrameCss = 'widht: 100%; margin: 0; padding 0; overflow-y: hidden;',
 						frame = frames.getItem(length),
 						cmd = frame.getAttribute('lj-cmd'),
@@ -309,7 +310,7 @@
 						doc = frameWin.document,
 						ljStyle = frame.getAttribute('lj-style');
 
-					if(ljStyle){
+					if (ljStyle) {
 						iFrameCss += ljStyle;
 					}
 
@@ -321,50 +322,55 @@
 				}
 			}
 
-			function findLJTags(evt){
+			function findLJTags(evt) {
 				var noteData,
 					isSelection = evt.name == 'selectionChange' || evt.name == 'click',
 					target = evt.data.element || evt.data.getTarget(),
 					node,
 					command;
 
-				if(evt.name == 'click' && (evt.data.getKey() == 1 || evt.data.$.button == 0)){
+				if (editor.onSwitch === true) {
+					delete editor.onSwitch;
+					return;
+				}
+
+				if (evt.name == 'click' && (evt.data.getKey() == 1 || evt.data.$.button == 0)) {
 					evt.data.preventDefault();
 				}
 
-				if(target.type != 1){
+				if (target.type != 1) {
 					target = target.getParent();
 				}
 
 				node = target;
 
-				if(isSelection){
+				if (isSelection) {
 					var frames = editor.document.getElementsByTag('iframe');
-					for(var i = 0, l = frames.count(); i < l; i++){
-						frames.getItem(i).removeClass('lj_selected');
+					for (var i = 0, l = frames.count(); i < l; i++) {
+						frames.getItem(i).removeClass('lj-selected');
 					}
 
-					if(node.is('iframe')){
-						node.addClass('lj_selected');
+					if (node.is('iframe')) {
+						node.addClass('lj-selected');
 					}
 				}
 
 				do {
 					var attr = node.getAttribute('lj-cmd');
 
-					if(!attr && node.type == 1){
+					if (!attr && node.type == 1) {
 						var parent = node.getParent();
-						if(node.is('img') && parent.getParent() && !parent.getParent().hasAttribute('lj:user')){
+						if (node.is('img') && parent.getParent() && !parent.getParent().hasAttribute('lj:user')) {
 							attr = 'image';
 							node.setAttribute('lj-cmd', attr);
-						} else if(node.is('a') && !parent.hasAttribute('lj:user')){
+						} else if (node.is('a') && !parent.hasAttribute('lj:user')) {
 							attr = 'LJLink';
 							node.setAttribute('lj-cmd', attr);
 						}
 					}
 
-					if(attr && ljTagsData.hasOwnProperty(attr)){
-						if(isSelection){
+					if (attr && ljTagsData.hasOwnProperty(attr)) {
+						if (isSelection) {
 							ljTagsData[attr].node = node;
 							editor.getCommand(attr).setState(CKEDITOR.TRISTATE_ON);
 						}
@@ -373,11 +379,11 @@
 							node: node
 						};
 					}
-				} while(node = node.getParent());
+				} while (node = node.getParent());
 
-				if(isSelection){
-					for(command in ljTagsData){
-						if(ljTagsData.hasOwnProperty(command) && (!noteData || !noteData.hasOwnProperty(command))){
+				if (isSelection) {
+					for (command in ljTagsData) {
+						if (ljTagsData.hasOwnProperty(command) && (!noteData || !noteData.hasOwnProperty(command))) {
 							delete ljTagsData[command].node;
 							editor.getCommand(command).setState(CKEDITOR.TRISTATE_OFF);
 						}
@@ -387,33 +393,33 @@
 				noteData ? CKEDITOR.note.show(noteData) : CKEDITOR.note.hide();
 			}
 
-			editor.dataProcessor.toHtml = function(html, fixForBody){
+			editor.dataProcessor.toHtml = function(html, fixForBody) {
 				html = html.replace(/(<lj [^>]+)(?!\/)>/gi, '$1 />').replace(/(<lj-map[^>]+)(?!\/)>/gi, '$1 />').replace(/(<lj-template[^>]*)(?!\/)>/gi, '$1 />').replace(/<((?!br)[^\s>]+)([^>]*?)\/>/gi, '<$1$2></$1>').replace(/<lj-poll.*?>[\s\S]*?<\/lj-poll>/gi,
-					function(ljtags){
+					function(ljtags) {
 						var poll = new Poll(ljtags);
 						return '<iframe class="lj-poll" frameborder="0" allowTransparency="true" ' + 'lj-cmd="LJPollLink" lj-data="' + poll.outputLJtags() + '" lj-content="' + poll.outputHTML() + '"></iframe>';
-					}).replace(/<lj-embed(.*?)>([\s\S]*?)<\/lj-embed>/gi, function(result, attrs, data){
-						return '<iframe' + attrs + ' class="lj-embed" lj-style="height: 100%;" lj-data="' + encodeURIComponent(data) + '" frameborder="0" allowTransparency="true"></iframe>';
+					}).replace(/<lj-embed(.*?)>([\s\S]*?)<\/lj-embed>/gi, function(result, attrs, data) {
+						return '<iframe' + attrs + ' class="lj-embed" lj-data="' + encodeURIComponent(data) + '" frameborder="0" allowTransparency="true"></iframe>';
 					});
 
-				if(!$('event_format').checked){
+				if (!$('event_format').checked) {
 					html = html.replace(/(<lj-raw.*?>)([\s\S]*?)(<\/lj-raw>)/gi,
-						function(result, open, content, close){
+						function(result, open, content, close) {
 							return open + content.replace(/\n/g, '') + close;
 						}).replace(/\n/g, '<br />');
 				}
 
 				html = CKEDITOR.htmlDataProcessor.prototype.toHtml.call(this, html, fixForBody);
-				if(CKEDITOR.env.ie){
+				if (CKEDITOR.env.ie) {
 					html = '<xml:namespace ns="livejournal" prefix="lj" />' + html;
 				}
 				return html;
 			};
 
-			editor.dataProcessor.toDataFormat = function(html, fixForBody){
+			editor.dataProcessor.toDataFormat = function(html, fixForBody) {
 				html = CKEDITOR.htmlDataProcessor.prototype.toDataFormat.call(this, html, fixForBody);
 
-				if(!$('event_format').checked){
+				if (!$('event_format').checked) {
 					html = html.replace(/<br\s*\/>/gi, '\n');
 				}
 
@@ -425,20 +431,20 @@
 			editor.dataProcessor.writer.indentationChars = '';
 			editor.dataProcessor.writer.lineBreakChars = '';
 
-			function onDoubleClick(evt){
+			function onDoubleClick(evt) {
 				var node = evt.data.element || evt.data.getTarget();
 
-				if(node.type != 1){
+				if (node.type != 1) {
 					node = node.getParent();
 				}
 
-				while(node){
+				while (node) {
 					var cmdName = node.getAttribute('lj-cmd');
-					if(ljTagsData.hasOwnProperty(cmdName)){
+					if (ljTagsData.hasOwnProperty(cmdName)) {
 						var cmd = editor.getCommand(cmdName);
-						if(cmd.state == CKEDITOR.TRISTATE_ON){
+						if (cmd.state == CKEDITOR.TRISTATE_ON) {
 							var selection = new CKEDITOR.dom.selection(editor.document);
-							ljTagsData[cmdName].node = node.is('body') ? new CKEDITOR.dom.element.get(node.getWindow().$.frameElement) : node;
+							ljTagsData[cmdName].node = node.is('body') ? new CKEDITOR.dom.element.get(node.getWindow().$.frame) : node;
 							selection.selectElement(ljTagsData[cmdName].node);
 							evt.data.dialog = '';
 							execFromEditor = true;
@@ -453,7 +459,7 @@
 
 			var styleSheet = '';
 
-			CKEDITOR.ajax.load(editor.config.contentsCss, function(data){
+			CKEDITOR.ajax.load(editor.config.contentsCss, function(data) {
 				styleSheet = data;
 			});
 
@@ -461,15 +467,15 @@
 			editor.on('doubleclick', onDoubleClick);
 			editor.on('afterCommandExec', updateFrames);
 			editor.on('dialogHide', updateFrames);
-			editor.on('dataReady', function(){
-				if(!CKEDITOR.note){
+			editor.on('dataReady', function() {
+				if (!CKEDITOR.note) {
 					createNote(editor);
 				}
 
 				editor.document.on('click', findLJTags);
 				editor.document.on('mouseout', CKEDITOR.note.hide);
 				editor.document.on('mouseover', findLJTags);
-				editor.document.on('keyup', onKeyUp);
+				editor.document.getBody().on('keyup', onKeyUp);
 				updateFrames();
 			});
 
@@ -477,25 +483,25 @@
 			var url = top.Site.siteroot + '/tools/endpoints/ljuser.bml';
 
 			editor.addCommand('LJUserLink', {
-				exec: function(editor){
+				exec: function(editor) {
 					var userName = '',
 						selection = new CKEDITOR.dom.selection(editor.document),
 						LJUser = ljTagsData.LJUserLink.node,
 						currentUserName;
 
-					if(LJUser){
+					if (LJUser) {
 						CKEDITOR.note && CKEDITOR.note.hide(true);
 						currentUserName = ljTagsData.LJUserLink.node.getElementsByTag('b').getItem(0).getText();
 						userName = prompt(top.CKLang.UserPrompt, currentUserName);
-					} else if(selection.getType() == 2){
+					} else if (selection.getType() == 2) {
 						userName = selection.getSelectedText();
 					}
 
-					if(userName == ''){
+					if (userName == '') {
 						userName = prompt(top.CKLang.UserPrompt, userName);
 					}
 
-					if(!userName || currentUserName == userName){
+					if (!userName || currentUserName == userName) {
 						return;
 					}
 
@@ -505,12 +511,12 @@
 						}),
 						method: 'POST',
 						url: url,
-						onData: function(data){
-							if(data.error){
+						onData: function(data) {
+							if (data.error) {
 								alert(data.error);
 								return;
 							}
-							if(!data.success){
+							if (!data.success) {
 								return;
 							}
 							data.ljuser = data.ljuser.replace('<span class="useralias-value">*</span>', '');
@@ -520,7 +526,7 @@
 							var tmpNode = new CKEDITOR.dom.element.createFromHtml(data.ljuser);
 							tmpNode.setAttribute('lj-cmd', 'LJUserLink');
 
-							if(LJUser){
+							if (LJUser) {
 								LJUser.$.parentNode.replaceChild(tmpNode.$, LJUser.$);
 							} else {
 								editor.insertElement(tmpNode);
@@ -541,14 +547,14 @@
 				command: 'image'
 			});
 
-			if(window.ljphotoEnabled){
+			if (window.ljphotoEnabled) {
 				editor.addCommand('LJImage_beta', {
-					exec: function(editor){
+					exec: function(editor) {
 						jQuery('#updateForm').photouploader({
 							type: 'upload'
-						}).photouploader('show').bind('htmlready', function (event){
+						}).photouploader('show').bind('htmlready', function (event) {
 								var html = event.htmlStrings;
-								for(var i = 0, l = html.length; i < l; i++){
+								for (var i = 0, l = html.length; i < l; i++) {
 									editor.insertElement(new CKEDITOR.dom.element.createFromHtml(html[i], editor.document));
 								}
 							});
@@ -564,7 +570,7 @@
 
 			//////////  LJ Link Button //////////////
 			editor.addCommand('LJLink', {
-				exec: function(editor){
+				exec: function(editor) {
 					!execFromEditor && this.state == CKEDITOR.TRISTATE_ON ? editor.execCommand('unlink') : editor.openDialog('link');
 					CKEDITOR.note && CKEDITOR.note.hide(true);
 				},
@@ -578,7 +584,7 @@
 
 			//////////  LJ Embed Media Button //////////////
 			editor.addCommand('LJEmbedLink', {
-				exec: function(){
+				exec: function() {
 					top.LJ_IPPU.textPrompt(top.CKLang.LJEmbedPromptTitle, top.CKLang.LJEmbedPrompt, doEmbed, {
 						width: '350px'
 					});
@@ -592,12 +598,11 @@
 
 			editor.addCss('.lj-embed {' + 'background: #CCCCCC url(' + CKEDITOR.getUrl(this.path + 'images/placeholder_flash.png') + ') no-repeat center center;' + 'border: 1px dotted #000000;' + 'height: 80px;' + 'width: 100%;' + '}');
 
-			function doEmbed(content){
-				if(content && content.length){
-					if(window.switchedRteOn){
+			function doEmbed(content) {
+				if (content && content.length) {
+					if (window.switchedRteOn) {
 						var iframe = new CKEDITOR.dom.element('iframe', editor.document);
 						iframe.setAttribute('lj-data', encodeURIComponent(content));
-						iframe.setAttribute('lj-style', 'height: 100%;');
 						iframe.setAttribute('class', 'lj-embed');
 						iframe.setAttribute('frameBorder', 0);
 						iframe.setAttribute('allowTransparency', 'true');
@@ -608,43 +613,80 @@
 			}
 
 			//////////  LJ Cut Button //////////////
+			editor.addCss('.lj-cut {\
+				margin: 5px 0;\
+				width: 100%;\
+				cursor: pointer;\
+				height: 9px!important;\
+				background-color: #FFF;\
+				border: 0 dashed #BCBCBC;\
+				background: url(/js/ck/images/ljcut.png) no-repeat 0 0;\
+			}');
+			editor.addCss('.lj-cut-open {\
+				background-position: 0 2px;\
+				border-width: 0 0 1px;\
+			}');
+			editor.addCss('.lj-cut-close {\
+				border-width: 1px 0 0;\
+				background-position: 0 -8px;\
+			}');
+			editor.addCss('.lj-selected {\
+				background-color: #C4E0F7;\
+				border: 1px solid #6EA9DF;\
+			}');
+
+
 			editor.addCommand('LJCut', {
-				exec: function(){
+				exec: function() {
 					var text,
 						ljCutNode = ljTagsData.LJCut.node;
 
-					if(ljCutNode){
-						if(text = prompt(top.CKLang.CutPrompt, ljCutNode.getAttribute('text') || top.CKLang.ReadMore)){
-							if(text == top.CKLang.ReadMore){
+					if (ljCutNode) {
+						if (text = prompt(top.CKLang.CutPrompt, ljCutNode.getAttribute('text') || top.CKLang.ReadMore)) {
+							if (text == top.CKLang.ReadMore) {
 								ljCutNode.removeAttribute('text');
 							} else {
 								ljCutNode.setAttribute('text', text);
 							}
 						}
 					} else {
-						if(text = prompt(top.CKLang.CutPrompt, top.CKLang.ReadMore)){
-							var selection = new CKEDITOR.dom.selection(editor.document);
+						if (text = prompt(top.CKLang.CutPrompt, top.CKLang.ReadMore)) {
+							var selection = new CKEDITOR.dom.selection(editor.document),
+								ranges = selection.getRanges(),
+								startContainer,
+								iframeOpen = new CKEDITOR.dom.element('iframe', editor.document),
+								iframeClose = new CKEDITOR.dom.element('iframe', editor.document);
 
-							ljTagsData.LJCut.node = new CKEDITOR.dom.element.get(document.createElement('lj:cut'));
-							ljTagsData.LJCut.node.setAttribute('lj-cmd', 'LJCut');
-
-							if(text != top.CKLang.ReadMore){
-								ljTagsData.LJCut.node.setAttribute('text', text);
+							iframeOpen.setAttribute('lj-cmd', 'LJCut');
+							iframeOpen.addClass('lj-cut lj-cut-open');
+							iframeOpen.setAttribute('frameBorder', 0);
+							iframeOpen.setAttribute('allowTransparency', 'true');
+							if (text != top.CKLang.ReadMore) {
+								iframeOpen.setAttribute('text', text);
 							}
 
-							var ranges = selection.getRanges();
-							selection.lock();
-							for(var i = 0, l = ranges.length; i < l; i++){
-								var range = ranges[i];
-								range.cloneContents().appendTo(ljTagsData.LJCut.node);
+							iframeClose.addClass('lj-cut lj-cut-close');
+							iframeClose.setAttribute('frameBorder', 0);
+							iframeClose.setAttribute('allowTransparency', 'true');
+
+							if(ranges[0].collapsed === true){
+								editor.insertElement(iframeClose);
+								iframeClose.insertBeforeMe(iframeOpen);
+							} else {
+								startContainer = ranges[0].getTouchedStartNode();
+
+								var fragment = new CKEDITOR.dom.documentFragment(editor.document);
+								fragment.append(iframeOpen);
+								for (var i = 0, l = ranges.length; i < l; i++) {
+									fragment.append(ranges[i].extractContents());
+								}
+								editor.insertElement(iframeClose);
+								iframeClose.insertBeforeMe(fragment);
 							}
-							selection.unlock();
-							editor.insertElement(ljTagsData.LJCut.node);
-							selection.selectElement(ljTagsData.LJCut.node);
 						}
+
+						CKEDITOR.note && CKEDITOR.note.hide(true);
 					}
-
-					CKEDITOR.note && CKEDITOR.note.hide(true);
 				},
 				editorFocus: false
 			});
@@ -655,21 +697,21 @@
 			});
 
 			//////////  LJ Justify //////////////
-			(function(){
-				function getAlignment(element, useComputedState){
+			(function() {
+				function getAlignment(element, useComputedState) {
 					useComputedState = useComputedState === undefined || useComputedState;
 
 					var align,
 						LJLike = ljTagsData.LJLike.node;
-					if(LJLike){
+					if (LJLike) {
 						var attr = element.getAttribute('lj-style');
 						align = attr ? attr.replace(/text-align:\s*(left|right|center)/i, '$1') : 'left';
-					} else if(useComputedState){
+					} else if (useComputedState) {
 						align = element.getComputedStyle('text-align');
 					} else {
-						while(!element.hasAttribute || !( element.hasAttribute('align') || element.getStyle('text-align') )){
+						while (!element.hasAttribute || !( element.hasAttribute('align') || element.getStyle('text-align') )) {
 							var parent = element.getParent();
-							if(!parent){
+							if (!parent) {
 								break;
 							}
 							element = parent;
@@ -684,17 +726,17 @@
 					return align;
 				}
 
-				function onSelectionChange(evt){
-					if(evt.editor.readOnly){
+				function onSelectionChange(evt) {
+					if (evt.editor.readOnly) {
 						return;
 					}
 
 					var command = evt.editor.getCommand(this.name),
 						element = evt.data.element,
 						cmd = element.type == 1 && element.hasAttribute('lj-cmd') && element.getAttribute('lj-cmd');
-					if(cmd == 'LJLike'){
+					if (cmd == 'LJLike') {
 						command.state = (getAlignment(element, editor.config.useComputedState) == this.value) ? CKEDITOR.TRISTATE_ON : CKEDITOR.TRISTATE_OFF;
-					} else if(!element || element.type != 1 || element.is('body') || element.is('iframe')){
+					} else if (!element || element.type != 1 || element.getName() == 'body' || element.getName() == 'iframe') {
 						command.state = CKEDITOR.TRISTATE_OFF;
 					} else {
 						command.state = getAlignment(element, editor.config.useComputedState) == this.value ? CKEDITOR.TRISTATE_ON : CKEDITOR.TRISTATE_OFF;
@@ -703,13 +745,13 @@
 					command.fire('state');
 				}
 
-				function justifyCommand(editor, name, value){
+				function justifyCommand(editor, name, value) {
 					this.name = name;
 					this.value = value;
 
 					var classes = editor.config.justifyClasses;
-					if(classes){
-						switch(value){
+					if (classes) {
+						switch (value) {
 							case 'left' :
 								this.cssClassName = classes[0];
 								break;
@@ -725,7 +767,7 @@
 					}
 				}
 
-				function onDirChanged(e){
+				function onDirChanged(e) {
 					var editor = e.editor;
 
 					var range = new CKEDITOR.dom.range(editor.document);
@@ -735,10 +777,10 @@
 					var walker = new CKEDITOR.dom.walker(range),
 						node;
 
-					while(( node = walker.next() )){
-						if(node.type == CKEDITOR.NODE_ELEMENT){
+					while (( node = walker.next() )) {
+						if (node.type == CKEDITOR.NODE_ELEMENT) {
 							// A child with the defined dir is to be ignored.
-							if(!node.equals(e.data.node) && node.getDirection()){
+							if (!node.equals(e.data.node) && node.getDirection()) {
 								range.setStartAfter(node);
 								walker = new CKEDITOR.dom.walker(range);
 								continue;
@@ -746,14 +788,14 @@
 
 							// Switch the alignment.
 							var classes = editor.config.justifyClasses;
-							if(classes){
+							if (classes) {
 								// The left align class.
-								if(node.hasClass(classes[ 0 ])){
+								if (node.hasClass(classes[ 0 ])) {
 									node.removeClass(classes[ 0 ]);
 									node.addClass(classes[ 2 ]);
 								}
 								// The right align class.
-								else if(node.hasClass(classes[ 2 ])){
+								else if (node.hasClass(classes[ 2 ])) {
 									node.removeClass(classes[ 2 ]);
 									node.addClass(classes[ 0 ]);
 								}
@@ -763,9 +805,9 @@
 							var style = 'text-align';
 							var align = node.getStyle(style);
 
-							if(align == 'left'){
+							if (align == 'left') {
 								node.setStyle(style, 'right');
-							} else if(align == 'right'){
+							} else if (align == 'right') {
 								node.setStyle(style, 'left');
 							}
 						}
@@ -773,17 +815,17 @@
 				}
 
 				justifyCommand.prototype = {
-					exec : function(editor){
+					exec : function(editor) {
 						var selection = editor.getSelection(),
 							enterMode = editor.config.enterMode;
 
-						if(!selection){
+						if (!selection) {
 							return;
 						}
 
 						var bookmarks = selection.createBookmarks();
 
-						if(ljTagsData.LJLike.node){
+						if (ljTagsData.LJLike.node) {
 							ljTagsData.LJLike.node.setAttribute('lj-style', 'text-align: ' + this.value);
 						} else {
 							var ranges = selection.getRanges(true);
@@ -795,16 +837,16 @@
 							var useComputedState = editor.config.useComputedState;
 							useComputedState = useComputedState === undefined || useComputedState;
 
-							for(var i = ranges.length - 1; i >= 0; i--){
+							for (var i = ranges.length - 1; i >= 0; i--) {
 								var range = ranges[i];
 								var encloseNode = range.getEnclosedNode();
-								if(encloseNode && encloseNode.is('iframe')){
+								if (encloseNode && encloseNode.is('iframe')) {
 									return;
 								}
 
 								iterator = range.createIterator();
 								iterator.enlargeBr = enterMode != CKEDITOR.ENTER_BR;
-								while(( block = iterator.getNextParagraph(enterMode == CKEDITOR.ENTER_P ? 'p' : 'div') )){
+								while (( block = iterator.getNextParagraph(enterMode == CKEDITOR.ENTER_P ? 'p' : 'div') )) {
 									block.removeAttribute('align');
 									block.removeStyle('text-align');
 
@@ -813,14 +855,14 @@
 
 									var apply = ( this.state == CKEDITOR.TRISTATE_OFF ) && ( !useComputedState || ( getAlignment(block, true) != this.value ) );
 
-									if(cssClassName){
+									if (cssClassName) {
 										// Append the desired class name.
-										if(apply){
+										if (apply) {
 											block.addClass(cssClassName);
-										} else if(!className){
+										} else if (!className) {
 											block.removeAttribute('class');
 										}
-									} else if(apply){
+									} else if (apply) {
 										block.setStyle('text-align', this.value);
 									}
 								}
@@ -862,19 +904,19 @@
 			})();
 
 			//////////  LJ Poll Button //////////////
-			if(top.canmakepoll){
+			if (top.canmakepoll) {
 				var currentPoll;
 
 				editor.addCss('.lj-poll {' + 'width:100%;' + 'border: #000 1px dotted;' + 'background-color: #d2d2d2;' + 'font-style: italic;' + '}');
 
-				CKEDITOR.dialog.add('LJPollDialog', function(){
+				CKEDITOR.dialog.add('LJPollDialog', function() {
 					var isAllFrameLoad = 0, okButtonNode, questionsWindow, setupWindow;
 
-					var onLoadPollPage = function(){
-						if(this.removeListener){
+					var onLoadPollPage = function() {
+						if (this.removeListener) {
 							this.removeListener('load', onLoadPollPage);
 						}
-						if(isAllFrameLoad && okButtonNode){
+						if (isAllFrameLoad && okButtonNode) {
 							currentPoll = new Poll(ljTagsData.LJPollLink.node && decodeURIComponent(ljTagsData.LJPollLink.node.getAttribute('lj-data')), questionsWindow.document, setupWindow.document, questionsWindow.Questions);
 
 							questionsWindow.ready(currentPoll);
@@ -891,14 +933,14 @@
 						type: 'button',
 						id: 'LJPoll_Ok',
 						label: editor.lang.common.ok,
-						onClick: function(evt){
+						onClick: function(evt) {
 							evt.data.dialog.hide();
 							var poll = new Poll(currentPoll, questionsWindow.document, setupWindow.document, questionsWindow.Questions);
 							var pollSource = poll.outputHTML();
 							var pollLJTags = poll.outputLJtags();
 
-							if(pollSource.length > 0){
-								if(ljTagsData.LJPollLink.node){
+							if (pollSource.length > 0) {
+								if (ljTagsData.LJPollLink.node) {
 									ljTagsData.LJPollLink.node.setAttribute('lj-content', pollSource);
 									ljTagsData.LJPollLink.node.setAttribute('lj-data', pollLJTags);
 								} else {
@@ -924,8 +966,8 @@
 						width: 420,
 						height: 270,
 						resizable: false,
-						onShow: function(){
-							if(isAllFrameLoad){
+						onShow: function() {
+							if (isAllFrameLoad) {
 								currentPoll = new Poll(ljTagsData.LJPollLink.node && unescape(ljTagsData.LJPollLink.node.getAttribute('data')), questionsWindow.document, setupWindow.document, questionsWindow.Questions);
 
 								questionsWindow.ready(currentPoll);
@@ -941,13 +983,13 @@
 									{
 										type: 'html',
 										html: '<iframe src="/tools/ck_poll_setup.bml" allowTransparency="true" frameborder="0" style="width:100%; height:320px;"></iframe>',
-										onShow: function(data){
-											if(!okButtonNode){
+										onShow: function(data) {
+											if (!ok...
 (truncated)
Tags: bml, css, gariev, js, livejournal, pm, png, s2
Subscribe
  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 0 comments