PageSourceSearch

https://shop.rerootedorganic.co.uk/api/website/reviews.js?20221006

js rerootedorganic.co.uk collected 2026-10-07 02:09:09 UTC 14,313 bytes, 399 lines download raw bytes

1
2function showReviewDialog(element,event){
3
4	console.log.call(console,"showReviewDialog",element,event);
5
6	if(event){
7	
8		event.preventDefault();
9		event.stopPropagation();
10		
11	}
12		
13	var container=element.parentNode;
14	
15	// Make sure dialog closed if one already open
16	hideReviewDialog();
17	
18	// Get ratings for all products and company
19	var request=new XMLHttpRequest();
20	request.open("get","https://shop.rerootedorganic.co.uk/api/website/reviews/?product="+container.id+"&t="+new Date().getTime(),true);
21	request.onload=function(){
22	
23		var result=JSON.parse(request.responseText);
24		if(result&&result.reviews){
25		
26			var reviews=result.reviews;
27			
28			// Show dialog
29			var screen=document.body.appendChild(document.createElement("div"));
30			screen.className="review-dialog";
31			screen.style.cssText="position:fixed; top:0px; left:0px; width:100%; height:100%; background-color:rgba(87,178,91,0.7); z-index:2147483647; display:table;";
32		
33			var cell=screen.appendChild(document.createElement("div"));
34			cell.style.cssText="display:table-cell; text-align:center; vertical-align:middle;";
35			
36			var dialog=cell.appendChild(document.createElement("div"));
37			dialog.style.cssText="position:relative; display:inline-block; width:100%; max-width:640px; background-color:#fff; border-radius:8px; box-sizing:border-box; padding:12px; text-align:left; box-shadow:0px 12px 24px 1px rgba(0,0,0,0.2);";
38			
39			// Close button
40			var button=dialog.appendChild(document.createElement("a"));
41			button.style.cssText="position:absolute; top:8px; right:8px; font-size:36px; line-height:36px; width:36px; text-align:center; display:inline-block; cursor:pointer; color:#716253; font-weight:400;";
42			button.innerHTML="×";
43			button.onclick=hideReviewDialog;
44			
45			var heading=dialog.appendChild(document.createElement("h2"));
46			heading.innerText=result.name+" Reviews";
47			heading.style.cssText="display:block; font-size:23px; text-transform:uppercase; line-height:1em; font-family:Montserrat,sans-serif; font-weight:900; color:#716253; margin:10px 12px 16px 12px;";
48			
49			var list=dialog.appendChild(document.createElement("div"));
50			list.style.cssText="overflow-y:auto; box-sizing:border-box; padding:0px 12px; max-height:75vh;";
51			
52			// Review button
53			var button=dialog.appendChild(document.createElement("button"));
54			button.className="fusion-button button-flat button-medium button-default button-4 fusion-button-default-span fusion-button-default-type";
55			button.style.cssText="margin:16px 0px 4px 8px;";
56			button.innerHTML='<span class="fusion-button-text">Leave a Review</span>';
57			result.id=container.id;
58			button.onclick=showAddReviewDialog.bind(null,result);
59			
60			// Loop reviews
61			for(var i=0;i<reviews.length;i++)
62				list.appendChild(createReviewElement(reviews[i]));
63				
64		}
65	}
66	
67	request.send();
68	
69}
70
71function formatTimespan(date){
72
73	//console.log.call(console,"formatTimespan",date);
74	
75	var seconds=Math.floor((new Date().getTime()-date.getTime())/1000);
76	var interval=seconds/31536000;
77	if(interval>1)
78		return (Math.floor(interval)+" years ago").replace(/^1 years/gi,"1 year");
79	
80	interval=seconds/2592000;
81	if(interval>1)
82		return (Math.floor(interval)+" months ago").replace(/^1 months/gi,"1 month");
83	
84	interval=seconds/86400;
85	if(interval>1)
86		return (Math.floor(interval)+" days ago").replace(/^1 days/gi,"1 day");
87	
88	interval=seconds/3600;
89	if(interval>1)
90		return (Math.floor(interval)+" hours ago").replace(/^1 hours/gi,"1 hour");
91	
92	interval=seconds/60;
93	if(interval>1)
94		return (Math.floor(interval)+" minutes ago").replace(/^1 minutes/gi,"1 minute");
95	
96	return (Math.floor(seconds)+" seconds ago").replace(/^(0|1) seconds/gi,"1 second");
97
98}
99
100function createReviewElement(review){
101
102	var element=document.createElement("div");
103	element.style.cssText="border-top:1px solid #ddd; box-sizing:border-box; padding:16px 0px 16px 0px; margin:0px 12px 0px 0px; text-align:left;";
104	
105	// Create stars
106	var rating=review.rating;
107	var stars=element.appendChild(document.createElement("div"));
108	for(var i=0;i<5;i++){
109		
110		var star=stars.appendChild(document.createElement("span"));
111		star.className="far";
112		star.innerHTML="&#xf005;";
113		star.style.color="#ccc";
114		star.style.fontSize="20px";
115		
116		if(rating>i){
117		
118			star.className="fa";
119			star.style.color="#57b25b";
120			star.style.fontWeight="bold";
121			
122		}
123	}
124	
125	var details=element.appendChild(document.createElement("div"));
126	details.style.cssText="margin-top:12px;";
127	
128	var customer=details.appendChild(document.createElement("b"));
129	customer.style.cssText="font-weight:800;";
130	customer.innerText=review.customer_name;
131	
132	var timeStamp=details.appendChild(document.createElement("span"));
133	timeStamp.style.cssText="";
134	timeStamp.innerText=" - "+formatTimespan(new Date(review.created));
135	
136	if(review.review){
137	
138		var text=element.appendChild(document.createElement("div"));
139		text.style.cssText="margin-top:3px; line-height:1.4em;";
140		
141		if(review.review.length>256){
142		
143			text.innerText=review.review.slice(0,256)+"... ";
144			var more=text.appendChild(document.createElement("a"));
145			more.href="";
146			more.innerText="more";
147			more.onclick=expandReviewText.bind(null,text,review.review);
148		
149		}
150		else
151			text.innerText=review.review;
152	
153	}
154	
155	return element;
156
157}
158
159function expandReviewText(element,fullText,event){
160
161	event.preventDefault();
162	
163	element.precisContent=element.innerHTML;
164	element.innerHTML='';
165	element.innerText=fullText+" ";
166	
167	var less=element.appendChild(document.createElement("a"));
168	less.href="";
169	less.innerText="less";
170	less.onclick=collapseReviewText.bind(null,element,fullText);
171
172}
173
174function collapseReviewText(element,fullText,event){
175
176	event.preventDefault();
177	
178	element.innerHTML=element.precisContent;
179	element.querySelector("a[href]").onclick=expandReviewText.bind(null,element,fullText);
180	
181}
182
183function hideReviewDialog(){
184
185	var dialog=document.querySelector(".review-dialog");
186	if(dialog){
187	
188		document.body.removeChild(dialog);
189		dialog=null;
190
191	}
192}
193
194function showAddReviewDialog(product){
195
196	console.log.call(console,"showAddReviewDialog",product);
197
198	// Make sure dialog closed if one already open
199	hideReviewDialog();
200	hideAddReviewDialog();
201	
202	// Show dialog
203	var screen=document.body.appendChild(document.createElement("div"));
204	screen.className="add-review-dialog";
205	screen.style.cssText="position:fixed; top:0px; left:0px; width:100%; height:100%; background-color:rgba(87,178,91,0.7); z-index:2147483647; display:table;";
206
207	var cell=screen.appendChild(document.createElement("div"));
208	cell.style.cssText="display:table-cell; text-align:center; vertical-align:middle;";
209	
210	var dialog=cell.appendChild(document.createElement("div"));
211	dialog.style.cssText="position:relative; display:inline-block; width:100%; max-width:640px; background-color:#fff; border-radius:8px; box-sizing:border-box; padding:12px; text-align:left; box-shadow:0px 12px 24px 1px rgba(0,0,0,0.2);";
212	
213	// Close button
214	var button=dialog.appendChild(document.createElement("a"));
215	button.style.cssText="position:absolute; top:8px; right:8px; font-size:36px; line-height:36px; width:36px; text-align:center; display:inline-block; cursor:pointer; color:#716253; font-weight:400;";
216	button.innerHTML="&times;";
217	button.onclick=hideAddReviewDialog;
218	
219	var heading=dialog.appendChild(document.createElement("h2"));
220	heading.innerText="As a valued customer we'd love your feedback...";
221	heading.style.cssText="display:block; font-size:23px; line-height:1em; font-family:Montserrat,sans-serif; font-weight:900; color:#716253; margin:10px 32px 16px 12px;";
222	
223	var scroller=dialog.appendChild(document.createElement("div"));
224	scroller.style.cssText="overflow-y:auto; box-sizing:border-box; padding:0px 12px; max-height:68vh;";
225	
226	var form=scroller.appendChild(document.createElement("form"));
227	form.style.cssText="margin:12px 0px 12px 0px;";
228	form.onsubmit=submitRating.bind(null,product,form,dialog);
229	form.innerHTML=''
230		+'<style>'
231		+'	.form .field{'
232		+'		margin:24px 0px 24px 0px;'
233		+'		max-width:480px;'
234		+'		text-align:left;'
235		+'	}'
236		+'	.form .field:first-child{ margin-top:11px; }'
237		+'	.form .field:last-child{ margin-bottom:22px; }'
238		+'	.form .field label{'
239		+'		display:block;'
240		+'		margin:0px 0px 8px 0px;'
241		+'		line-height:1.4em;'
242		+'	}'
243		+'	.form .field:focus-within label{ color:#57b25b; }'
244		+'	.form .field input,.form .field textarea{'
245		+'		box-sizing:border-box;'
246		+'		width:100%;'
247		+'		border:1px solid #c6c6c5;'
248		+'		border-radius:6px;'
249		+'		height:42px;'
250		+'		padding:0px 12px 0px 12px;'
251		+'	}'
252		+'	.form .field input.error,.form .field textarea.error,.form .field select.error{ border-color:#f00000; }'
253		+'	.form .field textarea{'
254		+'		padding:11px 12px;'
255		+'		resize:none;'
256		+'		height:84px;'
257		+'	}'
258		+'	.form .field input:focus,.form .field textarea:focus,.form .field select:focus{ border:1.5px solid rgba(87,178,91,0.6); }'
259		+'	.form .field.stars a{'
260		+'		display:inline-block;'
261		+'		color:#ccc;'
262		+'		font-size:30px;'
263		+'		margin-right:2px;'
264		+'		cursor:pointer;'
265		+'	}'
266		+'	.form .field.stars .error a{ color:rgba(224,0,0,0.5); }'
267		+'	.form .field.stars a:hover{'
268		+'		text-decoration:none; '
269		+'		color:#57b25b;'
270		+'	}'
271		+'	.form .field.stars a.selected{'
272		+'		font-weight:bold; '
273		+'		color:#57b25b;'
274		+'	}'
275		+'</style>'
276		+'	<div class="form">'
277		+'		<div class="field stars">'
278		+'			<label>Please rate our <span class="product-name">'+product.name+'</span></label>'
279		+'			<input type="hidden" name="product_rating"/>'
280		+'			<div>'
281		+'				<a class="far" onclick="toggleStar(this.parentNode.parentNode,1,event)">&#xf005;</a>'
282		+'				<a class="far" onclick="toggleStar(this.parentNode.parentNode,2,event)">&#xf005;</a>'
283		+'				<a class="far" onclick="toggleStar(this.parentNode.parentNode,3,event)">&#xf005;</a>'
284		+'				<a class="far" onclick="toggleStar(this.parentNode.parentNode,4,event)">&#xf005;</a>'
285		+'				<a class="far" onclick="toggleStar(this.parentNode.parentNode,5,event)">&#xf005;</a>'
286		+'			</div>'
287		+'		</div>'
288		+'		<div class="field">'
289		+'			<label>Please leave a review of our <span class="product-name">'+product.name+'</span></label>'
290		+'			<textarea name="product_review" maxlength="4000" autocomplete="off" onfocus="this.className=\'\';"></textarea>'
291		+'		</div>'
292		+'		<div class="field stars">'
293		+'			<label>Please rate ReRooted as a company</label>'
294		+'			<input type="hidden" name="company_rating"/>'
295		+'			<div>'
296		+'				<a class="far" onclick="toggleStar(this.parentNode.parentNode,1,event)">&#xf005;</a>'
297		+'				<a class="far" onclick="toggleStar(this.parentNode.parentNode,2,event)">&#xf005;</a>'
298		+'				<a class="far" onclick="toggleStar(this.parentNode.parentNode,3,event)">&#xf005;</a>'
299		+'				<a class="far" onclick="toggleStar(this.parentNode.parentNode,4,event)">&#xf005;</a>'
300		+'				<a class="far" onclick="toggleStar(this.parentNode.parentNode,5,event)">&#xf005;</a>'
301		+'			</div>'
302		+'		</div>'
303		+'		<div class="field">'
304		+'			<label>We\'re always looking for ways to improve. What do we do well? What can we do better?</label>'
305		+'			<textarea name="company_review" maxlength="4000" autocomplete="off" onfocus="this.className=\'\';"></textarea>'
306		+'		</div>'
307		+'		<div class="field">'
308		+'			<label>Your name</label>'
309		+'			<input name="customer_name" maxlength="100" autocomplete="off" onfocus="this.className=\'\';"/>'
310		+'		</div>'
311		+'	</div>';
312	
313	// Review button
314	var button=dialog.appendChild(document.createElement("button"));
315	button.className="fusion-button button-flat button-medium button-default button-4 fusion-button-default-span fusion-button-default-type";
316	button.style.cssText="margin:16px 0px 4px 8px;";
317	button.innerHTML='<span class="fusion-button-text">Submit</span>';
318	button.onclick=submitRating.bind(null,product,form,dialog);
319		
320}
321
322function toggleStar(element,rating,event){
323
324	console.log.call(console,"toggleStar",element,rating,event);
325	
326	if(event){
327	
328		event.preventDefault();
329		event.stopPropagation();
330		
331	}
332	
333	element.querySelector("input").value=(rating>0)?rating:"";
334	
335	var stars=element.querySelectorAll("a");
336	for(var i=0;i<stars.length;i++)
337		stars[i].className=(i<rating)?"fa selected":"far";
338		
339	element.querySelector("div").className="";
340
341}
342
343function submitRating(product,form,dialog,event){
344
345	console.log.call(console,"submitRating",product,form,dialog,event);
346	
347	if(event)
348		event.preventDefault();
349		
350	// Validate all fields contain a value
351	form.querySelectorAll(".field.stars > div")[0].className=(form.product_rating.value)?"":"error";
352	form.querySelectorAll(".field.stars > div")[1].className=(form.company_review.value.trim()&&!form.company_rating.value)?"error":"";
353	form.product_review.className=(form.product_review.value.trim())?"":"error";
354	form.customer_name.className=(form.customer_name.value.trim())?"":"error";
355	form.company_review.className=""; 
356	
357	if(!form.querySelector(".error")){
358	
359		// Add rating on server
360		var request=new XMLHttpRequest();
361		request.open("post","https://shop.rerootedorganic.co.uk/api/website/reviews/",true);
362		request.onload=function(){
363		
364			var result=JSON.parse(request.responseText);
365			if(result&&result.rated){
366			
367				// Show message
368				dialog.querySelector("h2").innerText="Thank you!";
369				dialog.querySelector("form").innerHTML='Your review has been submitted.';
370				dialog.querySelector("button").onclick=hideAddReviewDialog;
371				dialog.querySelector("button span").innerText="Close";
372				
373					
374			}
375		}
376		
377		request.send(JSON.stringify({
378			"product_id":product.id,
379			"product_rating":form.product_rating.value,
380			"product_review":form.product_review.value.trim(),
381			"company_rating":form.company_rating.value,
382			"company_review":form.company_review.value.trim(),
383			"customer_name":form.customer_name.value.trim()
384		}));
385		
386	}
387
388}
389
390function hideAddReviewDialog(){
391
392	var dialog=document.querySelector(".add-review-dialog");
393	if(dialog){
394	
395		document.body.removeChild(dialog);
396		dialog=null;
397
398	}
399}

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.