// A script for Clover Theme Manager // Copyright (C) 2014-2017 Blackosx // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // //Version=0.76.8 var gTmpDir = "/tmp/CloverThemeManager"; var gLogBashToJs = "bashToJs"; var gInstalledThemeListStr=""; // This is used for drawing upper shadow on installed theme bands var gUpdateThemeListStr=""; // This is used for drawing upper shadow on update theme bands //------------------------------------------------------------------------------------- // On initial load $(document).ready(function() { SetListingThemesMessageAndProgressBarPosition(); disableInterface(); hideButtons(); HideProgressBar(); readBashToJsMessageFile(); ResetButtonsAndBandsToDefault(); HideUpdateAllButton(); }); //------------------------------------------------------------------------------------- // Listen to keyboard document.addEventListener('keydown', function(event) { // Only continue if the keystroke was not combined with the Command key if (!event.metaKey) { // Check for key press 0-9 or A-Z and scroll to nearest theme based on key pressed. if ((event.keyCode >= 48 && event.keyCode <= 57) || (event.keyCode >= 65 && event.keyCode <= 90 )) { var keyPressed = event.keyCode; var searchKey = String.fromCharCode(keyPressed); // find lowercase key also if (event.keyCode >= 65 && event.keyCode <= 90 ) { var searchKeyLowerCase = String.fromCharCode(keyPressed + 32) } else { var searchKeyLowerCase = searchKey; } // Loop through each theme name and find first $('.themeTitle').each(function(){ // get text before first
var splitter = $(this).html().split('
'); // Compare first char of theme name if ( splitter[0].charAt(0) == searchKey || splitter[0].charAt(0) == searchKeyLowerCase ) { var firstThemeEntry = $("#ThemeBand").first(); var posfirstThemeEntry = firstThemeEntry.position(); // in relation to bottom of header. 0 = Alienware. 52 = BGM, christmas = 390, mac = 858 var thisThemeEntry = $(this).closest("#ThemeBand"); var offset = thisThemeEntry.offset(); $('#content').animate({ scrollTop: offset.top - 99 - posfirstThemeEntry.top }); return false; // stop. don't continue looping through the each } }) } // Check for left arrow if ( event.keyCode == 37 ) { // Check if large expanded previews are shown if ($("#preview_Toggle_Button").text().indexOf("Collapse") >= 0) { SetShowHidePreviews("Hide"); // Send a message to the bash script to record user choice in prefs macgap.app.launch("CTM_hidePreviews"); } else { ChangeThumbnailSize('smaller'); // Check for visible thumbnails var showHideButtonText = $("#BandsHeightToggleButton").text(); var currentThumbWidth = $(".thumbnail img").first().width(); if (currentThumbWidth == 100 ) { SetThemeBandHeight("Hide"); // Send a message to the bash script to record user choice in prefs macgap.app.launch("CTM_showThumbails"); } } } // Check for right arrow if ( event.keyCode == 39 ) { // Check for visible thumbnails var showHideButtonText = $("#BandsHeightToggleButton").text(); if (showHideButtonText.indexOf("Show") >= 0) { SetThemeBandHeight("Show"); // Send a message to the bash script to record user choice in prefs macgap.app.launch("CTM_hideThumbails"); } else { // Are thumbnails already at largest size? if ( $(".thumbnail img").first().width() == 175 ) { // Show Expanded previews SetShowHidePreviews("Show"); // Send a message to the bash script to record user choice in prefs macgap.app.launch("CTM_showPreviews"); } else { ChangeThumbnailSize('larger'); } } } // End Button - Scroll to bottom if ( event.keyCode == 35 ) { $("#content").animate({ scrollTop: $('#content').prop("scrollHeight")}, 1000); } // Home Button - Scroll to top if ( event.keyCode == 36 ) { $('#content').animate({ scrollTop: 0 }, 'slow'); } // Check for Enter / Return key if ( event.keyCode == 13 ) { focusedItem=$("*:focus").attr("id"); switch(focusedItem) { case "BootLogTitleBar": ActionShowHideBootlog(); break; case "RefreshButton": $('#partitionSelect').change(); break; case "OpenButton": macgap.app.launch("OpenPath"); break; case "EspButton": ActionMountESP(); break; case "BandsHeightToggleButton": ActionShowHideThumbnailsButton(); break; case "thumbSizeSmaller": ChangeThumbnailSize('smaller'); break; case "thumbSizeLarger": ChangeThumbnailSize('larger'); break; case "preview_Toggle_Button": ActionShowHideExpandedPreviews(); break; case "ShowHideUpdateAllButton": ActionUpdateAll(); break; case "ShowHideToggleButton": ActionShowHideInstalledThemes(); break; case "content": break; case "installedThemeDropDownNvram": ActionChangedDropDownNvram(); break; case "installedThemeDropDownNvram": ActionChangedDropDownConfigP(); break; default: // code to be executed if n is different from case 1 and 2 } // Is messagebox showing? // Read position of box to see where it is var position = $('#box').position(); if (position.top > 0) { CloseMessageBox(); enableInterface(); } } } else { // Command key was also pressed // Check for upper case or lower case e if ((event.keyCode == 69) || (event.keyCode == 101)) { ActionShowHideExpandedPreviews(); } // Check for upper case or lower case i if ((event.keyCode == 73) || (event.keyCode == 105)) { ActionShowHideInstalledThemes(); } // Check for upper case or lower case r if ((event.keyCode == 82) || (event.keyCode == 114)) { $('#partitionSelect').change(); } } }); //------------------------------------------------------------------------------------- // Called when the process is to close. function terminate() { clearTimeout(timerReadMessageFile); macgap.notice.close("*"); // Remove all notifications sent by app macgap.app.terminate(); } //------------------------------------------------------------------------------------- // looks for a file and if found, returns the contents function GetFileContents(filename) { xmlhttp = new XMLHttpRequest(); xmlhttp.open("GET",gTmpDir+"/"+filename,false); xmlhttp.send(null); fileContent = xmlhttp.responseText; if (fileContent != "" ) { return fileContent; } else { return 0; } } /* // Called when returning back from help page //------------------------------------------------------------------------------------- $(window).bind("pageshow", function(event) { if (event.originalEvent.persisted) { alert("From bfcache"); // check if macgap API works or generates an error if ('macgap.app.launch' in window) { try { alert("trying"); } catch (e) { alert("catch"); } alert("macgap working"); } else { try { alert("trying"); macgap.app.activate(); } catch (e) { alert("catch"); } alert("macgap not working"); //window.location.reload(); } } }); */ //------------------------------------------------------------------------------------- // Check for incoming messages from bash script function readBashToJsMessageFile() { incoming=GetFileContents(gLogBashToJs); if (incoming != 0) { // Split settings by newline var incoming = incoming.split('\n'); // Take first line var firstLine = (incoming[0]); // Split firstLine by @ var firstLineSplit = (firstLine).split('‡'); var firstLineCommand = (firstLineSplit[0]); // match command against known ones. switch(firstLineCommand) { case "Target": // Bash sends: "Target@$entry" macgap.app.removeMessage(firstLine); setTargetThemePath(firstLineSplit[1]); break; case "NotExist": // Bash Sends: "NotExist@${TARGET_THEME_DIR_DEVICE}@${TARGET_THEME_DIR}@entry" macgap.app.removeMessage(firstLine); presentNotExistsDialog(firstLineSplit[1],firstLineSplit[2],firstLineSplit[3]); break; case "InstalledThemes": // Bash sends: "InstalledThemes@${installedThemeStr}@" // where $installedThemeStr is a comma separated string. macgap.app.removeMessage(firstLine); updateBandsWithInstalledThemes(firstLineSplit[1]); // remember installed theme list gInstalledThemeListStr=firstLineSplit[1]; // Honour users choice of which themes to view (All or just Installed) GetShowHideButtonStateAndUpdateUI(); break; case "FreeSpace": // Bash sends: "FreeSpace@${freeSpace}@" macgap.app.removeMessage(firstLine); actOnFreeSpace(firstLineSplit[1]); break; case "UpdateAvailThemes": // Bash sends: "UpdateAvailThemes@${updateAvailThemeStr}@" // where $updateAvailThemeStr is a comma separated string. macgap.app.removeMessage(firstLine); hideCheckingThemeUpdateProgressBar(); ShowThemeUpdatesAvailableMessage(firstLineSplit[1]); ShowUpdateThemesInUI(firstLineSplit[1]); // remember installed theme list gUpdateThemeListStr=firstLineSplit[1]; break; case "UnversionedThemes": // Bash sends: "UnversionedThemes@${unversionedThemeStr}@" macgap.app.removeMessage(firstLine); displayUnversionedThemes(firstLineSplit[1]); break; case "Nvram": // Bash sends: "Nvram@${themeName}@" macgap.app.removeMessage(firstLine); SetCurrentThemeEntry("Nvram",firstLineSplit[1]); break; //case "NvramP": // Bash sends: "NvramP@${themeName}@" //macgap.app.removeMessage(firstLine); //SetCurrentThemeEntry("NvramP",firstLineSplit[1]); //break; case "ConfigP": // Bash sends: "ConfigP@${themeName}@" macgap.app.removeMessage(firstLine); SetCurrentThemeEntry("ConfigP",firstLineSplit[1]); break; case "Success": // Bash sends: "Success@${passedAction}@$themeTitleToActOn" macgap.app.removeMessage(firstLine); themeActionSuccess(firstLineSplit[1],firstLineSplit[2]); break; case "UpdateAll": // Bash sends: "UpdateAll@Theme@${arr[$u]}" macgap.app.removeMessage(firstLine); themeActionUpdateAll(firstLineSplit[1],firstLineSplit[2]); break; case "Fail": // Bash sends: "Fail@${passedAction}@$themeTitleToActOn" macgap.app.removeMessage(firstLine); themeActionFail(firstLineSplit[1],firstLineSplit[2]); break; case "NoPathSelected": // Bash sends: "NoPathSelected@@" macgap.app.removeMessage(firstLine); HideFreeSpace(); break; case "ThumbnailSize": // Bash sends: "ThumbnailSize@${gThumbSizeX}@${gThumbSizeY}" macgap.app.removeMessage(firstLine); SetThumbnailSize(firstLineSplit[1],firstLineSplit[2]); break; case "UnInstalledView": // Bash sends: "UnInstalledView@${gUISettingViewUnInstalled}@" macgap.app.removeMessage(firstLine); SetShowHideButton(firstLineSplit[1]); break; case "ThumbnailView": // Bash sends: "UnInstalledView@${gUISettingViewUnInstalled}@" macgap.app.removeMessage(firstLine); SetThemeBandHeight(firstLineSplit[1]); break; case "PreviewView": // Bash sends: "PreviewView@${gUISettingViewPreviews}@" macgap.app.removeMessage(firstLine); SetShowHidePreviews(firstLineSplit[1]); break; case "MessageESP": // Bash sends: "MessageESP@Mounted@${espMountedCount}" macgap.app.removeMessage(firstLine); UpdateMessageBox(firstLineSplit[1],firstLineSplit[2]); break; case "BootDevice": // Bash sends: "BootDevice@Mounted@${bootDeviceIdentifier}@${gBootDeviceMountPoint}" or "BootDevice@Failed@@" macgap.app.removeMessage(firstLine); ShowMessageBootDevice(firstLineSplit[1],firstLineSplit[2],firstLineSplit[3]); break; case "NewVolumeDropDown": // Bash sends: "NewVolumeDropDown@${newThemeList}" //${newThemeList} is a comma separated list macgap.app.removeMessage(firstLine); UpdateAndRefreshPartitionSelectMenu(firstLineSplit[1]); break; case "BootlogView": // Bash sends: "BootlogView@${gBootlogState}@" macgap.app.removeMessage(firstLine); SetBootLogState(firstLineSplit[1]); // Adjust footer height also //SetFooterHeight("IncludeCO"); break; case "SetPrediction": // Bash sends: "SetPrediction@${themeToSend}@" macgap.app.removeMessage(firstLine); SetPredictionText(firstLineSplit[1]); break; case "ShowHideControlOptions": // Bash sends: "ShowHideControlOptions@Show or Hide@" macgap.app.removeMessage(firstLine); ShowHideControlOptions(firstLineSplit[1]); break; case "UpdateThemePaths": // Bash sends: "UpdateThemePaths@${gNvramPlistFullPath}@${gConfigPlistFullPath}@${mountpoint}" macgap.app.removeMessage(firstLine); UpdateThemePaths(firstLineSplit[1],firstLineSplit[2],firstLineSplit[3]); break; case "EnableInterface": // Bash sends: "EnableInterface@@" macgap.app.removeMessage(firstLine); enableInterface(); break; case "CheckingThemeUpdates": // Bash sends: "EnableInterface@@" macgap.app.removeMessage(firstLine); showCheckingThemeUpdateProgressBar(); break; default: alert("Found else:" + firstLine + " | This is a problem and the app may not function correctly. Please report this error"); if(firstLine == "") { macgap.app.removeMessage(""); } else { macgap.app.removeMessage(firstLine); } break; } // recursively call function as long as file exists every 1/10th second. timerReadMessageFile = setTimeout(readBashToJsMessageFile, 100); } else { // recursively call function as long as file exists but at 1/2 second intervals timerReadMessageFile = setTimeout(readBashToJsMessageFile, 500); } } //------------------------------------------------------------------------------------- //function PopulateThemeListArray() //{ // Get each 'id' of a 'div' with class 'versionControl' and store everything after 'indicator_' in an array. //$(".versionControl").each(function(){ gThemeList.push(this.id.replace('indicator_','')); }); //} //------------------------------------------------------------------------------------- function setTargetThemePath(entry) { $('#partitionSelect').val(entry); ResetButtonsAndBandsToDefault(); if (entry != "-") { showButtons(); // Show open button beside device dropdown $("#OpenPathButton").css("display","block"); ShowFreeSpace(); } else { $("#OpenPathButton").css("display","none"); ShowMessageBoxClose(); HideProgressBar(); } } //------------------------------------------------------------------------------------- function presentNotExistsDialog(uuid,path,id) { if (uuid != "" & path != "") { ChangeMessageBoxHeaderColour("red"); SetMessageBoxText("Attention:" ,"Previously used:
" + path + "
on volume with UUID
" + uuid + "
is no longer mounted.

Please choose a theme path.") ShowMessageBox(); // Remove partition entry from dropdown menu if ( id != "-" ) { $("#partitionSelect option[value=" + id + "]").remove(); } } } //------------------------------------------------------------------------------------- function updateBandsWithInstalledThemes(themeList) { if (themeList != "") { splitThemeList = (themeList).split(','); if (splitThemeList != "-") { showButtons(); var unknownThemeCount=0; // Update only installed themes with uninstall buttons for (var t = 0; t < splitThemeList.length; t++) { // Does theme actually exist? // User could have their own theme installed which is not in the repo. if (!$("[id='button_" + splitThemeList[t] + "']").length) { //alert(splitThemeList[t] + " does not exist in the repo"); unknownThemeCount++; } ChangeButtonAndBandToUnInstall(splitThemeList[t]); } // Has the user chosen to view only installed themes? var readButton = $("#ShowHideToggleButton").text(); if (readButton.indexOf("Show") >= 0) { // Hide previews of uninstalled themes //ClosePreviewsForUninstalledThemes(); } // Update number of installed themes if (splitThemeList != ",") { // This check needs verifying!! - is a single comma possible? $("#NumInstalledThemes").html(splitThemeList.length + "/" + $('div[id^=ThemeBand]').length); if (unknownThemeCount > 0){ // Change colour of textThemeCount class to orange $("#NumInstalledThemes").css("color","#FFA500"); $("#NumInstalledThemesQuery").css("display","inline"); } else { $("#NumInstalledThemes").css("color","#FFF"); $("#NumInstalledThemesQuery").css("display","none"); } } else { $("#NumInstalledThemes").html("0/" + $('div[id^=ThemeBand]').length); } // Populate control option dropdown menus. UpdateAndRefreshInstalledThemeDropDown(splitThemeList); } else { // Populate control option dropdown menus even though there are no themes. UpdateAndRefreshInstalledThemeDropDown(""); // Update number of installed themes $("#NumInstalledThemes").html("-/" + $('div[id^=ThemeBand]').length); // Reset colours and question mark incase previously shown. $("#NumInstalledThemes").css("color","#FFF"); $("#NumInstalledThemesQuery").css("display","none"); } } else { showButtons(); // Populate control option dropdown menus even though there are no themes. UpdateAndRefreshInstalledThemeDropDown(""); // No themes installed on this volume $("#NumInstalledThemes").html("0/" + $('div[id^=ThemeBand]').length); // Reset colours and question mark incase previously shown. $("#NumInstalledThemes").css("color","#FFF"); $("#NumInstalledThemesQuery").css("display","none"); } } //------------------------------------------------------------------------------------- function actOnFreeSpace(availableSpace) { if (availableSpace != "") { // Bash sends the size read from the result of df // This will look like 168M // Is the last character a G? lastChar = availableSpace.slice(-1); if (lastChar == "K") { // change colour to red $(".textFreeSpace").css("color","#C00000"); } if (lastChar == "M") { // Remove last character of string number = availableSpace.slice(0,-1); // round down number = Math.floor(number); if(parseInt(number, 10) < parseInt(10, 10)) { // change colour to red $(".textFreeSpace").css("color","#C00000"); // Show user a low space warning message ChangeMessageBoxHeaderColour("red"); SetMessageBoxText("Warning: Low Space","You only have " + number +"MB remaining on this volume. Installing another theme may fail!"); ShowMessageBoxClose(); ShowMessageBox(); } } if (lastChar == "G") { // set to green as defined in the .css file $(".textFreeSpace").css("color","#3ef14b"); } $(".textFreeSpace").text(availableSpace+"B"); } } //------------------------------------------------------------------------------------- function ShowThemeUpdatesAvailableMessage(themeList) { if (themeList != "") { disableInterface(); localThemeUpdates = (themeList).split(','); if (localThemeUpdates != "") { var printString=("
"); // Update only installed themes with uninstall buttons for (var t = 0; t < localThemeUpdates.length; t++) { if(localThemeUpdates[t] != "") { // Prepare text for pretty print printString=(printString + "
" + localThemeUpdates[t]); // Send native notification sendNotification("Theme update available for " + localThemeUpdates[t] + "."); } } // Show a message to the user ChangeMessageBoxHeaderColour("blue"); SetMessageBoxText("Theme Updates:","There is an update available for: " + printString); ShowMessageBoxClose(); ShowMessageBox(); } } } //------------------------------------------------------------------------------------- function ShowUpdateThemesInUI(themeList) { if (themeList != "") { localThemeUpdates = (themeList).split(','); if (localThemeUpdates != "") { // Update only installed themes with update buttons for (var t = 0; t < localThemeUpdates.length; t++) { if(localThemeUpdates[t] != "") { ChangeButtonAndBandToUpdate(localThemeUpdates[t]); } } ShowUpdateAllButton(); } } } //------------------------------------------------------------------------------------- function displayUnversionedThemes(themeList) { if (themeList != "") { unVersionedThemes = (themeList).split(','); if (unVersionedThemes != "") { for (var t = 0; t < unVersionedThemes.length; t++) { SetUnVersionedControlIndicator(unVersionedThemes[t]); } } } } //------------------------------------------------------------------------------------- function SetCurrentThemeEntry(textToChange,themeName) { if (textToChange == "Nvram") { //$('#ctEntryNvram').text(themeName); SetDropDownNvram(themeName); } else if (textToChange == "ConfigP") { //$('#ctEntryConfig').text(themeName); SetDropDownConfigP(themeName); } } //------------------------------------------------------------------------------------- function SetDropDownNvram(themeName) { // Note: This menu is populated by UpdateAndRefreshInstalledThemeDropDown() var themeNotInstalled=1 if(themeName != "") { $('#installedThemeDropDownNvram option').each(function(){ if(this.value == themeName) { // Note: Bash script sends '-' when no theme is set $("#installedThemeDropDownNvram").val(themeName); themeNotInstalled=0 } }); if(themeNotInstalled == 1) { $("#installedThemeDropDownNvram").val("-"); } } checkEntryAndInsertRemoveOptionIfBlank($("#installedThemeDropDownNvram")); } /* //------------------------------------------------------------------------------------- function SetDropDownNvramP(themeName) { // Note: This menu is populated by UpdateAndRefreshInstalledThemeDropDown() var themeNotInstalled=1 if(themeName != "") { $('#installedThemeDropDownNvramP option').each(function(){ if(this.value == themeName) { // Note: Bash script sends '-' when no theme is set $("#installedThemeDropDownNvramP").val(themeName); themeNotInstalled=0 } }); if(themeNotInstalled == 1) { $("#installedThemeDropDownNvramP").val("-"); } } }*/ //------------------------------------------------------------------------------------- function SetDropDownConfigP(themeName) { // Note: This menu is populated by UpdateAndRefreshInstalledThemeDropDown() var themeNotInstalled=1 if(themeName != "") { $('#installedThemeDropDownConfigP option').each(function(){ if(this.value == themeName) { // Note: Bash script sends '-' when no theme is set $("#installedThemeDropDownConfigP").val(themeName); themeNotInstalled=0 } }); if(themeNotInstalled == 1) { $("#installedThemeDropDownConfigP").val("-"); } } checkEntryAndInsertRemoveOptionIfBlank($("#installedThemeDropDownConfigP")); } //------------------------------------------------------------------------------------- function themeActionSuccess(action,themeName) { if (action != "" & themeName != "") { // Present dialog to the user ChangeMessageBoxHeaderColour("green"); // Correct language - Install, UnInstall, Update to Installed, UnInstalled, Updated if (action == "Update") { printText="Updated"; // theme was updated, remove theme name from global update string gUpdateThemeListStr = gUpdateThemeListStr.replace(themeName+',',''); } else if (action == "UnInstall") { // theme was uninstalled - remove theme name from global update string (if there) gUpdateThemeListStr = gUpdateThemeListStr.replace(themeName+',',''); } else { printText=(action + "ed"); } // Print message HideProgressBar(); SetMessageBoxText("Success:","The theme " + themeName + " was successfully " + printText + "."); ShowMessageBoxClose(); // Send native notification sendNotification("Success: The theme " + themeName + " was successfully " + printText + "."); // Reset current theme list, bands and buttons ResetButtonsAndBandsToDefault(); hideButtons(); // Show Overlay Box to stop user interacting with buttons disableInterface(); } } //------------------------------------------------------------------------------------- function themeActionFail(action,themeName) { if (action != "" & themeName != "") { // Present dialog to the user ChangeMessageBoxHeaderColour("red"); // Correct language - Install, UnInstall, Update to Installed, UnInstalled, Updated if (action == "Update") { printText="Updated"; } else { printText=(action + "ed"); } // Print message HideProgressBar(); SetMessageBoxText("Failure:","The theme " + themeName + " was not " + printText + "."); ShowMessageBoxClose(); // Send native notification sendNotification("Failure: The theme " + themeName + " was not " + printText + "."); } } //------------------------------------------------------------------------------------- function themeActionUpdateAll(message,themeName) { if (message != "" & themeName != "") { // message box should already be showing.. Maybe add check? ChangeMessageBoxHeaderColour("green"); ShowProgressBar(); HideMessageBoxClose(); if (message == "Theme") { // theme was updated, remove theme name from global update string gUpdateThemeListStr = gUpdateThemeListStr.replace(themeName+',',''); // Change dialog text SetMessageBoxText("Success:","The theme " + themeName + " was successfully Updated."); // Send native notification sendNotification("Success: The theme " + themeName + " was successfully Updated."); } else if (message == "Complete"){ HideProgressBar(); // Change dialog text SetMessageBoxText("Completed:","All updates completed successfully."); ShowMessageBoxClose(); // Reset current theme list, bands and buttons ResetButtonsAndBandsToDefault(); hideButtons(); } else { alert ("Not supposed to reach here"); } } } //------------------------------------------------------------------------------------- function disableInterface() { // Disable path drop down menu and open button until updates have been checked. // Will re-enable in CheckForUpdatesThemeList(); $("#partitionSelect").prop("disabled", true); $("#OpenPathButton").prop("disabled", true); // Display message to notify checking for updates $("#ListingThemesMessage").css("display","block"); // Show Overlay Box to stop user interacting with buttons DisplayOverlayTwoBox(); // Show open button beside device dropdown $("#OpenPathButton").css("display","block"); } //------------------------------------------------------------------------------------- function enableInterface() { // Re-enable drop down menu and open button $("#partitionSelect").prop("disabled", false); $("#OpenPathButton").prop("disabled", false); // Hide message to notify checking for updates $("#ListingThemesMessage").css("display","none"); // Hide Overlay Box to allow user to interact with buttons HideOverlayTwoBox(); } //------------------------------------------------------------------------------------- function showCheckingThemeUpdateProgressBar() { // Disable path drop down menu and open button until updates have been checked. // Will re-enable in CheckForUpdatesThemeList(); $("#partitionSelect").prop("disabled", true); $("#OpenPathButton").prop("disabled", true); // Display message to notify checking for updates $("#CheckingUpdatesMessage").css("display","block"); } //------------------------------------------------------------------------------------- function hideCheckingThemeUpdateProgressBar() { // Disable path drop down menu and open button until updates have been checked. // Will re-enable in CheckForUpdatesThemeList(); $("#partitionSelect").prop("disabled", false); $("#OpenPathButton").prop("disabled", false); // Display message to notify checking for updates $("#CheckingUpdatesMessage").css("display","none"); } //------------------------------------------------------------------------------------- function SetThumbnailSize(width,height) { // function ChangeThumbnailSize() changes thumb size +/- 25px // So call it number of times necessary to achieve wanted width if (width != "" & height != "") { var currentThumbWidth = $(".thumbnail img").first().width(); if (currentThumbWidth > width) { var timesDifference=((currentThumbWidth-width)/25) for (s = 0; s < timesDifference; s++) { ChangeThumbnailSize('smaller'); } } else if (currentThumbWidth < width) { var timesDifference=((width-currentThumbWidth)/25) for (s = 0; s < timesDifference; s++) { ChangeThumbnailSize('larger'); } } } } //------------------------------------------------------------------------------------- $(function() { //----------------------------------------------------- // On changing the 'partitionSelect' dropdown menu. $("#partitionSelect").change(function() { var selectedPartition=$("#partitionSelect").val(); // Send massage to bash script to notify change of path. // The bash script will get, and return, a list of installed themes for this path. // The bash script will then check if any of the themes have available updates. // Send a message to the bash script to fetch new theme list. macgap.app.launch("CTM_selectedPartition‡" + selectedPartition); // The bash script will send back: // 1 - A list of themes. // 2 - Any themes from user prefs marked with an update available. // 3 - Any themes flagged as orphaned (ie. not parent bare clone). // These will be picked up by function readBashToJsMessageFile() // As long as the user did not select the 'Please Choose' menu option. if (selectedPartition != "-") { // Show Overlay Box to stop user interacting with buttons disableInterface(); // Show the Free Space text ShowFreeSpace(); } else { // Hide open button beside device dropdown $("#OpenPathButton").css("display","none"); // Hide the Free Space text HideFreeSpace(); } // Honour users choice of which themes to view (All or just Installed) GetShowHideButtonStateAndUpdateUI(); HideUpdateAllButton(); // Reset current theme list, bands and buttons ResetButtonsAndBandsToDefault(); hideButtons(); // show all themes, even if asked to Show Installed $(".accordion").css("display","block"); // Reset global var for updated themes gUpdateThemeListStr=""; }); //----------------------------------------------------- // On pressing the Rescan Boot Device button $("#RescanBootDeviceButton").on('click', function() { macgap.app.launch("RescanBootDevice"); }); //----------------------------------------------------- // On pressing the refresh path button $("#RefreshPathButton").on('click', function() { // select current dropdown selection $('#partitionSelect').change(); }); //----------------------------------------------------- // On pressing the open path button $("#OpenPathButton").on('click', function() { macgap.app.launch("OpenPath"); }); //----------------------------------------------------- // On pressing the mount ESP button $("#MountEspButton").on('click', function() { ActionMountESP(); }); //----------------------------------------------------- // On pressing a theme button (Install,UnInstall,Update) $("[id^=button_]").on('click', function() { var pressedButton=$(this).attr('id'); var currentStatus=$(this).attr('class'); RespondToButtonPress(pressedButton,currentStatus); }); //----------------------------------------------------- // On clicking the message box close button $('#boxclose').click(function(){ CloseMessageBox(); enableInterface(); }); //----------------------------------------------------- // On clicking an accordion entry $('.accordion').click(function(checkWhat) { // Reveal large screenshot image only if the install/uninstall/update // were not clicked. if (checkWhat.target.id.substring(0,6) != "button") { var hidden = $(this).closest("#ThemeBand").nextAll('[class="accordionContent"]').first().is(":hidden"); if (!hidden) { $(this) // Start with current .closest("#ThemeBand") // Traverse up the DOM to the ThemeBand div .nextAll('[class="accordionContent"]') // find the next siblings with class .accordionContent .first() // just use first one .slideUp('fast'); // Slide up } else { $(this) .closest("#ThemeBand") .nextAll('[class="accordionContent"]') .first() .slideToggle('fast'); } } else { return; } }); //----------------------------------------------------- // On clicking the bootlog band $('#BootLogTitleBar').click(function() { ActionShowHideBootlog(); }); //----------------------------------------------------- // On clicking the Hide / Show Thumbnails button $("#BandsHeightToggleButton").on('click', function() { ActionShowHideThumbnailsButton(); }); //----------------------------------------------------- // On clicking the Toggle Preview button - change to Expand/Collapse All $("#preview_Toggle_Button").click(function() { ActionShowHideExpandedPreviews(); }); //----------------------------------------------------- // On clicking the Update All button $("#ShowHideUpdateAllButton").on('click', function() { ActionUpdateAll(); }); //----------------------------------------------------- // On clicking the Show Installed / Show All button $("#ShowHideToggleButton").on('click', function() { ActionShowHideInstalledThemes(); }); //----------------------------------------------------- // On clicking the Thumbnail Smaller button $("#thumbSizeSmaller").on('click', function() { ChangeThumbnailSize('smaller'); }); //----------------------------------------------------- // On clicking the Thumbnail Larger button $("#thumbSizeLarger").on('click', function() { ChangeThumbnailSize('larger'); }); //----------------------------------------------------- // On clicking a version X mark $("[id^=indicator]").on('click', function() { // Show a message to the user ChangeMessageBoxHeaderColour("blue"); SetMessageBoxText("Untracked Theme","This theme was not installed by Clover Theme Manager. This means you will not be notified of any updates for this theme unless you UnInstall and then re-install it."); ShowMessageBoxClose(); ShowMessageBox(); }); //----------------------------------------------------- // On clicking the theme count question mark $("#NumInstalledThemesQuery").on('click', function() { // Show a message to the user ChangeMessageBoxHeaderColour("blue"); SetMessageBoxText("Unknown Theme Detected","There is a theme in this path with a name that does not match any in the Clover repository. This is not a problem, just be aware the number of installed themes shown in the main list will not match the counter."); ShowMessageBoxClose(); ShowMessageBox(); }); //----------------------------------------------------- // On changing the 'NVRAM' dropdown menu. $("#installedThemeDropDownNvram").change(function() { ActionChangedDropDownNvram(); }); //----------------------------------------------------- // On changing the 'Config.plist' dropdown menu. $("#installedThemeDropDownConfigP").change(function() { ActionChangedDropDownConfigP(); }); }); //------------------------------------------------------------------------------------- function ActionShowHideBootlog() { var hidden = $('#BootLogContainer').is(":hidden"); if (!hidden) { SetBootLogState("Close"); macgap.app.launch("CTM_bootlog‡Close"); } else { SetBootLogState("Open"); macgap.app.launch("CTM_bootlog‡Open"); } } //------------------------------------------------------------------------------------- function ActionMountESP() { macgap.app.launch("MountESP"); // Show a message to the user ChangeMessageBoxHeaderColour("blue"); SetMessageBoxText("EFI System Partition(s)","All currently unmounted EFI System Partitions will now be mounted and checked for a /EFI/Clover/Themes directory. If found, the paths will appear in the volume selector."); HideMessageBoxClose(); ShowProgressBar(); ShowMessageBox(); } //------------------------------------------------------------------------------------- function ActionShowHideThumbnailsButton() { var textState = $("#BandsHeightToggleButton").text(); if (textState.indexOf("Hide") >= 0) { SetThemeBandHeight("Hide"); // Send a message to the bash script to record user choice in prefs macgap.app.launch("CTM_showThumbails"); } if (textState.indexOf("Show") >= 0) { SetThemeBandHeight("Show"); // Send a message to the bash script to record user choice in prefs macgap.app.launch("CTM_hideThumbails"); } } //------------------------------------------------------------------------------------- function ActionShowHideExpandedPreviews() { var buttonText=$("#preview_Toggle_Button").text(); if (buttonText.indexOf("Expand") >= 0) { SetShowHidePreviews("Show"); // Send a message to the bash script to record user choice in prefs macgap.app.launch("CTM_showPreviews"); } if (buttonText.indexOf("Collapse") >= 0) { SetShowHidePreviews("Hide"); // Send a message to the bash script to record user choice in prefs macgap.app.launch("CTM_hidePreviews"); } } //------------------------------------------------------------------------------------- function ActionUpdateAll() { var themeList = ""; var themeListPrint = ""; $('.buttonUpdate').each(function(){ updateButtonName = $(this).attr('id'); // Update buttons for themes with spaces in their names had the // spaces replaced with five Q's. Let's put spaces back if (updateButtonName.indexOf('QQQQQ') >= 0) { updateButtonName = updateButtonName.replace(/QQQQQ/g, ' '); } // Get all after 'button_Update_' themeList = themeList + updateButtonName.substring(14) + "," themeListPrint = themeListPrint + updateButtonName.substring(14) + "
" }); // remove last char themeList = themeList.slice(0, -1); // Send a message to the bash script macgap.app.launch("CTM_UpdateAll‡" + themeList); // Show a message to the user ChangeMessageBoxHeaderColour("blue"); SetMessageBoxText("Updating:", themeListPrint); HideMessageBoxClose(); ShowProgressBar(); ShowMessageBox(); HideUpdateAllButton(); } //------------------------------------------------------------------------------------- function ActionShowHideInstalledThemes() { // Change text of button var textState = $("#ShowHideToggleButton").text(); if (textState.indexOf("Show Installed") >= 0) { SetShowHideButton("Hide"); // Send a message to the bash script to record user choice in prefs macgap.app.launch("CTM_hideUninstalled"); // Close all preview images for UnInstalled themes ClosePreviewsForUninstalledThemes(); } if (textState.indexOf("Show All") >= 0) { SetShowHideButton("Show"); // Send a message to the bash script to record user choice in prefs macgap.app.launch("CTM_showUninstalled"); } } //------------------------------------------------------------------------------------- function ActionChangedDropDownNvram() { var chosenOption=$("#installedThemeDropDownNvram").val(); if(chosenOption != "-") { // Send message to bash script to notify change. macgap.app.launch("CTM_changeThemeN‡" + chosenOption); // Remove the Remove option from the menu $("#installedThemeDropDownNvram option[value='!Remove!']").remove(); // If chosing to remove the entry then select the top (blank) option from the menu if(chosenOption == "!Remove!") { $("#installedThemeDropDownNvram option:first").attr('selected','selected'); } } } //------------------------------------------------------------------------------------- function ActionChangedDropDownConfigP() { var chosenOption=$("#installedThemeDropDownConfigP").val(); if(chosenOption != "-") { // Send message to bash script to notify change. macgap.app.launch("CTM_changeThemeC‡" + chosenOption); // Remove the Remove option from the menu $("#installedThemeDropDownConfigP option[value='!Remove!']").remove(); // If chosing to remove the entry then select the top (blank) option from the menu if(chosenOption == "!Remove!") { $("#installedThemeDropDownConfigP option:first").attr('selected','selected'); } } } //------------------------------------------------------------------------------------- function SetBootLogState(state) { // Note: The bootlog is not in the starting html template. // It's injected by the bash script if a bootlog has been found. var bootLogTitleBarHeight = $('#BootLogTitleBar').outerHeight(); var bootLogContainerBandCount = $('div[id^=bandHeader]').length; var bootLogContainerHeight = ( bootLogContainerBandCount * 26 ); // 26px = Height of a single #BandHeader, #Band Description (inc 1px border) var currentHeaderHeight = $('#header').outerHeight(); // Show and ShowClosed are passed by bash script if finding a bootlog. // ShowClosed is used if user has asked to close it and setting is in prefs. if(state == "Show") { // bash script has sent a command to show the bootlog var bootlogTotalHeight = bootLogTitleBarHeight + bootLogContainerHeight; var newHeaderHeight = (currentHeaderHeight + bootlogTotalHeight); $('#header').height(newHeaderHeight); $('#content').css("top","+="+bootlogTotalHeight); SetListingThemesMessageAndProgressBarPosition(); } else if (state == "ShowClosed" ) { // bash script has sent a command to show the bootlog but collapsed $('#BootLogContainer').hide(function() { var newHeaderHeight = (currentHeaderHeight + bootLogTitleBarHeight); $('#header').height(newHeaderHeight); $('#content').css("top","+="+bootLogTitleBarHeight); SetListingThemesMessageAndProgressBarPosition(); }); } else { // Open and Close are passed as a result of the user clicking the #BootLogTitleBar var hidden = $('#BootLogContainer').is(":hidden"); if(state == "Open") { // check it's not already open if (hidden) { // set header div z-index to 0 so header does not sit over sliding #content $('#header').css("z-index",0); var newHeaderHeight = (currentHeaderHeight + bootLogContainerHeight); $('#BootLogContainer').show(200); $('#content').animate({ left: '0', top: '+=' + (bootLogContainerHeight)}, 200, function () { // Action after animation has completed SetListingThemesMessageAndProgressBarPosition(); // set header div z-index to 1 so header sits over #content and shadows shows. $('#header').css("z-index",1); }); $('#header').height(newHeaderHeight); // Change arrow in bootlog header band title $('#BootLogTitleBar span').first().html('LAST BOOT\ \ \&\#x25BE\ \ \ \ |'); } } else { // check it's not already closed and not already been clicked and currently animating to close if (!hidden && (!$('#content').is(':animated'))) { // set header div z-index to 0 so header does not sit over sliding #content $('#header').css("z-index",0); var newHeaderHeight = (currentHeaderHeight - bootLogContainerHeight); $('#BootLogContainer').hide(200); $('#content').animate({ left: '0', top: '-=' + (bootLogContainerHeight)}, 200, function () { // Action after animation has completed $('#header').height(newHeaderHeight); SetListingThemesMessageAndProgressBarPosition(); // set header div z-index to 1 so header sits over #content and shadows shows. $('#header').css("z-index",1); }); // Change arrow in bootlog header band title $('#BootLogTitleBar span').first().html('LAST BOOT\ \ \&\#x25B8\ \ \ \ |'); } } } } //------------------------------------------------------------------------------------- function SetFooterHeight(UseControlOption) { // Note: only the footer links exist in the default template. // The nvram status band is injected by bootlog.sh // The control options are injected by script.sh var nvramBandHeight = $('#NvramFunctionalityBand').outerHeight(); var changeThemeContainerHeight = $('#changeThemeContainer').outerHeight(); var footerLinksHeight = $('#FooterLinks').outerHeight(); // Read text in nvram band as it has a dual purpose. // If not booted using Clover then it shows a message saying so. var nvramBandText = $('#nvramTextArea span').text(); if(UseControlOption == "IncludeCO") { // Show nvram band if it's not displaying message about not being booted by Clover if(nvramBandText != "This system was not booted using Clover.") { // set by bootlog.sh $('#NvramFunctionalityBand').css("display","block"); } var newFooterHeight = (changeThemeContainerHeight + nvramBandHeight + footerLinksHeight); } else if(UseControlOption == "ExcludeCO") { // Hide nvram band if it's not displaying message about not being booted by Clover if(nvramBandText != "This system was not booted using Clover.") { // set by bootlog.sh $('#NvramFunctionalityBand').css("display","none"); var newFooterHeight = (footerLinksHeight); } else { var newFooterHeight = (footerLinksHeight + nvramBandHeight); } } // set height of footer $('#footer').css("height",newFooterHeight); // Adjust bottom of #content to match footer height $('#content').css("bottom",newFooterHeight); } //------------------------------------------------------------------------------------- function SetListingThemesMessageAndProgressBarPosition() { var pathSelectorTop = $('#PathSelector').offset().top; $("#ListingThemesMessage").css({ top: (pathSelectorTop-5) }); // Also adjust position of the CheckingUpdatesMessage progress meter $("#CheckingUpdatesMessage").css({ top: (pathSelectorTop-5) }); } //------------------------------------------------------------------------------------- function SetShowHidePreviews(state) { var accordionBandState=$('.accordion').is(":hidden"); if(state == "Show") { if (accordionBandState) { $(".accordionInstalled").next('[class="accordionContent"]').slideDown('normal'); $(".accordionInstalledNoShadow").next('[class="accordionContent"]').slideDown('normal'); $(".accordionUpdate").next('[class="accordionContent"]').slideDown('normal'); $(".accordionUpdateNoShadow").next('[class="accordionContent"]').slideDown('normal'); } else { $(".accordion").next('[class="accordionContent"]').slideDown('normal'); $(".accordionInstalled").next('[class="accordionContent"]').slideDown('normal'); $(".accordionInstalledNoShadow").next('[class="accordionContent"]').slideDown('normal'); $(".accordionUpdate").next('[class="accordionContent"]').slideDown('normal'); $(".accordionUpdateNoShadow").next('[class="accordionContent"]').slideDown('normal'); } $("#preview_Toggle_Button").text("Collapse Previews"); $("#preview_Toggle_Button").css("background-image","-webkit-linear-gradient(top, rgba(0,0,0,1) 0%,rgba(82,82,82,1) 100%)"); $("#preview_Toggle_Button").css("border","1px solid #000"); $("#preview_Toggle_Button").css("color","#82f3ff"); } else if (state == "Hide") { if (accordionBandState) { $(".accordionInstalled").next('[class="accordionContent"]').slideUp('normal'); $(".accordionInstalledNoShadow").next('[class="accordionContent"]').slideUp('normal'); $(".accordionUpdate").next('[class="accordionContent"]').slideUp('normal'); $(".accordionUpdateNoShadow").next('[class="accordionContent"]').slideUp('normal'); } else { $(".accordion").next('[class="accordionContent"]').slideUp('normal'); $(".accordionInstalled").next('[class="accordionContent"]').slideUp('normal'); $(".accordionInstalledNoShadow").next('[class="accordionContent"]').slideUp('normal'); $(".accordionUpdate").next('[class="accordionContent"]').slideUp('normal'); $(".accordionUpdateNoShadow").next('[class="accordionContent"]').slideUp('normal'); } $("#preview_Toggle_Button").text("Expand Previews"); $("#preview_Toggle_Button").css("background-image","-webkit-linear-gradient(top, rgba(110,110,110,1) 0%,rgba(0,0,0,1) 100%)"); $("#preview_Toggle_Button").css("border","1px solid #282828"); $("#preview_Toggle_Button").css("color","#FFF"); } } //------------------------------------------------------------------------------------- function SetShowHideButton(state) { if(state == "Hide") { $("#ShowHideToggleButton").text("Show All"); $("#ShowHideToggleButton").css("background-image","-webkit-linear-gradient(top, rgba(0,0,0,1) 0%,rgba(82,82,82,1) 100%)"); $("#ShowHideToggleButton").css("border","1px solid #000"); $("#ShowHideToggleButton").css("color","#82f3ff"); GetShowHideButtonStateAndUpdateUI(); } else if (state == "Show") { $("#ShowHideToggleButton").text("Show Installed"); $("#ShowHideToggleButton").css("background-image","-webkit-linear-gradient(top, rgba(110,110,110,1) 0%,rgba(0,0,0,1) 100%)"); $("#ShowHideToggleButton").css("border","1px solid #282828"); $("#ShowHideToggleButton").css("color","#FFF"); GetShowHideButtonStateAndUpdateUI(); } } //------------------------------------------------------------------------------------- function SetThemeBandHeight(setting) { if (setting == "Hide") { // Hide + and - buttons $("#thumbSizeSmaller").css("display","none"); $("#thumbSizeLarger").css("display","none"); // Show spacer sml buttons to retain spacing of other buttons $(".spacerButtonSml").css("display","block"); // Move theme titles up $("[id=ThemeText]").css("top","80%"); // Hide all theme descriptions $(".themeDescription").css("display","none"); // Hide all theme authors $(".themeAuthor").css("display","none"); // Hide thumbnails $(".thumbnail").css("display","none"); // Adjust height of theme bands $(".accordion").css("height","27px"); $(".accordionInstalled").css("height","27px"); $(".accordionInstalledNoShadow").css("height","27px"); $(".accordionUpdate").css("height","27px"); $(".accordionUpdateNoShadow").css("height","27px"); // Reduce margin top of buttons $(".buttonInstall").css("margin-top","3px"); $(".buttonUnInstall").css("margin-top","3px"); $(".buttonUpdate").css("margin-top","3px"); // Reduce margin top of Unversioned Themes Indicator $(".versionControl").css("margin-top","9px"); // Add margin left to theme titles $("[id=ThemeText]").css("margin-left","32px"); // Change button text $("#BandsHeightToggleButton").text("Show Thumbnails"); // Set background colour to indicate its selected $("#BandsHeightToggleButton").css("background-image","-webkit-linear-gradient(top, rgba(0,0,0,1) 0%,rgba(82,82,82,1) 100%)"); $("#BandsHeightToggleButton").css("border","1px solid #000"); $("#BandsHeightToggleButton").css("color","#82f3ff"); } else if (setting == "Show") { // Show + and - buttons $("#thumbSizeSmaller").css("display","block"); $("#thumbSizeLarger").css("display","block"); // Hide spacer sml buttons to retain spacing of other buttons $(".spacerButtonSml").css("display","none"); // Revert theme titles margin top $("[id=ThemeText]").css("top","50%"); // Show all theme descriptions $(".themeDescription").css("display","inline"); // Show all theme authors $(".themeAuthor").css("display","inline"); // Show thumbnails $(".thumbnail").css("display","block"); // Adjust height of theme bands var currentThumbHeight = $(".thumbnail img").first().height(); var accordionHeight = (currentThumbHeight+14); $(".accordion").css("height",accordionHeight); $(".accordionInstalled").css("height",accordionHeight); $(".accordionInstalledNoShadow").css("height",accordionHeight); $(".accordionUpdate").css("height",accordionHeight); $(".accordionUpdateNoShadow").css("height",accordionHeight); // Revert margin top of buttons // Note: When thumb=100px wide, default button top=24px var currentThumbWidth = $(".thumbnail img").first().width(); var buttonMarginAdjustment = (((currentThumbWidth-100)/25)*7); var buttonMarginTop = (24 + buttonMarginAdjustment); $(".buttonInstall").css("margin-top",buttonMarginTop); $(".buttonUnInstall").css("margin-top",buttonMarginTop); $(".buttonUpdate").css("margin-top",buttonMarginTop); // Revert margin top of Unversioned Themes Indicatpor // Note: When thumb=100px wide, default margin top=28px var versionControlMarginTop = (28 + buttonMarginAdjustment); $(".versionControl").css("margin-top",versionControlMarginTop); // Remove added margin left to theme titles $("[id=ThemeText]").css("margin-left","0px"); // Change button text $("#BandsHeightToggleButton").text("Hide Thumbnails"); // Revert background colour $("#BandsHeightToggleButton").css("background-image","-webkit-linear-gradient(top, rgba(110,110,110,1) 0%,rgba(0,0,0,1) 100%)"); $("#BandsHeightToggleButton").css("border","1px solid #282828"); $("#BandsHeightToggleButton").css("color","#FFF"); } } //------------------------------------------------------------------------------------- function UpdateMessageBox(messageOne,messageTwo) { HideProgressBar(); if (messageOne != "" && messageTwo != "") { // Show a message to the user ChangeMessageBoxHeaderColour("blue"); if (messageOne == 'Mounted') { if (messageTwo == '0') { SetMessageBoxText("EFI System Partition(s)","There are no unmounted EFI system partitions with an existing /EFI/Clover/Themes directory."); } else { ChangeMessageBoxHeaderColour("green"); if (messageTwo == '1') { var msgWrd1="partition" var msgWrd2="was" } else { var msgWrd1="partitions" var msgWrd2="were" } SetMessageBoxText("EFI System Partition(s)",messageTwo + " EFI system " + msgWrd1 + " with an existing /EFI/Clover/Themes directory " + msgWrd2 + " mounted."); // Honour users choice of which themes to view (All or just Installed) GetShowHideButtonStateAndUpdateUI(); // Reset current theme list, bands and buttons ResetButtonsAndBandsToDefault(); hideButtons(); // show all themes, even if asked to Show Installed $(".accordion").css("display","block"); } } else if (messageOne == "Cancelled") { ChangeMessageBoxHeaderColour("red"); SetMessageBoxText("EFI System Partition(s)","Password dialog cancelled."); } ShowMessageBoxClose(); ShowMessageBox(); } } //------------------------------------------------------------------------------------- function ShowMessageBootDevice(result,deviceId,mountPoint) { // Show a message to the user if (result == "Failed") { ChangeMessageBoxHeaderColour("red"); SetMessageBoxText("Boot Device","The boot device failed to be detected. A Rescan button is available in the bootlog region."); ShowMessageBoxClose(); ShowMessageBox(); } else if (result == "Mounted") { // Update bootlog device text $("#bandIdentifer span").last().html("" + deviceId + "<\/span>"); $("#bandMountpoint span").last().html("" + mountPoint + "<\/span>"); // Hide Rescan button $("#RescanButton").hide(); // show message box confirming device found ChangeMessageBoxHeaderColour("blue"); SetMessageBoxText("Boot Device",deviceId + " on mountpoint " + mountPoint + " was detected as the boot device "); ShowMessageBoxClose(); ShowMessageBox(); } } //------------------------------------------------------------------------------------- function ChangeThumbnailSize(action) { // Adjust the width of each thumbnail image by 25px each time this is called. // Each adjustment also alters: // - thumbnail height and theme band height. // - Y position of buttons and version control indicator. // - width of title, author and description text box. var currentThumbWidth = $(".thumbnail img").first().width(); var currentThumbHeight = $(".thumbnail img").first().height(); var currentAccordionHeight = $(".accordion").first().height(); var currentThemeTextWidth = $("#ThemeText").first().width(); if (action=='larger' && currentThumbWidth <= 175) { var newAccordionHeight=(currentAccordionHeight+14); var newThumbWidth=(currentThumbWidth+25); var newThumbHeight=(currentThumbHeight+14); var newThemeTextWidth=(currentThemeTextWidth-30); } else if (action=='smaller' && currentThumbWidth >= 125) { var newAccordionHeight=(currentAccordionHeight-14); var newThumbWidth=(currentThumbWidth-25); var newThumbHeight=(currentThumbHeight-14); var newThemeTextWidth=(currentThemeTextWidth+30); } else { newThemeTextWidth=currentThemeTextWidth; } //alert(currentThumbWidth+","+action+","+currentThemeTextWidth+","+newThemeTextWidth); // Only make changes if thumbnail width has changed if (newThumbWidth != currentThumbWidth) { // Adjust height of theme bands $(".accordion").css("height",newAccordionHeight); $(".accordionInstalled").css("height",newAccordionHeight); $(".accordionInstalledNoShadow").css("height",newAccordionHeight); $(".accordionUpdate").css("height",newAccordionHeight); $(".accordionUpdateNoShadow").css("height",newAccordionHeight); // Change thumbnail size $(".thumbnail img").css("width",newThumbWidth); $(".thumbnail img").css("height",newThumbHeight); // Change margin top of buttons var buttonHeight = $(".buttonInstall").first().outerHeight(); var newButtonTop = ((newAccordionHeight-buttonHeight)/2); $(".buttonInstall").css("margin-top",newButtonTop); $(".buttonUnInstall").css("margin-top",newButtonTop); $(".buttonUpdate").css("margin-top",newButtonTop); // Change margin top of version control indicator $(".versionControl").css("margin-top",newButtonTop+3); // Reduce width of theme text (by 30px) to retain space for update button $("[id^=ThemeText]").width(newThemeTextWidth); // Send a message to the bash script to record thumbnail width if (newThumbWidth >= 100 && newThumbWidth <= 200) macgap.app.launch("CTM_thumbSize‡" + newThumbWidth + " " + newThumbHeight); } } //------------------------------------------------------------------------------------- function GetShowHideButtonStateAndUpdateUI() { var showHideState=$("[id='ShowHideToggleButton']").text(); var expandCollapseState=$("[id='preview_Toggle_Button']").text(); if (showHideState.indexOf("Show Installed") >= 0) { showHideState="Hide"; } else if (showHideState.indexOf("Show All") >= 0) { showHideState="Show"; } ShowHideUnInstalledThemes(showHideState,expandCollapseState); } //------------------------------------------------------------------------------------- function FindLineInString(CompleteString,SearchString) { var splitLines = (CompleteString).split(/\r\n|\r|\n/); for (l = 0; l < splitLines.length; l++) { if ((splitLines[l]).indexOf(SearchString) >= 0) return splitLines[l]; } return "0"; } //------------------------------------------------------------------------------------- function RespondToButtonPress(button,status) { // Update buttons have a class name 'button_Update_' and not 'button_' // The bash script matches against the string 'button_' // Remove 'Update_' from string. // Note: Could cause issues if a theme has 'Update_' in it's title. var button = button.replace('Update_', ''); // Update buttons for themes with spaces in their names had the // spaces replaced with five Q's. Let's put spaces back if (button.indexOf('QQQQQ') >= 0) { button = button.replace(/QQQQQ/g, ' '); } // Notify bash script. Send button name and it's current state. macgap.app.launch("CTM_ThemeAction‡" + button + "‡" + status); // Prepare vars for legible user message // PresedButton will begin with "button_" button=button.substring(7); // PresedButton will begin with "button" status=status.substring(6); if (status == "Install") { headerText="Downloading & Installing:"; printText="Installed"; } if (status == "UnInstall") { headerText="Un-Installing:"; printText="Un-Installed"; } if (status == "Update") { headerText="Updating:"; printText="Updated"; } // Show a message to the user ChangeMessageBoxHeaderColour("blue"); SetMessageBoxText(headerText, "Please wait while theme " + button + " is " + printText + "."); HideMessageBoxClose(); ShowProgressBar(); ShowMessageBox(); HideUpdateAllButton(); } //------------------------------------------------------------------------------------- // hide all option buttons function hideButtons() { $(".buttonInstall").css("display","none"); $(".buttonUnInstall").css("display","none"); $(".buttonUpdate").css("display","none"); } //------------------------------------------------------------------------------------- // show all option buttons function showButtons() { $(".buttonInstall").css("display","block"); $(".buttonUnInstall").css("display","block"); $(".buttonUpdate").css("display","block"); } //------------------------------------------------------------------------------------- function SetMessageBoxText(title,message) { $(".box h1").html(title); $(".box p").html(message); } //------------------------------------------------------------------------------------- function HideMessageBoxClose() { $("a.boxclose").css("display","none"); } //------------------------------------------------------------------------------------- function ShowMessageBoxClose() { $("a.boxclose").css("display","block"); } //------------------------------------------------------------------------------------- function HideFreeSpace() { $("#FreeSpace").css("display","none"); } //------------------------------------------------------------------------------------- function ShowFreeSpace() { $("#FreeSpace").css("display","block"); } //------------------------------------------------------------------------------------- function HideProgressBar() { $("#AnimatedBar").css("display","none"); } //------------------------------------------------------------------------------------- function ShowProgressBar() { $("#AnimatedBar").css("display","block"); } //------------------------------------------------------------------------------------- function DisplayOverlayBox() { $('#overlay').fadeIn('fast'); } //------------------------------------------------------------------------------------- function HideOverlayBox() { $('#overlay').fadeOut('fast'); } //------------------------------------------------------------------------------------- function DisplayOverlayTwoBox() { $('#overlayTwo').fadeIn('fast'); } //------------------------------------------------------------------------------------- function HideOverlayTwoBox() { $('#overlayTwo').fadeOut('fast'); } //------------------------------------------------------------------------------------- // From a tutorial by Mary Lou // http://tympanus.net/codrops/2009/12/03/css-and-jquery-tutorial-overlay-with-slide-out-box/ function ShowMessageBox() { // Read position of box and only fade in if at default off screen position. var position = $('#box').position(); if (position.top = -300) { // starting position = should match .box top in css $('#overlay').fadeIn('fast',function(){ // move box from current position so top=150px $('#box').animate({'top':'150px'},500, function(){ // Bounce doBounce($('.box'), 2, '10px', 100); }); }); } } //------------------------------------------------------------------------------------- // from http://stackoverflow.com/questions/10363671/jquery-bounce-effect-on-click-no-jquery-ui function doBounce(element, times, distance, speed) { for(var i = 0; i < times; i++) { element.animate({marginTop: '-='+distance}, speed) .animate({marginTop: '+='+distance}, speed); } } //------------------------------------------------------------------------------------- function CloseMessageBox() { // Read position of box and only fade out if at calculated top position is 150px which is set in ShowMessageBox() var position = $('#box').position(); if (position.top = 150) { var messageBoxHeight = $("#box").outerHeight(); var distanceToMove = 300; // matches top of .box in css if (messageBoxHeight > distanceToMove) { distanceToMove = messageBoxHeight; } $('#box').animate({'top':'-'+distanceToMove+'px'},500,function(){ // starting position = should match .box top in css $('#overlay').fadeOut('fast'); }); } } //------------------------------------------------------------------------------------- function ChangeMessageBoxHeaderColour(colour) { if(colour == "blue") { $("#box h1").css("background-color","#1e8ec6"); $("#box h1").css("color","#c4e0ee"); } if(colour == "red") { $("#box h1").css("background-color","#b43239"); $("#box h1").css("color","#f2d6d8"); } if(colour == "green") { $("#box h1").css("background-color","#8db035"); $("#box h1").css("color","#e4ecce"); } } //------------------------------------------------------------------------------------- function ResetButtonsAndBandsToDefault() { // Set class of all buttons to Install $(".buttonInstall").attr('class', 'buttonInstall'); $(".buttonUnInstall").attr('class', 'buttonInstall'); // Set all button text to Install $(".buttonInstall").html("Install"); $(".buttonUnInstall").html("Install"); // Change all installed band backgrounds to normal $(".accordionInstalled").attr("class","accordion"); $(".accordionInstalledNoShadow").attr("class","accordion"); // Change all update band backgrounds to normal $(".accordionUpdate").attr("class","accordion"); $(".accordionUpdateNoShadow").attr("class","accordion"); // Remove any update buttons $("[id^=button_Update]").remove(); // Remove any unVersioned indicators $("[id^=indicator_]").html("   "); $("[id^=indicator_]").css("pointer-events","none"); } //------------------------------------------------------------------------------------- function ChangeButtonAndBandToUnInstall(installedThemeName) { // Set class of this themes' button to UnInstall // Use an attribute selector to deal with themes with spaces in their name $("[id='button_" + installedThemeName + "']").attr('class', 'buttonUnInstall'); // Set class of this themes' button text to UnInstall $("[id='button_" + installedThemeName + "']").html("UnInstall"); // Note: bash script supplies this theme list in alphabetical order. // If themes are not called in alphabetical order this does not work. // Work out if band above is accordionInstalled. If yes then fill with accordionInstalledNoShadow var currentThemeBand = $("[id='button_" + installedThemeName + "']").closest("#ThemeBand"); var currentBandClass = currentThemeBand.attr('class'); var aboveBandClass = currentThemeBand.prevAll("#ThemeBand").first().attr('class'); if(typeof aboveBandClass != 'undefined') { // not at top band if(aboveBandClass == "accordion") { $("[id='button_" + installedThemeName + "']").closest('div[class="accordion"]').attr("class","accordionInstalled"); } else if(aboveBandClass == "accordionInstalled") { $("[id='button_" + installedThemeName + "']").closest('div[class="accordion"]').attr("class","accordionInstalledNoShadow"); } else if(aboveBandClass == "accordionInstalledNoShadow") { $("[id='button_" + installedThemeName + "']").closest('div[class="accordion"]').attr("class","accordionInstalledNoShadow"); } else if(aboveBandClass == "accordionUpdate") { $("[id='button_" + installedThemeName + "']").closest('div[class="accordion"]').attr("class","accordionInstalledNoShadow"); } else if(aboveBandClass == "accordionUpdateNoShadow") { $("[id='button_" + installedThemeName + "']").closest('div[class="accordion"]').attr("class","accordionInstalledNoShadow"); } } else { // at top band $("[id='button_" + installedThemeName + "']").closest('div[class="accordion"]').attr("class","accordionInstalledNoShadow"); } } //------------------------------------------------------------------------------------- function ChangeButtonAndBandToUpdate(themeName) { var themeNameForUpdate = themeName; // Check for any spaces in the theme name as I've just found out that // an id with spaces is invalid html. Ooops! This happens for each // theme with a name containing spaces. // For now, replace replace a space with five Q's. // This will only be used internally and the user won't see anything. if (themeName.indexOf(' ') >= 0) { themeNameForUpdate = themeName.replace(/ /g, 'QQQQQ'); } // Check we have not already added an update button for this theme. var buttonExistCheck=$("#button_Update_"+themeNameForUpdate); if (!jQuery.contains(document, buttonExistCheck[0])) { // Add a new 'update' button beside the current 'UnInstall' button // http://stackoverflow.com/questions/12618214/binding-jquery-events-before-dom-insertion $( '
' ).on('click', function(e) { e.preventDefault(); var pressedButton=$(this).attr('id'); var currentStatus=$(this).attr('class'); RespondToButtonPress(pressedButton,currentStatus); }).insertAfter("[id='button_" + themeName + "']"); $("[id='button_Update_" + themeNameForUpdate + "']").html("Update"); // set the vertical position to match the uninstall button var uninstallButtonTop=$("[id='button_" + themeName + "']").css("margin-top"); $("[id='button_Update_" + themeNameForUpdate + "']").css("margin-top",uninstallButtonTop); } // Change band background for themes with updates available // Note: bash script supplies this theme list in alphabetical order. // If themes are not called in alphabetical order this does not work. var currentThemeBand = $("[id='button_" + themeName + "']").closest("#ThemeBand"); var currentBandClass = currentThemeBand.attr('class'); // if UI is currently set to 'Show Installed' themes // then we only need to show update bands without shadows. var viewState = $(ShowHideToggleButton).text(); if (viewState.indexOf("Show All") >= 0) { $(currentThemeBand).attr("class","accordionUpdateNoShadow"); } else { // UI is set to 'Show all' themes so we need to figure out // if shadows are needed for the update bands. var aboveBandClass = currentThemeBand.prevAll("#ThemeBand").first().attr('class'); if(typeof aboveBandClass != 'undefined') { // not at top band if(aboveBandClass == "accordion") { $(currentThemeBand).attr("class","accordionUpdate"); } else { $(currentThemeBand).attr("class","accordionUpdateNoShadow"); } } else { // at top band $(currentThemeBand).attr("class","accordionUpdateNoShadow"); } } } //------------------------------------------------------------------------------------- function ChangeButtonsToUpdate() { $(".buttonInstall").attr('class', 'buttonUpdate'); $(".buttonInstall").html("Update"); } //------------------------------------------------------------------------------------- function SetUnVersionedControlIndicator(themeName) { // themeName will be the name of an installed theme // Display indicator to show theme is unversioned //$("[id='indicator_" + themeName + "']").html("\u2715"); $("[id='indicator_" + themeName + "']").html("?"); $("[id='indicator_" + themeName + "']").css("pointer-events","auto"); } //------------------------------------------------------------------------------------- function UpdateAndRefreshPartitionSelectMenu(list) { // Clear existing entries $(partitionSelect).empty(); // Add title menu option $("#partitionSelect").append(""); // Add list sent from bash script if (list != "") { splitList = (list).split(','); for (var t = 0; t < splitList.length; t++) { var parts = (splitList[t]).split(';'); var id = (parts[0]); var desc = (parts[1]); $("#partitionSelect").append(""); } } } //------------------------------------------------------------------------------------- function UpdateAndRefreshInstalledThemeDropDown(themeList) { // If menus exist in the DOM then populate them var test=$("#installedThemeDropDownNvram"); if (jQuery.contains(document, test[0])) { $(installedThemeDropDownNvram).empty(); populateDropDownMenu(installedThemeDropDownNvram,themeList); } //var test=$("#installedThemeDropDownNvramP"); //if (jQuery.contains(document, test[0])) { // $(installedThemeDropDownNvramP).empty(); // populateDropDownMenu(installedThemeDropDownNvramP,themeList); //} var test=$("#installedThemeDropDownConfigP"); if (jQuery.contains(document, test[0])) { $(installedThemeDropDownConfigP).empty(); populateDropDownMenu(installedThemeDropDownConfigP,themeList); } } //------------------------------------------------------------------------------------- function populateDropDownMenu(menu,themeList) { // Note: Bash script sends '-' when no theme is set. // This then sets the menu to '-' $(menu).append(""); //$(menu).append(""); $(menu).append(""); $(menu).append(""); for (var t = 0; t < themeList.length; t++) { if (themeList[t] != "") $(menu).append(""); } $(menu).append(""); $(menu).append(""); $(menu).append(""); $(menu).append(""); } //------------------------------------------------------------------------------------- function checkEntryAndInsertRemoveOptionIfBlank(menu) { var isThemeSet=$(menu).val(); var menuId=$(menu).attr('id'); if(isThemeSet != null && isThemeSet != " ") { // If remove option is not already in list then add the 'Remove Current Entry' option from the menu if ( $("#" + menuId + " option[value='!Remove!']").length == 0 ) { $("").insertAfter($("#" + menuId + " option:first")); } } } //------------------------------------------------------------------------------------- function imgErrorThumb(image){ image.onerror=""; image.src="assets/thumb_noimage.png"; return true; } //------------------------------------------------------------------------------------- function imgErrorPreview(image){ image.onerror=""; image.src="assets/preview_noimage.png"; return true; } //------------------------------------------------------------------------------------- function AddQuitButton(){ // Add button No $( '' ).on('click', function(e) { e.preventDefault(); // Terminate the app macgap.app.terminate(); }).insertAfter("[id='FeedbackButtons']"); // Set button text $("[id='feedback_Button_Quit']").html("Quit"); } //------------------------------------------------------------------------------------- function ShowHideUnInstalledThemes(showHide,expandCollapse) { if (showHide.indexOf("Show") >= 0) { if (expandCollapse.indexOf("Expand") >= 0) { $(".accordion").css("display","none"); } if (expandCollapse.indexOf("Collapse") >= 0) { $(".accordion").css("display","none"); $(".accordion").next('[class="accordionContent"]').css("display","none"); } // Remove all installed theme band shadows $(".accordionInstalled").attr("class","accordionInstalledNoShadow"); // Remove all update theme band shadows $(".accordionUpdate").attr("class","accordionUpdateNoShadow"); } else if (showHide.indexOf("Hide") >= 0) { if (expandCollapse.indexOf("Expand") >= 0) { $(".accordion").css("display","block"); } if (expandCollapse.indexOf("Collapse") >= 0) { $(".accordion").css("display","block"); $(".accordion").next('[class="accordionContent"]').css("display","block"); } // Reset all theme bands ResetButtonsAndBandsToDefault(); // Set all installed theme bands updateBandsWithInstalledThemes(gInstalledThemeListStr); } // Set all update theme bands if(gUpdateThemeListStr != "" ) ShowUpdateThemesInUI(gUpdateThemeListStr); } //------------------------------------------------------------------------------------- function ClosePreviewsForUninstalledThemes() { // Close all preview images for UnInstalled themes $('.buttonInstall').closest("#ThemeBand").next('[class="accordionContent"]').slideUp('normal'); } //------------------------------------------------------------------------------------- function sendNotification(messageBody) { // INSERT_NOTIFICATION_CODE_HERE } //------------------------------------------------------------------------------------- function SetPredictionText(message) { $("#predictionTheme").text(message); } //------------------------------------------------------------------------------------- function ShowHideControlOptions(state) { // Does the changeThemeContainer div exist in the DOM? var ctcDiv=$("#changeThemeContainer"); if (jQuery.contains(document, ctcDiv[0])) { var ctcDivExist=1; } var controlOptionsHidden = $('#changeThemeContainer').is(":hidden"); if (state == "Show") { // check it's not already showing if (ctcDivExist == 1 && controlOptionsHidden) { $('#changeThemeContainer').show(function() { SetFooterHeight("IncludeCO"); }); } else { // #changeThemeContainer does not exist. SetFooterHeight("IncludeCO"); } } else if (state == "Hide"){ // check it's not already hidden if (ctcDivExist == 1 && !controlOptionsHidden) { $('#changeThemeContainer').hide(function() { SetFooterHeight("ExcludeCO"); }); } else { // #changeThemeContainer does not exist. SetFooterHeight("ExcludeCO"); } } } //------------------------------------------------------------------------------------- function UpdateThemePaths(nvramPlistPath,configPlistPath,mountpoint) { // Replace paths in theme control option area //$('#ctTitleNvramP span').text(nvramPlistPath); $('#ctTitleConfig span').text(configPlistPath); // Unset any disabled control option drop down menus //$('#installedThemeDropDownNvramP').prop("disabled", false); $('#installedThemeDropDownConfigP').prop("disabled", false); // Update paths in bootlog $('.infoBodyReplaceable').each(function(){ var str = $(this).text(); var strTest = str.toUpperCase(); if (strTest.match("^/EFI")) { $(this).text(mountpoint+str); } }); } //------------------------------------------------------------------------------------- function ShowUpdateAllButton() { $("#ShowHideUpdateAllButton").show(); $(".spacerButtonUpdateAll").hide(); } //------------------------------------------------------------------------------------- function HideUpdateAllButton() { $("#ShowHideUpdateAllButton").hide(); $(".spacerButtonUpdateAll").show(); }