]> git.mxchange.org Git - friendica.git/blob - view/theme/frost-mobile/js/readmore.js
bug fix #1135, show more is usable again
[friendica.git] / view / theme / frost-mobile / js / readmore.js
1 /*!
2  * Readmore.js jQuery plugin
3  * Author: @jed_foster
4  * Project home: jedfoster.github.io/Readmore.js
5  * Licensed under the MIT license
6  */
7
8 ;(function($) {
9
10   var readmore = 'readmore',
11       defaults = {
12         speed: 100,
13         maxHeight: 200,
14         heightMargin: 16,
15         moreLink: '<a href="#">Read More</a>',
16         lessLink: '<a href="#">Close</a>',
17         embedCSS: true,
18         sectionCSS: 'display: block; width: 100%;',
19         startOpen: false,
20         expandedClass: 'readmore-js-expanded',
21         collapsedClass: 'readmore-js-collapsed',
22
23         // callbacks
24         beforeToggle: function(){},
25         afterToggle: function(){}
26       },
27       cssEmbedded = false;
28
29   function Readmore( element, options ) {
30     this.element = element;
31
32     this.options = $.extend( {}, defaults, options);
33
34     $(this.element).data('max-height', this.options.maxHeight);
35     $(this.element).data('height-margin', this.options.heightMargin);
36
37     delete(this.options.maxHeight);
38
39     if(this.options.embedCSS && ! cssEmbedded) {
40       var styles = '.readmore-js-toggle, .readmore-js-section { ' + this.options.sectionCSS + ' } .readmore-js-section { overflow: hidden; }';
41
42       (function(d,u) {
43         var css=d.createElement('style');
44         css.type = 'text/css';
45         if(css.styleSheet) {
46             css.styleSheet.cssText = u;
47         }
48         else {
49             css.appendChild(d.createTextNode(u));
50         }
51         d.getElementsByTagName('head')[0].appendChild(css);
52       }(document, styles));
53
54       cssEmbedded = true;
55     }
56
57     this._defaults = defaults;
58     this._name = readmore;
59
60     this.init();
61   }
62
63   Readmore.prototype = {
64
65     init: function() {
66       var $this = this;
67
68       $(this.element).each(function() {
69         var current = $(this),
70             maxHeight = (current.css('max-height').replace(/[^-\d\.]/g, '') > current.data('max-height')) ? current.css('max-height').replace(/[^-\d\.]/g, '') : current.data('max-height'),
71             heightMargin = current.data('height-margin');
72
73         if(current.css('max-height') != 'none') {
74           current.css('max-height', 'none');
75         }
76
77         $this.setBoxHeight(current);
78
79         if(current.outerHeight(true) <= maxHeight + heightMargin) {
80           // The block is shorter than the limit, so there's no need to truncate it.
81           return true;
82         }
83         else {
84           current.addClass('readmore-js-section ' + $this.options.collapsedClass).data('collapsedHeight', maxHeight);
85
86           var useLink = $this.options.startOpen ? $this.options.lessLink : $this.options.moreLink;
87           current.after($(useLink).on('click', function(event) { $this.toggleSlider(this, current, event) }).addClass('readmore-js-toggle'));
88
89           if(!$this.options.startOpen) {
90             current.css({height: maxHeight});
91           }
92         }
93       });
94
95       $(window).on('resize', function(event) {
96         $this.resizeBoxes();
97       });
98     },
99
100     toggleSlider: function(trigger, element, event)
101     {
102       event.preventDefault();
103
104       var $this = this,
105           newHeight = newLink = sectionClass = '',
106           expanded = false,
107           collapsedHeight = $(element).data('collapsedHeight');
108
109       if ($(element).height() <= collapsedHeight) {
110         newHeight = $(element).data('expandedHeight') + 'px';
111         newLink = 'lessLink';
112         expanded = true;
113         sectionClass = $this.options.expandedClass;
114       }
115
116       else {
117         newHeight = collapsedHeight;
118         newLink = 'moreLink';
119         sectionClass = $this.options.collapsedClass;
120       }
121
122       // Fire beforeToggle callback
123       $this.options.beforeToggle(trigger, element, expanded);
124
125       $(element).animate({'height': newHeight}, {duration: $this.options.speed, complete: function() {
126           // Fire afterToggle callback
127           $this.options.afterToggle(trigger, element, expanded);
128
129           $(trigger).replaceWith($($this.options[newLink]).on('click', function(event) { $this.toggleSlider(this, element, event) }).addClass('readmore-js-toggle'));
130
131           $(this).removeClass($this.options.collapsedClass + ' ' + $this.options.expandedClass).addClass(sectionClass);
132         }
133       });
134     },
135
136     setBoxHeight: function(element) {
137       var el = element.clone().css({'height': 'auto', 'width': element.width(), 'overflow': 'hidden'}).insertAfter(element),
138           height = el.outerHeight(true);
139
140       el.remove();
141
142       element.data('expandedHeight', height);
143     },
144
145     resizeBoxes: function() {
146       var $this = this;
147
148       $('.readmore-js-section').each(function() {
149         var current = $(this);
150
151         $this.setBoxHeight(current);
152
153         if(current.height() > current.data('expandedHeight') || (current.hasClass($this.options.expandedClass) && current.height() < current.data('expandedHeight')) ) {
154           current.css('height', current.data('expandedHeight'));
155         }
156       });
157     },
158
159     destroy: function() {
160       var $this = this;
161
162       $(this.element).each(function() {
163         var current = $(this);
164
165         current.removeClass('readmore-js-section ' + $this.options.collapsedClass + ' ' + $this.options.expandedClass).css({'max-height': '', 'height': 'auto'}).next('.readmore-js-toggle').remove();
166
167         current.removeData();
168       });
169     }
170   };
171
172   $.fn[readmore] = function( options ) {
173     var args = arguments;
174     if (options === undefined || typeof options === 'object') {
175       return this.each(function () {
176         if ($.data(this, 'plugin_' + readmore)) {
177           var instance = $.data(this, 'plugin_' + readmore);
178           instance['destroy'].apply(instance);
179         }
180
181         $.data(this, 'plugin_' + readmore, new Readmore( this, options ));
182       });
183     } else if (typeof options === 'string' && options[0] !== '_' && options !== 'init') {
184       return this.each(function () {
185         var instance = $.data(this, 'plugin_' + readmore);
186         if (instance instanceof Readmore && typeof instance[options] === 'function') {
187           instance[options].apply( instance, Array.prototype.slice.call( args, 1 ) );
188         }
189       });
190     }
191   }
192 })(jQuery);