sr-npm 1.7.1264 → 1.7.1268

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/backend/data.js CHANGED
@@ -287,7 +287,7 @@ async function saveJobsDescriptionsAndLocationApplyUrlReferencesToCMS() {
287
287
  const chunkPromises = chunk.map(async job => {
288
288
  try {
289
289
  const jobDetails = await fetchJobDescription(job._id);
290
- const richContentDescription=await htmlRichContentConverter(jobDetails.jobAd.sections,richContentConverterToken,jobDetails);
290
+ const richContentDescription=await htmlRichContentConverter(jobDetails.jobAd.sections,richContentConverterToken);
291
291
  const jobLocation = fetchJobLocation(jobDetails);
292
292
  const {applyLink , referFriendLink} = fetchApplyAndReferFriendLink(jobDetails);
293
293
  const updatedJob = {
@@ -114,12 +114,12 @@ async function fetchJobDescription(jobId,testObject=undefined) {
114
114
  return await makeSmartRecruitersRequest(`/v1/companies/${companyId}/postings/${jobId}`,templateType);
115
115
  }
116
116
 
117
- async function htmlRichContentConverter(sections,richContentConverterToken,jobName) {
117
+ async function htmlRichContentConverter(sections,richContentConverterToken) {
118
118
 
119
119
  const richContentObject = {}
120
120
  for (const [sectionTitle, sectionData] of Object.entries(sections)) {
121
121
  if (sectionData.text) {
122
- // Strip span tags but keep their content
122
+ // Strip span tags but keep their content , since <span> tags paragraphs are deleted by the converter
123
123
  const cleanedHtml = sectionData.text.replace(/<\/?span[^>]*>/gi, '');
124
124
  const raw = JSON.stringify({
125
125
  content: cleanedHtml,
@@ -142,7 +142,7 @@ async function htmlRichContentConverter(sections,richContentConverterToken,jobNa
142
142
  // Fix list items with nested paragraphs (causes line breaks after bold text)
143
143
  const flattenedContent = flattenListItems(data.richContent.richContent);
144
144
  // const richContentWithSpacing=addSpacingToRichContent(cleanedHtml,flattenedContent);
145
- const richContentWithSpacing=addEmptyParagraphsBetweenConsecutive(cleanedHtml,flattenedContent,jobName);
145
+ const richContentWithSpacing=addEmptyParagraphsBetweenConsecutive(cleanedHtml,flattenedContent);
146
146
  richContentObject[sectionTitle] = richContentWithSpacing
147
147
  }
148
148
  else {
@@ -153,163 +153,6 @@ async function htmlRichContentConverter(sections,richContentConverterToken,jobNa
153
153
  return richContentObject;
154
154
  }
155
155
 
156
- //Adds empty paragraph nodes between sections in rich content
157
- // to create visual spacing that the Wix RICOS converter strips out
158
- function addSpacingToRichContent(html, richContent) {
159
- if (!richContent || !richContent.nodes) {
160
- return richContent;
161
- }
162
-
163
-
164
- // Extract paragraph texts from HTML that end with &#xa0;
165
- const htmlParagraphsWithSpace = [];
166
- // Extract paragraphs with <br> tags
167
- const htmlParagraphsWithBr = new Map(); // text -> array of parts split by <br>
168
- // Check if HTML has consecutive paragraphs (</p><p> pattern)
169
- const hasConsecutiveParagraphs = /<\/p>\s*<p/i.test(html);
170
- // Check if HTML has paragraph followed by list (</p><ul> pattern)
171
- const hasParagraphBeforeList = /<\/p>\s*<ul/i.test(html);
172
-
173
- const pTagRegex = /<p>(.*?)<\/p>/gi;
174
- let match;
175
-
176
- while ((match = pTagRegex.exec(html)) !== null) {
177
- const content = match[1];
178
-
179
- // Check if this paragraph ends with &#xa0; (before closing tags)
180
- if (content.includes('&#xa0;')) {
181
- const textOnly = content.replace(/<[^>]+>/g, '').trim();
182
- htmlParagraphsWithSpace.push(textOnly);
183
- }
184
-
185
- // Check if this paragraph contains <br> tags
186
- if (content.includes('<br>') || content.includes('<br/>') || content.includes('<br />')) {
187
- // Split by <br> tags and extract text parts
188
- const parts = content.split(/<br\s*\/?>/i).map(part =>
189
- part.replace(/<[^>]+>/g, '').trim()
190
- ).filter(part => part.length > 0);
191
-
192
- if (parts.length > 1) {
193
- // Store the parts for this paragraph
194
- const fullText = content.replace(/<[^>]+>/g, '').replace(/\s+/g, '').trim();
195
- htmlParagraphsWithBr.set(fullText, parts);
196
- }
197
- }
198
- }
199
-
200
- const nodes = richContent.nodes;
201
- const newNodes = [];
202
- let nodeIdCounter = 0;
203
-
204
- // Check if a paragraph is bold (has BOLD decoration)
205
- const isBoldParagraph = (node) => {
206
- if (node.type !== 'PARAGRAPH') return false;
207
- const decorations = node.nodes?.[0]?.textData?.decorations || [];
208
- return decorations.some(d => d.type === 'BOLD');
209
- };
210
-
211
- // Check if a paragraph node's text matches one with &#xa0; in HTML
212
- const needsSpacingAfter = (node, nextNode) => {
213
- if (node.type !== 'PARAGRAPH') return false;
214
-
215
- // Add spacing after bold paragraphs
216
- if (isBoldParagraph(node)) {
217
- return true;
218
- }
219
-
220
- // If HTML has consecutive <p> tags and next node is also a paragraph, add spacing
221
- if (hasConsecutiveParagraphs && nextNode && nextNode.type === 'PARAGRAPH') {
222
- return true;
223
- }
224
-
225
- // If HTML has </p><ul> and next node is a list, add spacing
226
- if (hasParagraphBeforeList && nextNode && nextNode.type === 'BULLETED_LIST') {
227
- return true;
228
- }
229
-
230
- const text = node.nodes?.[0]?.textData?.text || '';
231
- const trimmedText = text.trim();
232
-
233
- // Check if this text matches any HTML paragraph that had &#xa0;
234
- return htmlParagraphsWithSpace.some(htmlText => {
235
- const cleanHtml = htmlText.replace(/&#xa0;/g, ' ').trim();
236
- return trimmedText.includes(cleanHtml) || cleanHtml.includes(trimmedText);
237
- });
238
- };
239
-
240
- // Check if a paragraph contains text that should be split by <br>
241
- const shouldSplitByBr = (node) => {
242
- if (node.type !== 'PARAGRAPH') return null;
243
-
244
- const text = node.nodes?.[0]?.textData?.text || '';
245
- const normalizedText = text.replace(/\s+/g, '').trim();
246
-
247
- // Find matching HTML paragraph with <br>
248
- for (const [htmlText, parts] of htmlParagraphsWithBr.entries()) {
249
- if (normalizedText.includes(htmlText) || htmlText.includes(normalizedText)) {
250
- return parts;
251
- }
252
- }
253
- return null;
254
- };
255
-
256
- // Add spacing after bulleted lists
257
- const isListEnd = (currentNode, nextNode) => {
258
- return currentNode.type === 'BULLETED_LIST' &&
259
- nextNode &&
260
- nextNode.type === 'PARAGRAPH';
261
- };
262
-
263
- for (let i = 0; i < nodes.length; i++) {
264
- const currentNode = nodes[i];
265
- const nextNode = nodes[i + 1];
266
-
267
- // Check if this paragraph should be split by <br>
268
- const brParts = shouldSplitByBr(currentNode);
269
- if (brParts && brParts.length > 1) {
270
- // Split into multiple paragraphs and add spacing between them
271
- const decorations = currentNode.nodes?.[0]?.textData?.decorations || [];
272
-
273
- brParts.forEach((part, idx) => {
274
- newNodes.push({
275
- ...currentNode,
276
- id: `${currentNode.id}_split_${idx}`,
277
- nodes: [{
278
- type: "TEXT",
279
- id: "",
280
- nodes: [],
281
- textData: {
282
- text: part,
283
- decorations: decorations
284
- }
285
- }]
286
- });
287
-
288
- // Add empty paragraph after each split part except the last
289
- if (idx < brParts.length - 1) {
290
- newNodes.push(createEmptyParagraph(`empty_br_${nodeIdCounter++}`));
291
- }
292
- });
293
-
294
- // Add spacing after the split paragraphs if there's a next node
295
- if (nextNode) {
296
- newNodes.push(createEmptyParagraph(`empty_${nodeIdCounter++}`));
297
- }
298
- } else {
299
- newNodes.push(currentNode);
300
-
301
- // Add empty paragraph after paragraphs with &#xa0;, consecutive paragraphs, or after lists
302
- if ((needsSpacingAfter(currentNode, nextNode) || isListEnd(currentNode, nextNode)) && nextNode) {
303
- newNodes.push(createEmptyParagraph(`empty_${nodeIdCounter++}`));
304
- }
305
- }
306
- }
307
-
308
- return {
309
- ...richContent,
310
- nodes: newNodes
311
- };
312
- }
313
156
 
314
157
  function createEmptyParagraph(id) {
315
158
  return {
@@ -371,13 +214,7 @@ function flattenListItems(richContent) {
371
214
  }
372
215
 
373
216
  // Adds empty paragraph nodes between consecutive paragraphs and before lists
374
- function addEmptyParagraphsBetweenConsecutive(html, richContent,jobName) {
375
- console.log("jobName is : ",jobName);
376
- if(jobName.name==="Assistant Store Manager - Noel Leeming Albany")
377
- {
378
- console.log("rich content is : ",richContent);
379
- console.log("html is : ",html);
380
- }
217
+ function addEmptyParagraphsBetweenConsecutive(html, richContent) {
381
218
  if (!richContent || !richContent.nodes) return richContent;
382
219
  const hasConsecutiveParagraphs = /<\/p>\s*<p/i.test(html);
383
220
  const hasParagraphBeforeList = /<\/p>\s*<ul/i.test(html);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sr-npm",
3
- "version": "1.7.1264",
3
+ "version": "1.7.1268",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -39,7 +39,7 @@ let secondarySearchIsFilled=false // whether the secondary search is filled with
39
39
  let keywordAllJobs; // all jobs that are displayed in the jobs repeater when the keyword is filled
40
40
  let ActivateURLOnchange=true; // whether to activate the url onchange
41
41
  let considerAllJobs=false; // whether to consider all jobs or not
42
-
42
+ let finishedUrlOnChange=false;
43
43
  const pagination = {
44
44
  pageSize: 10,
45
45
  currentPage: 1,
@@ -48,7 +48,8 @@ const pagination = {
48
48
  async function careersMultiBoxesPageOnReady(_$w,urlParams) {
49
49
  //to handle back and forth , url changes
50
50
  onChange(async ()=>{
51
- await handleBackAndForth(_$w);
51
+ finishedUrlOnChange? finishedUrlOnChange=false : await handleBackAndForth(_$w);
52
+
52
53
  });
53
54
  await loadData(_$w);
54
55
  await loadJobsRepeater(_$w); // if we remove the await here the job list will be flaky , it doesn't fill it properly
@@ -76,6 +77,7 @@ async function handleBackAndForth(_$w){
76
77
  await clearAll(_$w,true);
77
78
  await handleUrlParams(_$w,newQueryParams,true);
78
79
  ActivateURLOnchange=true;
80
+
79
81
 
80
82
  }
81
83
  else{
@@ -206,6 +208,11 @@ async function handleUrlParams(_$w,urlParams,handleBackAndForth=false) {
206
208
  const jobsFirstPage=currentJobs.slice(startSlicIndex,endSlicIndex);
207
209
  _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.JOBS_REPEATER).data = jobsFirstPage;
208
210
  handlePaginationButtons(_$w);
211
+ if(ActivateURLOnchange)
212
+ {
213
+ finishedUrlOnChange=true;
214
+ }
215
+
209
216
  }
210
217
  } catch (error) {
211
218
  console.error('Failed to handle url params:', error);