PageSourceSearch

https://www.boitecast.net/wp-content/plugins/jetpack/modules/related-posts/related-posts.js

js boitecast.net collected 2026-10-02 15:39:12 UTC 5,913 bytes, 192 lines download raw bytes

1/* jshint onevar: false */
2
3/**
4 * Load related posts
5 */
6(function($) {
7	var jprp = {
8		response: null,
9
10		/**
11		 * Utility get related posts JSON endpoint from URLs
12		 *
13		 * @param string URL (optional)
14		 * @return string endpoint URL
15		 */
16		getEndpointURL: function( URL ) {
17			var locationObject = document.location;
18
19			if ( 'string' === typeof( URL ) && URL.match( /^https?:\/\// ) ) {
20				locationObject = document.createElement( 'a' );
21				locationObject.href = URL;
22			}
23
24			var args = 'relatedposts=1';
25			if ( ! $( '#jp-relatedposts' ).data( 'exclude' ) ) {
26				args += '&relatedposts_exclude=' + $( '#jp-relatedposts' ).data( 'exclude' );
27			}
28
29			var pathname = locationObject.pathname;
30			if ( '/' !== pathname[0] ) {
31				pathname = '/' + pathname;
32			}
33
34			if ( '' === locationObject.search ) {
35				return pathname + '?' + args;
36			} else {
37				return pathname + locationObject.search + '&' + args;
38			}
39		},
40
41		getAnchor: function( post, classNames ) {
42			var anchor_title = post.title;
43			if ( '' !== ( '' + post.excerpt ) ) {
44				anchor_title += '\n\n' + post.excerpt;
45			}
46
47			var anchor = $( '<a>' );
48
49			anchor.attr({
50				'class': classNames,
51				'href': post.url,
52				'title': anchor_title,
53				'rel': 'nofollow',
54				'data-origin': post.url_meta.origin,
55				'data-position': post.url_meta.position
56			});
57
58			var anchor_html = $( '<div>' ).append( anchor ).html();
59			return [
60				anchor_html.substring( 0, anchor_html.length-4 ),
61				'</a>'
62			];
63		},
64
65		generateMinimalHtml: function( posts ) {
66			var self = this;
67			var html = '';
68
69			$.each( posts, function( index, post ) {
70				var anchor = self.getAnchor( post, 'jp-relatedposts-post-a' );
71				var classes = 'jp-relatedposts-post jp-relatedposts-post' + index;
72
73				html += '<p class="' + classes + '" data-post-id="' + post.id + '" data-post-format="' + post.format + '">';
74				html += '<span class="jp-relatedposts-post-title">
74' + anchor[0] + post.title + anchor[1] + '</span>';
75				html += '<span class="jp-relatedposts-post-date">' + post.date + '</span>';
76				html += '<span class="jp-relatedposts-post-context">' + post.context + '</span>';
77				html += '</p>';
78			} );
79			return '<div class="jp-relatedposts-items jp-relatedposts-items-minimal">' + html + '</div>';
80		},
81
82		generateVisualHtml: function( posts ) {
83			var self = this;
84			var html = '';
85
86			$.each( posts, function( index, post ) {
87				var anchor = self.getAnchor( post, 'jp-relatedposts-post-a' );
88				var classes = 'jp-relatedposts-post jp-relatedposts-post' + index;
89				if ( ! post.img.src ) {
90					classes += ' jp-relatedposts-post-nothumbs';
91				} else {
92					classes += ' jp-relatedposts-post-thumbs';
93				}
94
95				html += '<div class="' + classes + '" data-post-id="' + post.id + '" data-post-format="' + post.format + '">';
96				if ( post.img.src ) {
97					html += anchor[0] + '<img class="jp-relatedposts-post-img" src="' + post.img.src + '" width="' + post.img.width + '" alt="' + post.title + '" />' + anchor[1];
98				} else {
99					var anchor_overlay = self.getAnchor( post, 'jp-relatedposts-post-a jp-relatedposts-post-aoverlay' );
100					html += anchor_overlay[0] + anchor_overlay[1];
101				}
102				html += '<h4 class="jp-relatedposts-post-title">
102' + anchor[0] + post.title + anchor[1] + '</h4>';
103				html += '<p class="jp-relatedposts-post-excerpt">' + $( '<p>' ).text( post.excerpt ).html() + '</p>';
104				html += '<p class="jp-relatedposts-post-date">' + post.date + '</p>';
105				html += '<p class="jp-relatedposts-post-context">' + post.context + '</p>';
106				html += '</div>';
107			} );
108			return '<div class="jp-relatedposts-items jp-relatedposts-items-visual">' + html + '</div>';
109		},
110
111		/**
112		 * We want to set a max height on the excerpt however we want to set
113		 * this according to the natual pacing of the page as we never want to
114		 * cut off a line of text in the middle so we need to do some detective
115		 * work.
116		 */
117		setVisualExcerptHeights: function() {
118			var elements = $( '#jp-relatedposts .jp-relatedposts-post-nothumbs .jp-relatedposts-post-excerpt' );
119
120			if ( 0 >= elements.length ) {
121				return;
122			}
123
124			var fontSize = parseInt( elements.first().css( 'font-size' ), 10 ),
125				lineHeight = parseInt( elements.first().css( 'line-height' ), 10 );
126
127			// Show 5 lines of text
128			elements.css(
129				'max-height',
130				( 5 * lineHeight / fontSize ) + 'em'
131			);
132		},
133
134		getTrackedUrl: function( anchor ) {
135			var args = 'relatedposts_hit=1';
136			args += '&relatedposts_origin=' + $( anchor ).data( 'origin' );
137			args += '&relatedposts_position=' + $( anchor ).data( 'position' );
138
139			var pathname = anchor.pathname;
140			if ( '/' !== pathname[0] ) {
141				pathname = '/' + pathname;
142			}
143
144			if ( '' === anchor.search ) {
145				return pathname + '?' + args;
146			} else {
147				return pathname + anchor.search + '&' + args;
148			}
149		},
150
151		cleanupTrackedUrl: function() {
152			if ( 'function' !== typeof history.replaceState ) {
153				return;
154			}
155
156			var cleaned_search = document.location.search.replace( /\brelatedposts_[a-z]+=[0-9]*&?\b/gi, '' );
157			if ( '?' === cleaned_search ) {
158				cleaned_search = '';
159			}
160			if ( document.location.search !== cleaned_search ) {
161				history.replaceState( {}, document.title, document.location.pathname + cleaned_search );
162			}
163		}
164	};
165
166	$( function() {
167		jprp.cleanupTrackedUrl();
168
169		$.getJSON( jprp.getEndpointURL(), function( response ) {
170			if ( 0 === response.items.length || 0 === $( '#jp-relatedposts' ).length ) {
171				return;
172			}
173
174			jprp.response = response;
175
176			var html = '';
177			if ( !response.show_thumbnails ) {
178				html = jprp.generateMinimalHtml( response.items );
179			} else {
180				html = jprp.generateVisualHtml( response.items );
181			}
182
183			$( '#jp-relatedposts' ).append( html );
184			jprp.setVisualExcerptHeights();
185			$( '#jp-relatedposts' ).show();
186
187			$( '#jp-relatedposts a.jp-relatedposts-post-a' ).click(function() {
188				this.href = jprp.getTrackedUrl( this );
189			});
190		} );
191	} );
192})(jQuery);

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.