2 * ExpanderEx object is used in s1 style comment pages and provides
3 * ajax functionality to expand comments instead of loading iframe page as it is
5 * expander object is also used in commentmanage.js
7 ExpanderEx = function(){
8 this.__caller__; // <a> HTML element from where ExpanderEx was called
9 this.url; // full url of thread to be expanded
10 this.id; // id of the thread
12 this.is_S1; // bool flag, true == journal is in S1, false == in S2
14 ExpanderEx.Collection={};
15 ExpanderEx.ReqCache = {};
17 ExpanderEx.make = function(el,url,id,is_S1){
18 var local = (new ExpanderEx).set({__caller__:el,url:url.replace(/#.*$/,''),id:id,is_S1:!!is_S1});
22 ExpanderEx.collapse = function(el,url,id,is_S1){
23 var local = (new ExpanderEx).set({__caller__:el,url:url.replace(/#.*$/,''),id:id,is_S1:!!is_S1});
24 local.collapseThread();
27 ExpanderEx.prototype.set = function(options){
28 for(var opt in options){
29 this[opt] = options[opt];
34 ExpanderEx.prototype.getCanvas = function(id,context){
35 return context.document.getElementById('ljcmt'+id);
38 ExpanderEx.prototype.parseLJ_cmtinfo = function(context,callback){
40 var LJ = context.LJ_cmtinfo;
43 if(/^\d*$/.test(j) && (node = this.getCanvas(j,context))){
44 map[j] = {info:LJ[j],canvas:node};
45 if(typeof callback == 'function'){
53 ExpanderEx.preloadImg = function(){
54 (new Image()).src = Site.imgprefix + '/preloader-s.gif?v=3';
57 ExpanderEx.prototype.addPreloader = function(){
58 this.loader = new Image();
59 this.loader.src = Site.imgprefix + '/preloader-s.gif?v=3';
60 this.loader.className = 'i-exp-preloader';
61 this.__caller__.parentNode.appendChild( this.loader );
64 ExpanderEx.prototype.removePreloader = function(){
69 if( this.loader.parentNode ){
70 this.loader.parentNode.removeChild( this.loader );
75 ExpanderEx.prototype.loadingStateOn = function(){
76 // turn on preloader there
78 this.stored_caller = this.__caller__.cloneNode(true);
79 this.__caller__.setAttribute('already_clicked','already_clicked');
80 this.__caller__.onclick = function(){return false}
81 this.__caller__.style.color = '#ccc';
84 ExpanderEx.prototype.loadingStateOff = function(){
86 // actually, the <a> element is removed from main window by
87 // copying comment from ifame, so this code is not executed (?)
88 this.__caller__.removeAttribute('already_clicked','already_clicked');
89 if(this.__caller__.parentNode) this.__caller__.parentNode.replaceChild(this.stored_caller,this.__caller__);
90 //remove preloader if exist
91 this.removePreloader();
94 // When frame is removed immediately, IE raises an error sometimes
97 ExpanderEx.prototype.killFrame = function(){
98 document.body.removeChild(this.iframe);
101 ExpanderEx.prototype.isFullComment = function( comment ) {
102 return !!Number(comment.info.full);
105 ExpanderEx.prototype.expandThread = function( json ) {
106 this.loadingStateOff();
108 //we show expand link if comment block has collapsed children
109 function isChildCollapsed( idx )
112 for( var i = idx + 1; i < json.length; ++i ) {
113 state = json[ i ].state;
114 if( state === "expanded" ) { return false; }
115 if( state === "collapsed" ) { return true; }
122 for( var i = 0; i < json.length; ++i ) {
123 //we skip comment blocks thate were not expanded
124 if( json[ i ].state && json[ i ].state !== "expanded") {
128 threadId = json[ i ].thread;
130 var oldHtml = LiveJournal.CommentManager.updateCell( threadId, json[ i ].html );
131 if( !( threadId in ExpanderEx.Collection ) ) {
132 ExpanderEx.Collection[ threadId ] = oldHtml;
136 //duplicate cycle, because we do not know, that external scripts do with node
137 for( var i = 0; i < json.length; ++i ) {
138 threadId = json[ i ].thread;
139 LJ_cmtinfo[ threadId ].parent = this.id;
140 if( json[ i ].state && json[ i ].state === "expanded") {
141 this.initCommentBlock( jQuery( '#ljcmt' + threadId )[0] , threadId );
148 ExpanderEx.prototype.collapseThread = function( id ){
149 var threadId = id || this.id;
150 this.collapseBlock( threadId );
152 var children = LJ_cmtinfo[ threadId ].rc;
153 for( var i = 0; i < children.length; ++i )
154 this.collapseThread( children[ i ] );
157 ExpanderEx.prototype.collapseBlock = function( id )
159 if( id in ExpanderEx.Collection ) {
160 LiveJournal.CommentManager.updateCell( id, ExpanderEx.Collection[ id ] );
162 this.initCommentBlock( LiveJournal.CommentManager.getCell( id )[0], id, true );
163 delete ExpanderEx.Collection[ id ];
167 ExpanderEx.prototype.initCommentBlock = function( el_, id, restoreInitState )
169 if( !restoreInitState ){
170 LJ_cmtinfo[ id ].oldvars = {
171 full: LJ_cmtinfo[ id ].full || 0,
172 expanded: LJ_cmtinfo[ id ].expanded || 0
174 LJ_cmtinfo[ id ].full = 1;
175 LJ_cmtinfo[ id ].expanded = 1;
178 LJ_cmtinfo[ id ].full = LJ_cmtinfo[ id ].oldvars.full;
179 LJ_cmtinfo[ id ].expanded = LJ_cmtinfo[ id ].oldvars.expanded;
180 delete LJ_cmtinfo[ id ].oldvars;
182 window.ContextualPopup && ContextualPopup.searchAndAdd(el_);
183 //window.setupAjax && setupAjax(el_, true);
184 window.ESN && ESN.initTrackBtns(el_);
189 ExpanderEx.prototype.toString = function(){
190 return '__'+this.id+'__';
194 ExpanderEx.prototype.get = function(){
195 if(this.__caller__.getAttribute('already_clicked')){
198 this.loadingStateOn();
201 //set timeout to allow browser to display image before request
202 setTimeout( function(){
203 LiveJournal.CommentManager.getThreadJSON( obj.id, function(result) {
204 obj.expandThread(result);
205 ExpanderEx.ReqCache[ obj.id ] = result;
206 }, false, false, true );
212 ExpanderEx.preloadImg();