1$(function(){ 2 // App globals 3 if(/site=([^&]+)/.test(window.location.href)){ 4 var site = window.location.href.match(/site=([^&]+)/)[1]; // automatically set site based on staging url. 5 }else{ 6 var site = 'www'; // default to www if fails to retreive from staging url. 7 } 8 var thisScriptsPath = $('script[src*="select-lists.js"]').attr('src').replace('select-lists.js', ''); // set the path of this script so we can determine the path of the JSON files. 9 var JSONPath = thisScriptsPath + 'json/'; // path where the JSON data files are kept. 10 var APIJSONPath = window.location.origin + '/files/source?site=' + site + '&path=' + encodeURIComponent(JSONPath); // OU API path for retrieving JSON files from staging 11 var JSONfileExt = 'json'; // JSON data file extension. 12 var selectLists = {}; // this stores the html code for each select lists. 13 var defaultText = 'Nothing'; // this is used when an option is set to empty string. 14 var suppressAlertMessages = false; // used to suppress future alert messages after an alert message is displayed. 15 16 // Event listeners [START] 17 $('body').on('mouseenter', 'table[class^="ou-"]', function(){ 18 /* 19 A mouseenter event is used to trigger the loading of the select list data via ajax when 20 the mouse enters over a table transformation. This is necessary since the table transformation 21 markup is not part of the DOM until an editable region edit button is clicked. I felt this 22 method is more reliable then using the domSubtreeModified event. 23 */ 24 loadSelectLists(); 25 disableKeyboardEntry(); 26 trimContent(); 27 }); 28 29 $('body').on('click', 'table[class^="ou-"] [data-select-list]', function(){ 30 if($(this).children('ul.ou-select-list').length) return; // if a select list is already open for this cell then just return. 31 32 // retrieves the current value, loads the specified select list, adds an active class to the option that matches the current value and scrolls to the location of that option. 33 var selectList = $(this).data('select-list'); 34 var selectedOption = trim($(this).text()); 35 setOption(); // run setOption() to close any open select lists before opening this new one. 36 37 if(selectLists[selectList] == '') return; // No select list content so just return. 38 39 $(this).html(selectLists[selectList]); 40 $('ul.ou-select-list li[data-value="' + selectedOption + '"]').addClass('active'); 41 42 if(!$('ul.ou-select-list li.active').length){ 43 $('ul.ou-select-list li:first').addClass('active'); 44 } 45 46 if (/Edge\/\d./i.test(navigator.userAgent)){ 47 /* 48 On Microsoft Edge apply this workaround so that the scroll to active feature will work. Microsoft tries to "help" 49 by automatically scrolling to the cursor position. So let's trigger the autoscroll to happen again after a half second. 50 */ 51 setTimeout(function(){ 52 $('ul.ou-select-list').scrollTop($('ul.ou-select-list').scrollTop() + $('ul.ou-select-list li.active').position().top); // automatically scroll to selected option. 53 }, 500); 54 } 55 56 $('ul.ou-select-list').scrollTop($('ul.ou-select-list').scrollTop() + $('ul.ou-select-list li.active').position().top); // automatically scroll to selected option. 57 58 $('ul.ou-select-list li').on('click', function(){ 59 $('ul.ou-select-list li.active').removeClass('active'); 60 $(this).addClass('active'); 61 setOption(); 62 }); 63 }); 64 65 $(document).click(function(e) { 66 // this closes the select list whenever the user clicks anywhere outside of it. 67 var target = e.target; 68 69 if (!$(target).is('table[class^="ou-"] [data-select-list]') && !$(target).parents().is('table[class^="ou-"] [data-select-list]')) { 70 setOption(); 71 } 72 }); 73 // Event listeners [END] 74 75 // App specific functions [START] 76 function loadSelectLists(){ 77 // retrieves list data for the all the select lists via inline, js include or ajax declaration methods. Then it builds the html code and caches it in a variable named "selectLists". 78 $('[data-select-list]').each(function() { 79 var selectList = $(this).data('select-list'); 80 if(!selectLists.hasOwnProperty(selectList)){ 81 selectLists[selectList] = ''; 82 83 if(selectList.split(',').length > 1){ // "Inline" list declaration method used since commas exist in data attribute value. 84 selectLists[selectList] = buildSelectList(selectList.split(','), '{{text}}'); // no default lineTemplate declared when inline method is used so just set to {{text}}. 85 }else{ // "JSON Files" list declaration method is the default if inline method is not used. 86 $.getJSON(APIJSONPath + selectList + '.' + JSONfileExt, function(data){ 87 data = $.parseJSON(data.source); // OU API returns the files source wrapped in JSON so we now need to grab the source keys value and parse the value to JSON. 88 if('path' in data){ 89 getOptionsByPath(selectList, data); 90 }else{ 91 selectLists[selectList] = buildSelectList(data.options, ('lineTemplate' in data) ? data.lineTemplate : '{{text}}'); 92 } 93 }).fail(function(data){
94 if(!suppressAlertMessages && data.responseJSON.code == 'ACCESS_DENIED'){ 95 suppressAlertMessages = true; // suppress future alert messages. 96 alert('Unable to load Select List data due to access restrictions.\n\nPlease ask your administrator to change the Access Group to "Everyone" for: ' + JSONPath); 97 } 98 }); 99 } 100 } 101 }); 102 } 103 104 function disableKeyboardEntry(){ 105 if(tinyMCE.activeEditor.OU == undefined || tinyMCE.activeEditor.OU.keyboardEntryDisabled != true){ 106 tinyMCE.activeEditor.on('keydown', function(e){ 107 if($(e.target).find('ul.ou-select-list').length){ 108 e.preventDefault(); 109 } 110 111 if($(tinyMCE.activeEditor.selection.getNode()).is('[data-select-list]')){ 112 e.preventDefault(); 113 } 114 }); 115 116 tinyMCE.activeEditor["OU"] = {'keyboardEntryDisabled': true}; 117 } 118 } 119 120 function trimContent(){ 121 $('table[class^="ou-"] [data-select-list]').filter(function(){ 122 return (trim($(this).text()) == ''); 123 }).html(''); 124 } 125 126 function getOptionsByPath(selectList, data){ 127 var options = [':' + defaultText + ':{{text}}']; // Make sure to include an empty option to start off with. 128 $.getJSON(window.location.origin + '/files/list?site=' + site + '&path=' + escape(data.path) + '&images=true', function(fileData){ 129 fileData = fileData.entries; // we only need the entries property 130 for(var i=0; i<fileData.length; i++){ 131 if(!fileData[i].is_directory){ 132 options.push(fileData[i].remote_path + ':' + escape(fileData[i].http_path)); 133 } 134 } 135 136 selectLists[selectList] = buildSelectList(options, ('lineTemplate' in data) ? data.lineTemplate : '{{text}}'); 137 }); 138 } 139 140 function buildSelectList(options, defaultLineTemplate){ 141 // builds the select list html code 142 143 if(!Array.isArray(options) || options.length == 0) return ''; // If options argument is not an array then just return empty string. 144 145 var selectListHTML = '<ul class="ou-select-list">'; 146 for(var i=0; i<options.length; i++){ 147 var aOption = options[i].split(':'); 148 var value = trim(aOption[0]); 149 var text = trim(aOption[0]); 150 var lineTemplate = defaultLineTemplate; 151 152 if(aOption.length > 1){ 153 // text was included in data so use it 154 text = trim(aOption[1]); 155 } 156 157 value = unescape(value); 158 text = unescape(text); 159 160 if(aOption.length == 3){ 161 // lineTemplate was included in data so use it. 162 lineTemplate = trim(aOption[2]); 163 } 164 165 if(text == '') text = defaultText; // Set display text to defaultText if it's an empty string. 166 167 selectListHTML += '<li data-value="' + value + '">' + lineTemplate.replace(/{{value}}/g, value).replace(/{{text}}/g, text) + '</li>'; 168 } 169 selectListHTML += '</ul>'; 170 return selectListHTML; 171 } 172 173 function setOption(){ 174 $('ul.ou-select-list').each(function(){ 175 $(this).closest('td').text(trim($(this).find('li.active').data('value'))); 176 }); 177 } 178 // App specific functions [END] 179 180 // Utility functions 181 function trim(s){ 182 return s.toString().replace(/^\s+|\s+$/g, ''); 183 } 184 185}); 186 187 188$(function(){function t(){return!e(this).is('[data-table-separator-options~="disable"]')}function e(t){var e=$(t).parent().closest("[data-table-separator-options]");return e.length||(e=$(t).closest(".ou-justedit-region").prevAll().filter("ouc\\:div").first()),e}$("body").on("click",".ou-table-separator",function(){var t=$(this),a=e(this).is('[data-table-separator-options~="clone"]'),o=e(this).is('[data-table-separator-options~="empty"]');a?(t.prev().length?$clone=t.prev().clone():$clone=t.next().clone(),o&&$clone.find("td").not(":has(> table)").text(" "),$clone.hide(),t.replaceWith($clone.fadeIn())):(t.replaceWith('<p><br data-mce-bogus="1" data-focus-me="1"></p>'),tinyMCE.activeEditor.selection.select(tinyMCE.activeEditor.dom.select("[data-focus-me]")[0]),$("[data-focus-me]").removeAttr("data-focus-me"),tinyMCE.activeEditor.selection.collapse(!1)),tinyMCE.activeEditor.isNotDirty=!1}),$("body").on("mouseenter",".ou-justedit-region",function(){$(".ou-justedit-region table:first-child, .ou-justedit-region table + table").filter(t).before('<div class="ou-table-separator mceNonEditable" data-mce-contenteditable="false" data-mce-bogus="1"></div>'),$(".ou-justedit-region table:last-child").filter(t).after('<div class="ou-table-separator mceNonEditable" data-mce-contenteditable="false" data-mce-bogus="1"></div>');var a=$(".ou-table-separator + .ou-table-separator");a.prev().remove(),a.filter(function(){return!e(this).is('[data-table-separator-options~="clone"]')}).replaceWith('<p><br data-mce-bogus="1"></p>'),$("div.ou-table-separator > table").each(function(){var t=$(this).parent();t.replaceWith(t.html())})})});
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.