1var imgPath = '/wp-content/plugins/wp_google_drive_integration/blocks/images'; 2var storagePrefix = 'wpgdi-'; 3__wgdi__clearStorage(storagePrefix); 4 5function __wpgdi__googleDriveFolderPopulate( e ) 6{ 7 if( e != 'undefined' || e != '' || e != false ) 8 { 9 var view = e.find('.google-drive-folder-list'); 10 var sectionId = e.parents('section').data('id') 11 view.attr('storageid', sectionId).append('<div class="view-loading">Loading...</div>'); 12 var gDriveFolderId = e.attr("fid"); 13 var listStyle = view.attr("liststyle"); 14 switch (listStyle) { 15 case "file-tree": 16 __wgdi__populateFileTree(gDriveFolderId, view); 17 __wgdi__toggleSearchable(view, true); 18 break; 19 case "file-buttons": 20 __wgdi__populateFileButtons(gDriveFolderId, view); 21 __wgdi__toggleSearchable(view, true); 22 break; 23 case "table-list": 24 __wgdi__populateTableList(gDriveFolderId, view); 25 break; 26 case "board-policy": 27 __wgdi__populateBoardPolicy(gDriveFolderId, view); 28 break; 29 } 30 } else { 31 console.log("init") 32 } 33} 34 35function __wgdi__checkFolderIdChanged(gDriveFolderId, sectionId) 36{ 37 if(sessionStorage.getItem('gid-' + sectionId) != gDriveFolderId){ 38 //changed 39 sessionStorage.setItem('gid-' + sectionId, gDriveFolderId); 40 return true; 41 }else{ 42 return false; 43 } 44} 45 46function __wgdi__populateFileTree(gDriveFolderId, view, notRoot, firstFolder = true) 47{ 48 var id = view.attr('storageid'); 49 var storageName = 'file-tree' + id; 50 if(gDriveFolderId){ 51 let googleAPIkey = gdi_drive_api_key; 52 let url = "https://www.googleapis.com/drive/v3/files?q='" + gDriveFolderId + "'+in+parents&fields=files(contentHints(indexableText,thumbnail/mimeType),createdTime,description,fileExtension,id,kind,mimeType,shortcutDetails,modifiedTime,name,parents,properties,size),kind&pageSize=1000&key=" + googleAPIkey; 53 //stores Google URL fetch result into storage so when 54 //properties are changed don't spam the Google API. 55 //sessionStorage is reseted after page reload 56 if((!sessionStorage.getItem(storagePrefix + storageName) || (!sessionStorage.getItem(storagePrefix + storageName) && !notRoot)) || (__wgdi__checkFolderIdChanged(gDriveFolderId, id) && !notRoot)){ 57 fetch(url) 58 .then(res => res.json()) 59 .then((object) => { 60 sessionStorage.setItem(storagePrefix + storageName, JSON.stringify(object)); 61 __wgdi__populateFileTree__output(gDriveFolderId, object, view, notRoot, firstFolder) 62 }) 63 .catch(err => { 64 //console.log(err); 65 if(view){view.innerHTML = 'Error loading Google Folder. Please enter a valid ID or make sure the folder has public access.'} 66 }); 67 }else{ 68 var object = JSON.parse(sessionStorage.getItem(storagePrefix + storageName)); 69 __wgdi__populateFileTree__output(gDriveFolderId, object, view, notRoot, firstFolder); 70 } 71 } 72} 73 74function __wgdi__populateFileTree__output(gDriveFolderId, object, view, notRoot, firstFolder) 75{ 76 let ul; 77 view.find('.view-loading').remove(); 78 if(view.find(".files-list").length < 1){ 79 ul = jQuery("<ul/>", {class: "files-list"}); 80 }else{ 81 view.find(".files-list").remove(); 82 ul = jQuery("<ul/>", {class: "files-list"}); 83 ul.empty(); 84 } 85 view.append(ul); 86 if(!notRoot){ 87 ul.addClass("list"); 88 } 89 ul.attr({id: gDriveFolderId, "by": view.attr("by"), "direction": view.attr("direction")}); 90 91 var showIcon = view.attr("showicon") != '' && view.attr("showicon") != 'false' ? true : false; 92 var showFilesize = view.attr("showfilesize") != '' && view.attr("showfilesize") != 'false' ? true : false; 93 var by = view.attr("by") != "date" ? view.attr("by") : "modifiedTime"; 94 var direction = view.attr("direction"); 95 96 for(let i in object){ 97 if(typeof object[i] === "object"){ 98 let files = object[i]; 99 //sort 100 if(direction == "asc"){ 101 files.sort((a, b) => (a[by] > b[by]) ? 1 : -1); 102 }
102else if(direction == "desc"){ 103 files.sort((a, b) => (a[by] < b[by]) ? 1 : -1); 104 } 105 for(let j in files){ 106 let file = files[j]; 107 let fileName = file.name; 108 if(fileName != ".DS_Store"){ 109 let mimeType = file.mimeType; 110 let fileSize = ''; 111 if(showFilesize) { 112 fileSize = file.size / 1000; 113 fileSize = fileSize < 1000 ? fileSize.toFixed(0) + " KB" : (fileSize / 1000).toFixed(1) + " MB"; 114 fileSize = " <span>.......... " + fileSize + "</span>"; 115 file.size = fileSize; 116 }else{ 117 file.size = ''; 118 } 119 file.customName = fileName + fileSize; 120 let li = jQuery("<li/>"); 121 const mimeFiles = ["image/png", "image/jpg", "image/jpeg", "application/pdf", "application/vnd.google-apps.file", "application/vnd.google-apps.document", "application/vnd.google-apps.presentation", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"]; 122 123 if(mimeFiles.includes(file.mimeType)){ //if is file 124 genFileIcon(file,li,ul); 125 }else if(file.mimeType == "application/vnd.google-apps.folder"){ //if is folder 126 genFolderIcon(view, file, li, ul, firstFolder); 127 }else if(file.mimeType == "application/vnd.google-apps.shortcut") {//if is a shortcut 128 const mimeType = file.shortcutDetails.targetMimeType; 129 if(mimeFiles.includes(mimeType)) { 130 file.mimeType = mimeType; 131 genFileIcon(file, li, ul); 132 }else{ 133 file.id = file.shortcutDetails.targetId; 134 genFolderIcon(view, file, li, ul, firstFolder) 135 } 136 } 137 } 138 } 139 } 140 } 141 142 function genFileIcon(file, li, ul) { 143 let iconDom; 144 let label = file.customName; 145 if(file.fileExtension){ 146 iconDom = showIcon ? __makeFileIcon(file.fileExtension, 'raw') : ''; 147 }else{ 148 iconDom = showIcon ? __makeFileIcon(file.mimeType, 'raw') : ''; 149 } 150 li.attr({type: "file", name: file.customName, date: file.modifiedTime, tabindex: 0}).append(iconDom, label).on("click", function(){ 151 window.open('https://drive.google.com/file/d/' + file.id + '/view'); 152 }); 153 ul.append(li); 154 } 155 156 function genFolderIcon(view, file, li, ul, firstFolder) { 157 let iconFolder = jQuery("<img/>", {class: "list-icon", src: imgPath + "/icon-folder-closed.svg"}); 158 li.attr({type: "folder", name: file.customName, date: file.modifiedTime, tabindex: 0, by: by, direction: direction}).append(iconFolder, file.name); 159 if(firstFolder) { 160 li.addClass('first-folder'); 161 } 162 ul.append(li); 163 if(parseInt(view.attr("expandfolder")) == 1){ 164 li.addClass("expand"); 165 iconFolder.attr("src", imgPath + "/icon-folder-open.svg"); 166 } 167 li.on('click', function(event){ 168 let li = jQuery(this); 169 li.find('ul').on('click', function(j){ 170 j.stopPropagation(); 171 }) 172 let expandClass = "expand"; 173 const empty = jQuery('<li/>', {class: 'empty-label'}).append('<small><em>(Empty)</em></small>'); 174 if(!li.hasClass(expandClass)){ 175 iconFolder.attr("src", imgPath + "/icon-folder-open.svg"); 176 li.addClass(expandClass); 177 if(li.find('ul').children().length < 1) { 178 li.find('ul').append(empty) 179 }else{ 180 if(li.find('ul > [type="folder"]').length > 0) { 181 const expandCollapseWrapper= jQuery('<div/>', {class: 'expandCollapseWrapper'}); 182 const expandBtn = jQuery('<button/>', {class: 'closed'}).append('+ Expand All').on('click', function(event) { expandCollapse(event, 'e', li); }); 183 const collapseBtn = jQuery('<button/>', {class: 'closed'}).append('- Collapse All').on('click', function(event) { expandCollapse(event, 'c', li); }); 184 if(li.parents('.first-folder').find('> .expandCollapseWrapper').length < 1) { 185 li.append(expandCollapseWrapper.append(expandBtn, collapseBtn)); 186 } 187 } 188 } 189 }else{ 190 iconFolder.attr("src", imgPath + "/icon-folder-closed.svg"); 191 li.removeClass(expandClass); 192 li.find('.empty-label, .expandCollapseWrapper').remove(); 193 } 194 }); 195 li.attr({'storageid': view.parents('section').data('id') + file.name, 'showicon': showIcon, 'showFilesize': file.size}); 196 __wgdi__populateFileTree(file.id, li, true, false); 197 } 198 199 function expandCollapse(e, action, li) { 200 e.stopPropagation(); 201 if(action == 'e') { 202 li.find('[type="folder"]').not('.expand').trigger('click'); 203 }else{ 204 li.find('[type="folder"]').filter('.expand').trigger('click'); 205 } 206 } 207} 208 209//File Buttons 210function __wgdi__populateFileButtons(gDriveFolderId, view, notRoot) 211{ 212 var id = view.attr('storageid'); 213 var storageName = 'file-buttons' + id; 214 if(gDriveFolderId){ 215 let googleAPIkey = gdi_drive_api_key; 216 let url = "https://www.googleapis.com/drive/v3/files?q='" + gDriveFolderId + "'+in+parents&fields=files(contentHints(indexableText,thumbnail/mimeType),createdTime,description,fileExtension,id,kind,thumbnailLink,mimeType,modifiedTime,name,parents,properties,size),kind&pageSize=1000&key=" + googleAPIkey; 217 218 //stores Google URL fetch result into storage so when 219 //properties are changed don't spam the Google API. 220 //sessionStorage is reseted after page reload 221 if((!sessionStorage.getItem(storagePrefix + storageName) || (!sessionStorage.getItem(storagePrefix + storageName) && !notRoot)) || (__wgdi__checkFolderIdChanged(gDriveFolderId, id) && !notRoot)){ 222 fetch(url) 223 .then(res => res.json()) 224 .then((object) => { 225 sessionStorage.setItem(storagePrefix + storageName, JSON.stringify(object)); 226 __wgdi__populateFileButtons__output(gDriveFolderId, object, view, notRoot) 227 }) 228 .catch(err => { 229 //console.log(err); 230 if(view){view.innerHTML = 'Error loading Google Folder. Please enter a valid ID or make sure the folder has public access.'} 231 }); 232 }else{ 233 var object = JSON.parse(sessionStorage.getItem(storagePrefix + storageName)); 234 __wgdi__populateFileButtons__output(gDriveFolderId, object, view, notRoot); 235 } 236 } 237} 238 239function __wgdi__populateFileButtons__output(gDriveFolderId, object, view, notRoot) 240{ 241 let div; 242 view.find('.view-loading').remove(); 243 if(view.find(".file-buttons").length < 1){ 244 div = jQuery("<div/>", {class: "file-buttons"}); 245 }else{ 246 view.find(".file-buttons").remove(); 247 div = jQuery("<div/>", {class: "file-buttons"}); 248 div.empty(); 249 } 250 view.append(div); 251 if(!notRoot){ 252 div.addClass("list"); 253 } 254 div.attr({id: gDriveFolderId, "by": view.attr("by"), "direction": view.attr("direction")}); 255 256 var showIcon = view.attr("showicon") != '' && view.attr("showicon") != 'false' ? true : false;
257 var showThumb = view.attr("showthumb") != '' && view.attr("showthumb") != 'false' ? true : false; 258 var thumbSize = view.attr("thumbsize"); 259 var showFilename = view.attr("showfilename") != '' && view.attr("showfilename") != 'false' ? true : false; 260 var showFilesize = view.attr("showfilesize") != '' && view.attr("showfilesize") != 'false' ? true : false; 261 var by = view.attr("by") != "date" ? view.attr("by") : "modifiedTime"; 262 var direction = view.attr("direction"); 263 var showToolTip = view.attr("showtip") != '' && view.attr("showtip") != 'false' ? true : false; 264 265 for(let i in object){ 266 if(typeof object[i] === "object"){ 267 let files = object[i]; 268 //sort 269 if(direction == "asc"){ 270 files.sort((a, b) => (a[by] > b[by]) ? 1 : -1); 271 }else if(direction == "desc"){ 272 files.sort((a, b) => (a[by] < b[by]) ? 1 : -1); 273 } 274 275 for(let j in files){ 276 let file = files[j]; 277 let fileName = file.name; 278 if(fileName != ".DS_Store"){ 279 let fileId = file.id; 280 let fileExt = file.fileExtension; 281 let mimeType = file.mimeType; 282 let fileModified = file.modifiedTime; 283 let fileSize = ''; 284 if(showFilesize) { 285 fileSize = file.size / 1000; 286 fileSize = fileSize < 1000 ? fileSize.toFixed(0) + " KB" : (fileSize / 1000).toFixed(1) + " MB"; 287 fileSize = " <span>(" + fileSize + ")</span>"; 288 }else{ 289 fileSize = ''; 290 } 291 const parseTitle = __wdgi__fileButtonParser(fileName); 292 let label = showFilename ? parseTitle.display + fileSize: ''; 293 294 295 if(mimeType != "application/vnd.google-apps.folder" || mimeType != "application/zip"){//if is file 296 if(!showThumb) { 297 let iconDom; 298 if(fileExt){ 299 iconDom = showIcon ? __makeFileIcon(fileExt, 'raw') : ''; 300 }else{ 301 iconDom = showIcon ? __makeFileIcon(mimeType, 'raw') : ''; 302 } 303 let buttonWrapper = jQuery("<div/>", {class: "file-button-wrapper"}); 304 let button = jQuery("<button/>", {class: "file-button", tabindex: "0"}); 305 let toolTip = jQuery("<div/>", {class: "tooltip"}).append(parseTitle.tip); 306 button.attr({type: "file", name: fileName, date: fileModified, tabindex: 0}); 307 if(showToolTip && parseTitle?.tip) { 308 buttonWrapper.append(toolTip); 309 } 310 buttonWrapper.append(button.append(iconDom, label)); 311 button.on("click", function(){ 312 window.open('https://drive.google.com/file/d/' + fileId + '/view'); 313 }); 314 div.append(buttonWrapper); 315 }else{ 316 let thumbnailWrapper; 317 let thumbLink; 318 let thumbnail; 319 if(file?.thumbnailLink) { 320 321 thumbnailWrapper = jQuery("<div/>", {class: "thumbnail"}); 322 thumbLink = thumbSize == 'thumb-small' ? file.thumbnailLink.replace(/=s\d+$/, '=s400') : thumbSize == 'thumb-medium' ? file.thumbnailLink.replace(/=s\d+$/, '=s600') : thumbSize == 'thumb-large' ? file.thumbnailLink.replace(/=s\d+$/, '=s800') : file.thumbnailLink; 323 if(showThumb ) { 324 //loader 325 let loader = jQuery("<small/>", {class: ""}).append('Loading preview...'); 326 thumbnailWrapper.append(loader); 327 thumbnail = jQuery("<img/>", {src: thumbLink}).on('load', () => { 328 loader.remove(); 329 thumbnailWrapper.append(thumbnail) 330 }) 331 } 332 333 334 thumbnailWrapper.on("click", function(){ 335 window.open('https://drive.google.com/file/d/' + fileId + '/view'); 336 }); 337 label = jQuery("<div/>").append(label); 338 div.append(thumbnailWrapper.append(label)); 339 } 340 } 341 } 342 } 343 } 344 } 345 } 346} 347 348function __wdgi__fileButtonParser(text) { 349 const regex = /^(.*?)\s*\((.*?)\)(\..*)$/; 350 const matches = text.match(regex); 351 352 if (matches) { 353 // const outsideText = matches[1]; // "long file name title" 354 // const insideText = matches[2]; // "short title" 355 // const extension = matches[3]; // ".pdf" 356 return {display: matches[1], tip: matches[2]} 357 } else { 358 return {display: text} 359 } 360} 361 362function __wgdi__populateTableList(gDriveFolderId, view) 363{ 364 view.find('.view-loading').remove(); 365 var id = view.attr('storageid'); 366 var storageName = 'file-tree' + id; 367 if(gDriveFolderId){ 368 let googleAPIkey = gdi_drive_api_key; 369 let url = "https://www.googleapis.com/drive/v3/files?pageSize=1000&q='" + gDriveFolderId + "'+in+parents&fields=files(contentHints(indexableText,thumbnail/mimeType),createdTime,description,fileExtension,id,kind,mimeType,modifiedTime,name,parents,properties,size),kind&pageSize=1000&key=" + googleAPIkey; 370 371 //stores Google URL fetch result into storage so when 372 //properties are changed don't spam the Google API. 373 //sessionStorage is reseted after page reload 374 if(!sessionStorage.getItem(storagePrefix + storageName) || __wgdi__checkFolderIdChanged(gDriveFolderId, id)){ 375 fetch(url) 376 .then(res => res.json()) 377 .then((object) => { 378 sessionStorage.setItem(storagePrefix + storageName, JSON.stringify(object)); 379 __wgdi__populateTableList__output(object, view); 380 }) 381 .catch(err => { 382 console.log(err); 383 //if(view){ul.innerHTML = 'Error loading Google Folder. Please enter a valid ID or make sure the folder has public access.'} 384 }); 385 }else{ 386 var object = JSON.parse(sessionStorage.getItem(storagePrefix + storageName)); 387 __wgdi__populateTableList__output(object, view); 388 } 389 } 390} 391 392function __wgdi__populateTableList__output(object, view) { 393 view.find('.view-loading').remove(); 394 var headers = [ 395 { 396 name: 'Filename', 397 sort: { 398 compare: (a, b) => { 399 const getText = function(x) { 400 return jQuery(x.props.content).find('span').html(); 401 } 402 if( getText(a) > getText(b)) { 403 return 1; 404 }else if( getText(b) > getText(a) ) { 405 return -1; 406 }else{ 407 return 0; 408 } 409 } 410 } 411 }, 412 { 413 name: 'Date', 414 sort: { 415 compare: (a, b) => { 416 const stamp = function(x) { 417 return __wgdi__toTimestamp(x); 418 } 419 if( stamp(a) > stamp(b)) { 420 return 1; 421 }else if( stamp(b) > stamp(a) ) { 422 return -1; 423 }else{ 424 return 0; 425 } 426 } 427 }, 428 hidden: view.attr('showdate') ? false : true 429 }, 430 { 431 name: 'Size', 432 sort: { 433 compare: (a, b) => { 434 const base = function(x) { 435 var splice = x.split(' '); 436 if(splice[1] == 'KB') { 437 return splice[0] * 1000; 438 }else if(splice[1] == 'MB') { 439 return splice[0] * 1000000; 440 } 441 } 442 if( base(a) > base(b)) { 443 return 1; 444 }else if( base(b) > base(a) ) { 445 return -1; 446 }else{ 447 return 0; 448 } 449 } 450 }, 451 hidden: view.attr('showFilesize') ? false : true 452 }]; 453 var data = []; 454 var row = []; 455 456 var showIcon = view.attr("showicon") ? true : false;
457 458 //presort data based on settings 459 if(view.attr('by') != '' || typeof view.attr('by') != 'undefined') { 460 object.files.sort(function (a, b) { 461 var by = view.attr('by') ? view.attr('by') : 'name'; 462 if(view.attr('direction') == 'asc') { 463 return a[by].localeCompare(b[by]); 464 }else{ 465 return b[by].localeCompare(a[by]); 466 } 467 }); 468 } 469 470 jQuery.each(object.files, function(i, val){ 471 var itemId = val.id; 472 var itemName = val.name; 473 var itemExt = val.fileExtension; 474 var itemLink = "https://drive.google.com/file/d/" + itemId + "/view"; 475 var mimeType = val.mimeType; 476 var fileSize = val.size / 1000; 477 fileSize = fileSize < 1000 ? fileSize.toFixed(0) + " KB" : (fileSize / 1000).toFixed(1) + " MB"; 478 var fileDateTimestamp = __wgdi__toTimestamp(val.createdTime); 479 var fileDateLamens = __wgdi__timestampToDate(val.createdTime, "MMM DD, YYYY"); 480 if(mimeType != "application/vnd.google-apps.folder"){ 481 var icon = showIcon ? __makeFileIcon(itemExt, 'raw') : ''; 482 var link = gridjs.html("<a href='" + itemLink + "' target='_blank'>" + icon + "<span>" + itemName + "</span></a>"); 483 var row = [link, fileDateLamens, fileSize]; 484 data.push(row); 485 } 486 }); 487 488 var options = { 489 columns: headers, 490 data: data, 491 sort: true, 492 resizable: false, 493 search: { 494 enabled: view.attr('searchable') 495 }, 496 pagination: { 497 enabled: view.attr('paginate'), 498 limit: view.attr('paginate-limit'), 499 summary: true 500 } 501 } 502 503 var tableWrapper = jQuery("<div/>", {class: "datatable-wrapper"}); 504 view.append(tableWrapper); 505 var table = new gridjs.Grid(options).render(tableWrapper[0]); 506} 507 508function __wgdi__populateBoardPolicy(gDriveFolderId, view, notRoot) 509{ 510 var id = view.attr('storageid'); 511 var storageName = 'file-tree' + id; 512 if(gDriveFolderId){ 513 let googleAPIkey = gdi_drive_api_key; 514 let url = "https://www.googleapis.com/drive/v3/files?q='" + gDriveFolderId + "'+in+parents&fields=files(contentHints(indexableText,thumbnail/mimeType),createdTime,description,fileExtension,id,kind,mimeType,modifiedTime,name,parents,properties,size),kind&pageSize=1000&key=" + googleAPIkey; 515 //stores Google URL fetch result into storage so when 516 //properties are changed don't spam the Google API. 517 //sessionStorage is reseted after page reload 518 if(!sessionStorage.getItem(storagePrefix + storageName) || __wgdi__checkFolderIdChanged(gDriveFolderId, id)){ 519 fetch(url) 520 .then(res => res.json()) 521 .then((object) => { 522 sessionStorage.setItem(storagePrefix + storageName, JSON.stringify(object)); 523 __wgdi__populateBoardPolicy__output(gDriveFolderId, object, view) 524 }) 525 .catch(err => { 526 //console.log(err); 527 var message = "ERROR: The files below have incorrect Board Policy formatting and will display incorrectly. Please follow <a href='https://drive.google.com/open?id=1I4XdmS2pW8Tu0T8ROkvyXo94cUOmXYftcOP3-TUj7ig' target='_blank'>this guide.</a><br/><br/>"; 528 }); 529 //return false; 530 }else{ 531 var object = JSON.parse(sessionStorage.getItem(storagePrefix + storageName)); 532 __wgdi__populateBoardPolicy__output(gDriveFolderId, object, view); 533 } 534 } 535} 536 537function __wgdi__populateBoardPolicy__output(gDriveFolderId, object, view) 538{ 539 view.find('.view-loading').remove(); 540 if(view.find(".files-list").length > 0){ 541 view.find(".files-list").remove() 542 }; 543 544 var table = jQuery("<table/>", {class: "files-list board-policy"}); 545 var heading = "<thead><tr>\ 546 <th>Series Number</th>\ 547 <th>Article Title</th>\ 548 </tr></thead>"; 549 550 var body = jQuery("<tbody/>"); 551 552 var fileArray = {}; 553 var error = ""; 554 jQuery.each(object.files, function(key, val){ 555 var itemId = val.id; 556 var itemName = val.name; 557 var itemExt = val.fileExtension; 558 var mimeType = val.mimeType; 559 if(mimeType != "application/vnd.google-apps.folder"){ 560 //var itemLink = "/file/drive/" + itemId + "/" + encodeURIComponent(string_to_slug(itemName)).replace(/\(/g, "%28").replace(/\)/g, "%29"); 561 var itemLink = "https://drive.google.com/file/d/" + itemId + "/view"; 562 //checkfor correct regex format 563 var regex = /^(\w)+(\s){1}([\w\d\.])+(\s){1}(-)/; 564 if(!itemName.match(regex)){ 565 error += "<li>" + itemName + "</li>"; 566 }else{ 567 //process arrays 568 var nameSplit = itemName.split(/\s-(.+)/);//split filename into Series Number & Filename 569 570 var seriesNumber = nameSplit[0]; 571 var seriesNumberSplit = seriesNumber.split(" ");//split the Series Number to Letter & Number 572 var seriesNumberOnly = seriesNumberSplit[1].match(/[a-z]+|[^a-z]+/gi); 573 var version = typeof seriesNumberOnly[1] == "undefined" ? "" : seriesNumberOnly[1]; 574 seriesNumberOnly = seriesNumberOnly[0]; 575 var seriesLetterOnly = seriesNumberSplit[0]; 576 var articleName = nameSplit[1].trim(); 577 var subArray = {itemId, articleName, seriesLetterOnly, seriesNumberOnly, version, itemLink}; 578 579 if(!(seriesNumberOnly in fileArray)){ 580 fileArray[seriesNumberOnly] = []; 581 fileArray[seriesNumberOnly].unshift(subArray); 582 }else{ 583 fileArray[seriesNumberOnly].unshift(subArray); 584 } 585 } 586 } 587 588 }); 589 var fileArraySorted = (Object.keys(fileArray)).sort(__wgdi__sortNumerically); 590 var groupClass = "group-a"; 591 for(const key of fileArraySorted){
592 var val = fileArray[key]; 593 var seriesNumber = ""; 594 var articleName; 595 596 //split each series letter into their own groups so they can be sorted correctly 597 var bpArray = []; 598 var arArray = []; 599 var verArray = []; 600 jQuery.each(val, function(i, val){ 601 switch (val.seriesLetterOnly.__wgdi__capitalize()) { 602 case "BP": 603 case "BB": 604 bpArray.push(val); 605 break; 606 case "AR": 607 arArray.push(val); 608 break; 609 default: 610 verArray.push(val); 611 break; 612 } 613 }); 614 615 //sorting each array group 616 var orderedArray = []; 617 bpArray.sort(function(a, b){ 618 if(a.articleName > b.articleName) { return -1; } 619 if(a.articleName < b.articleName) { return 1; } 620 return 0; 621 }); 622 jQuery.each(bpArray, function(i, row){ 623 orderedArray.push(row); 624 }); 625 arArray.sort(function(a, b){ 626 if(a.articleName > b.articleName) { return -1; } 627 if(a.articleName < b.articleName) { return 1; } 628 return 0; 629 }); 630 jQuery.each(arArray, function(i, row){ 631 orderedArray.push(row); 632 }); 633 verArray.sort(function(a, b){ 634 if(a.version < b.version) { return -1; } 635 if(a.version > b.version) { return 1; } 636 return 0; 637 }); 638 jQuery.each(verArray, function(i, row){ 639 orderedArray.push(row); 640 }); 641 642 var tempNumber = ""; 643 var tempName = ""; 644 var row = ""; 645 jQuery.each(orderedArray, function(i, val){ 646 articleName = val.articleName.split(/\.(.+)/)[0]; 647 if(tempName == articleName){ 648 row += "<tr class='" + groupClass + "' data-id='" + val.itemId + "' onclick='window.open(\"" + val.itemLink + "\")'><td>" + val.seriesLetterOnly + " " + val.seriesNumberOnly + val.version + "</td><td> " + articleName + "</td></tr>"; 649 }else if(tempName != articleName && tempNumber == val.seriesNumberOnly){ 650 row += "<tr class='" + groupClass + " no-border' data-id='" + val.itemId + "' onclick='window.open(\"" + val.itemLink + "\")'><td>" + val.seriesLetterOnly + " " + val.seriesNumberOnly + val.version + "</td><td> " + articleName + "</td></tr>"; 651 }else{ 652 row += "<tr class='" + groupClass + " new' data-id='" + val.itemId + "' onclick='window.open(\"" + val.itemLink + "\")'><td>" + val.seriesLetterOnly + " " + val.seriesNumberOnly + val.version + "</td><td> " + articleName + "</td></tr>"; 653 } 654 tempNumber = val.seriesNumberOnly; 655 tempName = articleName; 656 }); 657 658 body.append(row); 659 groupClass = groupClass == "group-a" ? "group-b" : "group-a"; 660 }; 661 var tableWrapper = jQuery("<div/>", {class: "datatable-wrapper"}); 662 table.append(heading, body); 663 view.append(tableWrapper.append(table)); 664 table.dataTable({ 665 "bPaginate": false, 666 "sPaginationType": "full_numbers", 667 "pageLength": 1000, 668 "asStripeClasses": [], 669 "bSort": false 670 }); 671 if(error != ""){ 672 var message = "ERROR: The files below have incorrect Board Policy formatting and will display incorrectly. Please follow <a href='https://drive.google.com/open?id=1I4XdmS2pW8Tu0T8ROkvyXo94cUOmXYftcOP3-TUj7ig' target='_blank'>this guide.</a><br/><br/>"; 673 alertify.alert(message + "<ul>" + error + "</ul>"); 674 } 675 //__wgdi__sortDocuments(ul); 676} 677 678function __wgdi__toggleSearchable(parentDom, val) 679{ 680 val = !val ? parentDom.attr("searchable") : val; 681 val = parseInt(val); 682 var searchBox = parentDom.find('input.searchbox').length > 0 ? parentDom.find('.searchbox') : jQuery('<input/>', {type: 'text', class: 'searchbox', placeholder: 'type to search'}); 683 684 if(val){ 685 parentDom.find("ul.list").before(searchBox); 686 __wgdi__makeSearchable(searchBox, parentDom); 687 }else{ 688 searchBox.remove(); 689 } 690} 691 692function __wgdi__makeSearchable(search, view) 693{ 694 search.keyup(function(){ 695 var e = jQuery(this); 696 var searchTerms = e.val(); 697 view.find('li').each(function() { 698 var e = jQuery(this); 699 var hasMatch = searchTerms.length == 0 || e.html().toLowerCase().indexOf(searchTerms.toLowerCase()) > 0; 700 e.toggle(hasMatch); 701 hasMatch ? e.addClass("search-open") : e.removeClass("search-open"); 702 if(searchTerms.length == 0){ 703 e.removeClass("search-open"); 704 } 705 }); 706 }); 707} 708 709function __wgdi__makeId(range) 710{ 711 var text = ""; 712 var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; 713 714 for (var i = 0; i < range; i++) 715 text += possible.charAt(Math.floor(Math.random() * possible.length)); 716 717 return text; 718} 719 720function __makeFileIcon(fileExt, exportType) 721{ 722 let icon = "icon-file.svg"; //generic 723 switch (fileExt) { 724 case "pdf": 725 case "application/pdf": 726 icon = "icon-pdf.svg"; 727 break; 728 case "docx": 729 case "doc": 730 case "application/vnd.google-apps.document": 731 icon = "icon-word.svg"; 732 break; 733 case "xls": 734 case "xlsx": 735 case "application/vnd.google-apps.spreadsheet": 736 icon = "icon-excel.svg"; 737 break; 738 case "zip": 739 icon = "icon-zip.svg"; 740 break; 741 case "pptx": 742 case "application/vnd.google-apps.presentation": 743 icon = "icon-pptx.svg"; 744 break; 745 case "jpeg": 746 case "jpg": 747 case "png": 748 icon = "icon-img.svg"; 749 break; 750 } 751 if(exportType == 'raw') { 752 return iconRaw = "<img class='list-icon' src='" + imgPath + "/" + icon + "'/>"; 753 }else if(exportType == 'dom') { 754 return iconDom = jQuery("<img/>", {class: "list-icon", src: imgPath + "/" + icon}); 755 } 756}
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.