Plugin Directory

Changeset 2074973


Ignore:
Timestamp:
04/25/2019 07:47:17 PM (7 years ago)
Author:
paulswarthout
Message:

Added cursor wait for those things that take a while to run. Cleaned up the Javascript AJAX calls to make them consistent. Discovered naming conflicts with other plugins' Javascript functions and variables. Moved the common functions into a Javascript library of sorts.

Location:
child-themes-helper
Files:
67 added
2 deleted
12 edited

Legend:

Unmodified
Added
Removed
  • child-themes-helper/trunk/child-themes-helper.php

    r2073439 r2074973  
    99    Description: Tool to aid child theme developer. Copies files from the parent theme to the child theme, duplicating the folder structure in the child theme. Directly edit the child theme's files. Create a new child theme from any template theme.
    1010
    11     Version: 2.1.1
     11    Version: 2.2
    1212
    1313    Author: Paul A. Swarthout
  • child-themes-helper/trunk/classes/class_childThemesHelper.php

    r2072750 r2074973  
    217217                            Array( $this, 'pas_cth_tabPage' ),
    218218
    219                             "",
     219                            "dashicons-admin-appearance",
    220220
    221221                            61 // appears just below the Appearances menu.
     
    13761376            echo "<div class='createChildThemeBox'>";
    13771377
     1378            $urlPattern = "^[a-zA-Z]{4,5}\:/{2}[a-zA-Z0-9]{1}[a-zA-Z0-9:/\-\.\&\=\?]+$";
    13781379
    13791380
     
    14021403                    <br>
    14031404
    1404                     <input type='text' name='childThemeName' id='childThemeName' value='' required pattern='^[a-zA-Z][a-zA-Z0-9\-\ ]+' data-message='Child Theme Names must begin with a letter' onblur='javascript:pas_cth_validateField(this);'>
     1405                    <input required type='text' name='childThemeName' id='childThemeName' value='' data-pattern='^[a-zA-Z][a-zA-Z0-9\- ]+$' data-message='Child Theme Name: Names must begin with a letter and contain only numbers letters, spaces, and dashes. The name is required.' onblur='javascript:pas_cth_validateField(this);'>
    14051406
    14061407                </label>
     
    14141415            Theme URI<br>
    14151416
    1416             <input type='text' name='themeURI' id='themeURI' value='' pattern='^[a-zA-Z]{4,5}\://[a-zA-Z0-9:/\-\.\&\=\?]+$' data-message='Invalid URI' onblur='javascript:pas_cth_validateField(this);'>
     1417            <input type='text' name='themeURI' id='themeURI' value='' data-pattern='{$urlPattern}' data-message='Theme URI: The entered URL is not valid.' onblur='javascript:pas_cth_validateField(this);'>
    14171418
    14181419            </label><br>
     
    14221423            Theme Description<br>
    14231424
    1424             <textarea required id='description' name='description' pattern='^[a-zA-Z0-9\.:;?#\%,\(\)/ ]+$' data-message='You may use letters, numbers, and special characters that you would normally use in writing, only. No HTML or other scripts are allowed here.' onblur='javascript:pas_cth_validateField(this);'></textarea>
     1425            <textarea id='description' name='description' data-pattern='^[a-zA-Z0-9\.:;?#\%,\(\)/ ]+$' data-message='Description: You may use letters, numbers, and special characters that you would normally use in writing, only. No HTML or other scripts are allowed here.' onblur='javascript:pas_cth_validateField(this);'></textarea>
    14251426
    14261427            </label><br>
     
    14301431            Author Name:<br>
    14311432
    1432             <input type='text' id='authorName' name='authorName' value='' pattern='^[a-zA-Z \.]+$' data-message='upper or lower case, spaces, or periods, only.' onblur='javascript:pas_cth_validateField(this);'>
     1433            <input type='text' id='authorName' name='authorName' value='' data-pattern='^[a-zA-Z \.]+$' data-message='Author Name: You may use upper or lower case letters, spaces, or periods, only.' onblur='javascript:pas_cth_validateField(this);'>
    14331434
    14341435            </label><br>
     
    14381439            Author URI:<br>
    14391440
    1440             <input type='text' id='authorURI' name='authorURI' value=''  pattern='^[a-zA-Z]{4,5}\://[a-zA-Z0-9:/\-\.\&\=\?]+$' data-message='Invalid URI' onblur='javascript:pas_cth_validateField(this);'>
     1441            <input type='text' id='authorURI' name='authorURI' value=''  data-pattern='{$urlPattern}' data-message='Author URI: The entered URL is not valid.' onblur='javascript:pas_cth_validateField(this);'>
    14411442
    14421443            </label><br>
    14431444
    1444             <input type='hidden' id='version' name='version' value='0.0.1' readonly>
     1445            <input type='hidden' id='version' name='version' value='0.1.0' readonly>
    14451446
    14461447            <br>
     
    14681469                    class='blueButton'
    14691470
    1470                     onclick='javascript:this.form.reset();'
     1471                    onclick='javascript:pas_cth_js_resetChildThemeForm(this.form)'
    14711472
    14721473                >
  • child-themes-helper/trunk/css/style.css

    r2057158 r2074973  
    313313    font-style:italic;
    314314    color:black;
     315}
     316.pas_cth_errorCondition {
     317    background-color:#FFFF90;
    315318}
    316319@media (min-width:830px) {
     
    912915    background-color:rgba(255, 255, 255, .8);
    913916    color:black;
    914     z-index:99999;
     917    z-index:1000000;
    915918}
    916919#ef_readonly_msg    { grid-column:1 / span 4;   grid-row:1; }
     
    987990    font-size:12pt;
    988991    font-weight:bold;
     992    z-index:1000005;
    989993}
    990994#sp_saveButton, #sp_closeButton {
  • child-themes-helper/trunk/js/color_picker.js

    r2057158 r2074973  
     1"use strict;"
    12// /js/color_picker.js
    23
     
    463464function pas_cth_js_showColorPicker(clr) {
    464465
    465     var xmlhttp = new XMLHttpRequest();
    466 
    467     var data    = new FormData();
    468 
    469466    var currentColor = clr.value;
    470467
     
    472469
    473470
    474 
    475     data.append('action', 'displayColorPicker');
    476 
    477     data.append('initialColor', currentColor);
    478 
    479     data.append('callingFieldName', fieldName);
    480 
    481 
    482 
    483     xmlhttp.open("POST", ajaxurl,true);
    484 
    485 
    486 
    487     xmlhttp.onreadystatechange = function () {
    488 
    489         if (4 == xmlhttp.readyState) {
    490 
    491             // strip the AJAX zero from wp_die() WORDPRESS ONLY
    492 
    493             var response = (xmlhttp.responseText.length >= 1 ?
    494 
    495                                 xmlhttp.responseText.left(xmlhttp.responseText.length - 1) :
    496 
    497                                 xmlhttp.responseText);
    498 
    499 
    500 
    501             switch (xmlhttp.status) {
    502 
    503                 case 200: // Everything is Okay
    504 
    505                     /* If responseText is not empty, there might be a request to overwrite
    506 
    507                      * or a request to delete that needs to be displayed.
    508 
    509                      * else, reload the page.
    510 
    511                      * <= 1 accounts for the AJAX return of zero that sometimes shows up
    512 
    513                      * despite my best efforts to avoid that.
    514 
    515                      */
    516 
    517                     if (response.length <= 0) {
    518 
    519                         // refresh the current display
    520 
    521                         location.reload();
    522 
    523                     } else {
    524 
    525                         pas_cth_js_createColorWindow(response);
    526 
    527                         // display any output from the wp_ajax_* function.
    528 
    529 //                      pas_cth_js_processResponse(response);
    530 
    531                     }
    532 
    533                     break;
    534 
    535 
    536 
    537                 case 400: // There was an error
    538 
    539                     msg = "400 Error:<br>" + xmlhttp.statusText;
    540 
    541                     pas_cth_js_showBox().innerHTML = msg;
    542 
    543                     break;
     471    var dataBlock = {};
     472
     473
     474    dataBlock.initialColor = currentColor;
     475    dataBlock.callingFieldName = fieldName;
     476
     477    var successCallback = function (response) {
     478        if (response.length) {
     479            pas_cth_js_createColorWindow(response);
     480        } else {
     481            location.reload();
     482        }
     483    }
     484
     485
     486    pas_cth_js_AJAXCall('displayColorPicker', dataBlock, successCallback, pas_cth_js_failureCallback);
     487}
     488
     489
     490
     491function pas_cth_js_createColorWindow(response) {
     492
     493    var colorPickerWindow = document.getElementById("colorPickerWindow");
     494
     495    var theBody = document.getElementsByTagName("body")[0];
     496
     497    if (colorPickerWindow == null || colorPickerWindow == undefined) {
     498
     499        colorPickerWindow = document.createElement("div");
     500
     501        colorPickerWindow.setAttribute("id", "colorPickerWindow");
     502
     503        theBody.appendChild(colorPickerWindow);
     504
     505    }
     506
     507    colorPickerWindow.innerHTML = response;
     508
     509}
     510
     511function exitColorPickerDialog() {
     512
     513    var colorPickerWindow = document.getElementById("colorPickerWindow");
     514
     515    var parent = colorPickerWindow.parentNode;
     516
     517    if (parent != null) {
     518
     519        parent.removeChild(colorPickerWindow)
     520
     521    }
     522
     523    colorPickerWindow.remove();
     524
     525}
     526
     527function makeElement(id, name, type, value) {
     528
     529    var element = document.createElement("input");
     530
     531    element.setAttribute("id", id);
     532
     533    element.setAttribute("name", name);
     534
     535    element.setAttribute("type", type);
     536
     537    element.setAttribute("value", value);
     538
     539    return element;
     540
     541}
     542
     543function saveColor(button) {
     544
     545    var abbr = button.getAttribute("data-abbr");
     546
     547    var cp = new colorPickerElements(abbr);
     548
     549    var dataBlock = {};
     550    cp.initialColor.value = cp.hexval.value;
     551
     552
     553
     554    var jsInput;
     555
     556
     557
     558    dataBlock.hexColorCode = cp.hexval.value;
     559    dataBlock.abbreviation = abbr;
     560
     561    cp.saveButton.disabled = true;
     562    cp.resetButton.disabled = true;
     563
     564    pas_cth_js_AJAXCall('saveOptions', dataBlock, pas_cth_js_successCallback, pas_cth_js_failureCallback);
     565}
     566
     567function resetColor(element) {
     568
     569    var abbr = element.id.left(element.id.length - "_resetButton".length)
     570
     571    var cp = new colorPickerElements(abbr);
     572
     573    cp.hexval.value = cp.initialColor.value;
     574
     575    var hexcolors = cp.hexColor2Decimal(cp.initialColor.value);
     576
     577    cp.rval.value = hexcolors.red;
     578
     579    cp.gval.value = hexcolors.green;
     580
     581    cp.bval.value = hexcolors.blue;
     582
     583
     584
     585    cp.redSlider.value = hexcolors.red;
     586
     587    cp.greenSlider.value = hexcolors.green;
     588
     589    cp.blueSlider.value = hexcolors.blue;
     590
     591
     592
     593    updateColorPicker(abbr);
     594
     595    cp.saveButton.disabled = true;
     596
     597    cp.resetButton.disabled = true;
     598
     599
     600
     601}
     602
     603// Get Complementary color
     604
     605function invertColor(hex, bw = true) {
     606
     607    if (hex.indexOf('#') === 0) {
     608
     609        hex = hex.slice(1);
     610
     611    }
     612
     613    var r = parseInt(hex.slice(0, 2), 16),
     614
     615        g = parseInt(hex.slice(2, 4), 16),
     616
     617        b = parseInt(hex.slice(4, 6), 16);
     618
     619    if (bw) {
     620
     621        // http://stackoverflow.com/a/3943023/112731
     622
     623        return (r * 0.299 + g * 0.587 + b * 0.114) > 186
     624
     625            ? '#000000'
     626
     627            : '#FFFFFF';
     628
     629    }
     630
     631    // invert color components
     632
     633    r = (255 - r).toString(16).digits(2);
     634
     635    g = (255 - g).toString(16).digits(2);
     636
     637    b = (255 - b).toString(16).digits(2);
     638
     639    // pad each with zeros and return
     640
     641    return "#" + r + g + b;
     642
     643}
     644
     645function showDropDown(listBoxID) {
     646
     647    var listBox = document.getElementById(listBoxID)
     648
     649    if (listBox.style.display == "") {
     650
     651        listBox.style.display = "inline-block";
     652
     653    } else {
     654
     655        listBox.style.display = "";
     656
     657    }
     658
     659}
     660
     661function selectThisFont(fontDataElement) {
     662
     663    var fontData = JSON.parse(fontDataElement.getAttribute("data-font"));
     664
     665    var row             = fontData['data-row'];
     666
     667    var fontName        = row['fontName']
     668
     669    var fontBase        = row['fontFile-base'];
     670
     671    var fontFile        = fontData['url'] + fontBase + ".ttf";
     672
     673    var fontSampleImg   = fontData['url'] + fontBase + ".png";
     674
     675
     676
     677    var textBox = document.getElementById(fontData['text-box']);
     678
     679    var listBox = document.getElementById(fontData['list-box']);
     680
     681
     682
     683    var selectedFontNameElement = document.getElementById("selectedFontName")
     684;
     685    var selectedFontSampleElement = document.getElementById("selectedFontSample")
     686;
     687   
     688    var dataBlock = {};
     689
     690
     691    selectedFontNameElement.innerHTML = fontName
     692
     693
     694
     695    var img = document.getElementById("sampleFontImage")
     696
     697    if (img != null) {
     698
     699        if (img.parentNode != null) {
     700
     701            img.parentNode.removeChild(img);
     702
     703        }
     704
     705        img.remove();
     706
     707    }
     708
     709    img = document.createElement("img")
     710
     711    img.setAttribute("id", "sampleFontImage")
     712
     713    img.src = fontSampleImg
     714
     715    img.style.cssText = "visibility:visible;display:inline;";
     716
     717    selectedFontSampleElement.appendChild(img)
     718
     719
     720
     721    textBox.style.display = "inline";
     722
     723    listBox.style.display = "none";
     724
     725
     726
     727    dataBlock.fontName = fontName;
     728    dataBlock['fontFile-base'] = fontBase;
     729
     730    var successCallback = function (response) {
     731        if (response.length) {
     732            pas_cth_js_processResponse(response);
     733            pas_cth_js_hideWait();
     734        }
     735    }
     736
     737    pas_cth_js_AJAXCall('saveDefaultFont', dataBlock, successCallback, pas_cth_js_failureCallback);
     738}
     739
     740function test(abbr) {
     741
     742    var r = document.getElementById(abbr + "_rval_cell")
     743
     744    r.style.backgroundColor = "#00FF00";
     745
     746
     747
     748    var rslidercell = document.getElementById(abbr + "_redSlider_cell")
     749
     750    var gslidercell = document.getElementById(abbr + "_greenSlider_cell")
     751
     752    var bslidercell = document.getElementById(abbr + "_blueSlider_cell")
     753
     754}
     755
     756
     757
     758function makeItDarker(element) {
     759
     760    var abbr = element.id.left(element.id.length - "_darkerBTN".length);
     761
     762    var cp = new colorPickerElements(abbr);
     763
     764
     765
     766    var cv = new colorValues(cp);
     767
     768
     769
     770    var minColor = getMinColor(cv.redValue, cv.greenValue, cv.blueValue);
     771
     772    var adjustValue = 255 * 0.05; // 5%
     773
     774
     775
     776    cp.rval.value = (parseInt(cp.rval.value, 10) - adjustValue < 0 ? 0 : parseInt(cp.rval.value, 10) - adjustValue);
     777
     778    cp.redSlider.value = cp.rval.value;
     779
     780
     781
     782    cp.gval.value = (parseInt(cp.gval.value, 10) - adjustValue < 0 ? 0 : parseInt(cp.gval.value, 10) - adjustValue);
     783
     784    cp.greenSlider.value = cp.gval.value;
     785
     786
     787
     788    cp.bval.value = (parseInt(cp.bval.value, 10) - adjustValue < 0 ? 0 : parseInt(cp.bval.value, 10) - adjustValue);
     789
     790    cp.blueSlider.value = cp.bval.value;
     791
     792    updateColorPicker(abbr);
     793
     794}
     795
     796function makeItLighter(element) {
     797
     798    var abbr = element.id.left(element.id.length - "_lighterBTN".length);
     799
     800    var cp = new colorPickerElements(abbr);
     801
     802
     803
     804    var cv = new colorValues(cp);
     805
     806
     807
     808    var maxColor = getMaxColor(cv.redValue, cv.greenValue, cv.blueValue);
     809
     810    var adjustValue = 255 * 0.05; // 5%
     811
     812
     813
     814    cp.rval.value = (parseInt(cp.rval.value, 10) + adjustValue > 255 ? 255 : parseInt(cp.rval.value, 10) + adjustValue);
     815
     816    cp.redSlider.value = cp.rval.value;
     817
     818
     819
     820    cp.gval.value = (parseInt(cp.gval.value, 10) + adjustValue > 255 ? 255 : parseInt(cp.gval.value, 10) + adjustValue);
     821
     822    cp.greenSlider.value = cp.gval.value;
     823
     824
     825
     826    cp.bval.value = (parseInt(cp.bval.value, 10) + adjustValue > 255 ? 255 : parseInt(cp.bval.value, 10) + adjustValue);
     827
     828    cp.blueSlider.value = cp.bval.value;
     829
     830    updateColorPicker(abbr);
     831
     832}
     833
     834function setWebColor(element, color) {
     835
     836    var abbr = element.getAttribute("data-abbr");
     837
     838    var cp = new colorPickerElements(abbr);
     839
     840    var decvalues = cp.hexColor2Decimal(color);
     841
     842
     843
     844    cp.rval.value = decvalues.red;
     845
     846    cp.gval.value = decvalues.green;
     847
     848    cp.bval.value = decvalues.blue;
     849
     850
     851
     852    cp.redSlider.value = decvalues.red;
     853
     854    cp.greenSlider.value = decvalues.green;
     855
     856    cp.blueSlider.value = decvalues.blue;
     857
     858    cp.hexval.value = color;
     859
     860
     861
     862    updateColorPicker(abbr);
     863
     864}
     865
     866function generateScreenShot(abbr) {
     867
     868    var saveBTNs = new eList(document.getElementsByClassName("saveButton")).toArray();
     869
     870    var unsavedCount = 0;
     871
     872
     873
     874    saveBTNs.map(function (cell) {
     875
     876        if (! cell.disabled ) {
     877
     878            unsavedCount++;
     879
     880        }
     881
     882    });
     883
     884
     885
     886    if (unsavedCount > 0) {
     887
     888        var box = pas_cth_library.displayError("Please save or reset your changes before attempting to generate a new screenshot for your child theme.");
     889
     890        var p = document.createElement("P");
     891
     892        p.innerHTML = "close [X]";
     893
     894        box.appendChild(p);
     895
     896        return;
     897
     898    }
     899
     900    var displayScreenshotFile = function (xmlResponse) {
     901
     902        var parser = new DOMParser();
     903
     904        var xmlDoc = parser.parseFromString(xmlResponse,"text/xml");
     905
     906        var records = xmlDoc.getElementsByTagName("record");
     907
     908        var site_url    = records[0].getElementsByTagName("siteURL")[0].textContent;
     909
     910        var stylesheet  = records[0].getElementsByTagName("stylesheet")[0].textContent;
     911
     912        var filename    = records[0].getElementsByTagName("filename")[0].textContent;
     913
     914
     915
     916        var box = pas_cth_library.createBox("screenshotBox")
     917        box.onclick = function () {
     918
     919            if (this.parentNode != null) {
     920
     921                this.parentNode.removeChild(this);
    544922
    545923            }
    546924
     925            this.remove();
     926
    547927        }
    548928
    549     }
    550 
    551     xmlhttp.send(data);
    552 
    553 }
    554 
    555 
    556 
    557 function pas_cth_js_createColorWindow(response) {
    558 
    559     var colorPickerWindow = document.getElementById("colorPickerWindow");
    560 
    561     var theBody = document.getElementsByTagName("body")[0];
    562 
    563     if (colorPickerWindow == null || colorPickerWindow == undefined) {
    564 
    565         colorPickerWindow = document.createElement("div");
    566 
    567         colorPickerWindow.setAttribute("id", "colorPickerWindow");
    568 
    569         theBody.appendChild(colorPickerWindow);
    570 
    571     }
    572 
    573     colorPickerWindow.innerHTML = response;
    574 
    575 }
    576 
    577 function exitColorPickerDialog() {
    578 
    579     var colorPickerWindow = document.getElementById("colorPickerWindow");
    580 
    581     var parent = colorPickerWindow.parentNode;
    582 
    583     if (parent != null) {
    584 
    585         parent.removeChild(colorPickerWindow)
    586 
    587     }
    588 
    589     colorPickerWindow.remove();
    590 
    591 }
    592 
    593 function makeElement(id, name, type, value) {
    594 
    595     var element = document.createElement("input");
    596 
    597     element.setAttribute("id", id);
    598 
    599     element.setAttribute("name", name);
    600 
    601     element.setAttribute("type", type);
    602 
    603     element.setAttribute("value", value);
    604 
    605     return element;
    606 
    607 }
    608 
    609 function saveColor(button) {
    610 
    611     var abbr = button.getAttribute("data-abbr");
    612 
    613     var cp = new colorPickerElements(abbr);
    614 
    615     cp.initialColor.value = cp.hexval.value;
    616 
    617 
    618 
    619     var xmlhttp = new XMLHttpRequest();
    620 
    621     var data = new FormData();
    622 
    623     var jsInput;
    624 
    625 
    626 
    627     data.append("hexColorCode", cp.hexval.value);
    628 
    629     data.append("abbreviation", abbr);
    630 
    631     data.append("action", "saveOptions");
    632 
    633 
    634 
    635     xmlhttp.open("POST", ajaxurl,true);
    636 
    637 
    638 
    639     xmlhttp.onreadystatechange = function () {
    640 
    641         if (4 == xmlhttp.readyState) {
    642 
    643             var response = (xmlhttp.responseText.length >= 1 ?
    644 
    645                                 xmlhttp.responseText.left(xmlhttp.responseText.length - 1) :
    646 
    647                                 xmlhttp.responseText);
    648 
    649 
    650 
    651             switch (xmlhttp.status) {
    652 
    653                 case 200: // Everything is okay
    654 
    655                     if (response.length <= 0) {
    656 
    657                     } else {
    658 
    659                         pas_cth_js_processResponse(response);
    660 
    661                     }
    662 
    663                     break;
    664 
    665 
    666 
    667                 case 400:
    668 
    669                     msg = "400 Error:<br>" + xmlhttp.statusText;
    670 
    671                     pas_cth_js_showBox().innerHTML = msg;
    672 
    673                     break;
    674 
    675             }
    676 
    677         }
    678 
    679     }
    680 
    681     cp.saveButton.disabled = true;
    682 
    683     cp.resetButton.disabled = true;
    684 
    685     xmlhttp.send(data)
    686 
    687 }
    688 
    689 function resetColor(element) {
    690 
    691     var abbr = element.id.left(element.id.length - "_resetButton".length)
    692 
    693     var cp = new colorPickerElements(abbr);
    694 
    695     cp.hexval.value = cp.initialColor.value;
    696 
    697     var hexcolors = cp.hexColor2Decimal(cp.initialColor.value);
    698 
    699     cp.rval.value = hexcolors.red;
    700 
    701     cp.gval.value = hexcolors.green;
    702 
    703     cp.bval.value = hexcolors.blue;
    704 
    705 
    706 
    707     cp.redSlider.value = hexcolors.red;
    708 
    709     cp.greenSlider.value = hexcolors.green;
    710 
    711     cp.blueSlider.value = hexcolors.blue;
    712 
    713 
    714 
    715     updateColorPicker(abbr);
    716 
    717     cp.saveButton.disabled = true;
    718 
    719     cp.resetButton.disabled = true;
    720 
    721 
    722 
    723 }
    724 
    725 // Get Complementary color
    726 
    727 function invertColor(hex, bw = true) {
    728 
    729     if (hex.indexOf('#') === 0) {
    730 
    731         hex = hex.slice(1);
    732 
    733     }
    734 
    735     var r = parseInt(hex.slice(0, 2), 16),
    736 
    737         g = parseInt(hex.slice(2, 4), 16),
    738 
    739         b = parseInt(hex.slice(4, 6), 16);
    740 
    741     if (bw) {
    742 
    743         // http://stackoverflow.com/a/3943023/112731
    744 
    745         return (r * 0.299 + g * 0.587 + b * 0.114) > 186
    746 
    747             ? '#000000'
    748 
    749             : '#FFFFFF';
    750 
    751     }
    752 
    753     // invert color components
    754 
    755     r = (255 - r).toString(16).digits(2);
    756 
    757     g = (255 - g).toString(16).digits(2);
    758 
    759     b = (255 - b).toString(16).digits(2);
    760 
    761     // pad each with zeros and return
    762 
    763     return "#" + r + g + b;
    764 
    765 }
    766 
    767 function showDropDown(listBoxID) {
    768 
    769     var listBox = document.getElementById(listBoxID)
    770 
    771     if (listBox.style.display == "") {
    772 
    773         listBox.style.display = "inline-block";
    774 
    775     } else {
    776 
    777         listBox.style.display = "";
    778 
    779     }
    780 
    781 }
    782 
    783 function selectThisFont(fontDataElement) {
    784 
    785     var fontData = JSON.parse(fontDataElement.getAttribute("data-font"));
    786 
    787     var row             = fontData['data-row'];
    788 
    789     var fontName        = row['fontName']
    790 
    791     var fontBase        = row['fontFile-base'];
    792 
    793     var fontFile        = fontData['url'] + fontBase + ".ttf";
    794 
    795     var fontSampleImg   = fontData['url'] + fontBase + ".png";
    796 
    797 
    798 
    799     var textBox = document.getElementById(fontData['text-box']);
    800 
    801     var listBox = document.getElementById(fontData['list-box']);
    802 
    803 
    804 
    805     var selectedFontNameElement = document.getElementById("selectedFontName")
    806 
    807     var selectedFontSampleElement = document.getElementById("selectedFontSample")
    808 
    809 
    810 
    811     selectedFontNameElement.innerHTML = fontName
    812 
    813 
    814 
    815     var img = document.getElementById("sampleFontImage")
    816 
    817     if (img != null) {
    818 
    819         if (img.parentNode != null) {
    820 
    821             img.parentNode.removeChild(img);
    822 
    823         }
    824 
    825         img.remove();
    826 
    827     }
    828 
    829     img = document.createElement("img")
    830 
    831     img.setAttribute("id", "sampleFontImage")
    832 
    833     img.src = fontSampleImg
    834 
    835     img.style.cssText = "visibility:visible;display:inline;";
    836 
    837     selectedFontSampleElement.appendChild(img)
    838 
    839 
    840 
    841     textBox.style.display = "inline";
    842 
    843     listBox.style.display = "none";
    844 
    845 
    846 
    847     var xmlhttp = new XMLHttpRequest();
    848 
    849     var data = new FormData();
    850 
    851     data.append("action", "saveDefaultFont");
    852 
    853     data.append("fontName", fontName);
    854 
    855     data.append("fontFile-base", fontBase);
    856 
    857 
    858 
    859     xmlhttp.open("POST", ajaxurl,true);
    860 
    861     xmlhttp.onreadystatechange = function () {
    862 
    863 
    864 
    865         if (4 == xmlhttp.readyState) {
    866 
    867             // strip the AJAX zero from wp_die() WORDPRESS ONLY
    868 
    869             var response = (xmlhttp.responseText.length >= 1 ?
    870 
    871                                 xmlhttp.responseText.left(xmlhttp.responseText.length - 1) :
    872 
    873                                 xmlhttp.responseText);
    874 
    875             switch (xmlhttp.status) {
    876 
    877                 case 200: // Everything is Okay
    878 
    879                     /* If responseText is not empty, there might be a request to overwrite
    880 
    881                      * or a request to delete that needs to be displayed.
    882 
    883                      * else, reload the page.
    884 
    885                      * <= 1 accounts for the AJAX return of zero that sometimes shows up
    886 
    887                      * despite my best efforts to avoid that.
    888 
    889                      */
    890 
    891                     if (response.length <= 0) {
    892 
    893                         // do nothing. Just return.
    894 
    895 
    896 
    897                     } else {
    898 
    899                         // display any output from the wp_ajax_* function.
    900 
    901                         pas_cth_js_processResponse(response);
    902 
    903                     }
    904 
    905                     break;
    906 
    907 
    908 
    909                 case 400: // There was an error
    910 
    911                     msg = "400 Error:<br>" + xmlhttp.statusText;
    912 
    913                     pas_cth_js_showBox().innerHTML = msg;
    914 
    915                     break;
    916 
    917             }
    918 
    919         }
    920 
    921     }
    922 
    923     xmlhttp.send(data);
    924 
    925 }
    926 
    927 function test(abbr) {
    928 
    929     var r = document.getElementById(abbr + "_rval_cell")
    930 
    931     r.style.backgroundColor = "#00FF00";
    932 
    933 
    934 
    935     var rslidercell = document.getElementById(abbr + "_redSlider_cell")
    936 
    937     var gslidercell = document.getElementById(abbr + "_greenSlider_cell")
    938 
    939     var bslidercell = document.getElementById(abbr + "_blueSlider_cell")
    940 
    941 }
    942 
    943 
    944 
    945 function makeItDarker(element) {
    946 
    947     var abbr = element.id.left(element.id.length - "_darkerBTN".length);
    948 
    949     var cp = new colorPickerElements(abbr);
    950 
    951 
    952 
    953     var cv = new colorValues(cp);
    954 
    955 
    956 
    957     var minColor = getMinColor(cv.redValue, cv.greenValue, cv.blueValue);
    958 
    959     var adjustValue = 255 * 0.05; // 5%
    960 
    961 
    962 
    963     cp.rval.value = (parseInt(cp.rval.value, 10) - adjustValue < 0 ? 0 : parseInt(cp.rval.value, 10) - adjustValue);
    964 
    965     cp.redSlider.value = cp.rval.value;
    966 
    967 
    968 
    969     cp.gval.value = (parseInt(cp.gval.value, 10) - adjustValue < 0 ? 0 : parseInt(cp.gval.value, 10) - adjustValue);
    970 
    971     cp.greenSlider.value = cp.gval.value;
    972 
    973 
    974 
    975     cp.bval.value = (parseInt(cp.bval.value, 10) - adjustValue < 0 ? 0 : parseInt(cp.bval.value, 10) - adjustValue);
    976 
    977     cp.blueSlider.value = cp.bval.value;
    978 
    979     updateColorPicker(abbr);
    980 
    981 }
    982 
    983 function makeItLighter(element) {
    984 
    985     var abbr = element.id.left(element.id.length - "_lighterBTN".length);
    986 
    987     var cp = new colorPickerElements(abbr);
    988 
    989 
    990 
    991     var cv = new colorValues(cp);
    992 
    993 
    994 
    995     var maxColor = getMaxColor(cv.redValue, cv.greenValue, cv.blueValue);
    996 
    997     var adjustValue = 255 * 0.05; // 5%
    998 
    999 
    1000 
    1001     cp.rval.value = (parseInt(cp.rval.value, 10) + adjustValue > 255 ? 255 : parseInt(cp.rval.value, 10) + adjustValue);
    1002 
    1003     cp.redSlider.value = cp.rval.value;
    1004 
    1005 
    1006 
    1007     cp.gval.value = (parseInt(cp.gval.value, 10) + adjustValue > 255 ? 255 : parseInt(cp.gval.value, 10) + adjustValue);
    1008 
    1009     cp.greenSlider.value = cp.gval.value;
    1010 
    1011 
    1012 
    1013     cp.bval.value = (parseInt(cp.bval.value, 10) + adjustValue > 255 ? 255 : parseInt(cp.bval.value, 10) + adjustValue);
    1014 
    1015     cp.blueSlider.value = cp.bval.value;
    1016 
    1017     updateColorPicker(abbr);
    1018 
    1019 }
    1020 
    1021 function setWebColor(element, color) {
    1022 
    1023     var abbr = element.getAttribute("data-abbr");
    1024 
    1025     var cp = new colorPickerElements(abbr);
    1026 
    1027     var decvalues = cp.hexColor2Decimal(color);
    1028 
    1029 
    1030 
    1031     cp.rval.value = decvalues.red;
    1032 
    1033     cp.gval.value = decvalues.green;
    1034 
    1035     cp.bval.value = decvalues.blue;
    1036 
    1037 
    1038 
    1039     cp.redSlider.value = decvalues.red;
    1040 
    1041     cp.greenSlider.value = decvalues.green;
    1042 
    1043     cp.blueSlider.value = decvalues.blue;
    1044 
    1045     cp.hexval.value = color;
    1046 
    1047 
    1048 
    1049     updateColorPicker(abbr);
    1050 
    1051 }
    1052 
    1053 function generateScreenShot(abbr) {
    1054 
    1055     var saveBTNs = new eList(document.getElementsByClassName("saveButton")).toArray();
    1056 
    1057     var unsavedCount = 0;
    1058 
    1059 
    1060 
    1061     saveBTNs.map(function (cell) {
    1062 
    1063         if (! cell.disabled ) {
    1064 
    1065             unsavedCount++;
    1066 
    1067         }
    1068 
    1069     });
    1070 
    1071 
    1072 
    1073     if (unsavedCount > 0) {
    1074 
    1075         var box = displayError("Please save or reset your changes before attempting to generate a new screenshot for your child theme.");
     929        var theBody = document.getElementsByTagName("body")[0];
    1076930
    1077931        var p = document.createElement("P");
    1078932
    1079         p.innerHTML = "close [X]";
     933        p.appendChild(document.createTextNode("[X] close"));
     934
     935
     936
     937        var img = document.createElement("IMG");
     938
     939        img.src = site_url + "/wp-content/themes/" + stylesheet + "/" + filename + "?cacheBuster=" + Date.now();
     940
     941        box.appendChild(img);
    1080942
    1081943        box.appendChild(p);
    1082944
    1083         return;
    1084 
    1085     }
    1086 
    1087     var displayScreenshotFile = function (xmlResponse) {
    1088 
    1089         var parser = new DOMParser();
    1090 
    1091         var xmlDoc = parser.parseFromString(xmlResponse,"text/xml");
    1092 
    1093         var records = xmlDoc.getElementsByTagName("record");
    1094 
    1095         var site_url    = records[0].getElementsByTagName("siteURL")[0].textContent;
    1096 
    1097         var stylesheet  = records[0].getElementsByTagName("stylesheet")[0].textContent;
    1098 
    1099         var filename    = records[0].getElementsByTagName("filename")[0].textContent;
    1100 
    1101 
    1102 
    1103         var box = document.createElement("DIV");
    1104 
    1105         box.onclick = function () {
    1106 
    1107             if (this.parentNode != null) {
    1108 
    1109                 this.parentNode.removeChild(this);
    1110 
    1111             }
    1112 
    1113             this.remove();
    1114 
    1115         }
    1116 
    1117         var theBody = document.getElementsByTagName("body")[0];
    1118 
    1119         box.id = "screenshotBox";
    1120 
    1121         var p = document.createElement("P");
    1122 
    1123         p.appendChild(document.createTextNode("[X] close"));
    1124 
    1125 
    1126 
    1127         var img = document.createElement("IMG");
    1128 
    1129         img.src = site_url + "/wp-content/themes/" + stylesheet + "/" + filename + "?cacheBuster=" + Date.now();
    1130 
    1131         box.appendChild(img);
    1132 
    1133         box.appendChild(p);
    1134 
    1135         theBody.appendChild(box);
    1136 
    1137945    }
    1138946
  • child-themes-helper/trunk/js/edit_file.js

    r2057158 r2074973  
     1"use strict;"
    12if (typeof String.prototype.toBold == "undefined") {
    23
     
    145146    var element = document.getElementById(event.srcElement.dataset.elementid);
    146147
    147     var xmlhttp = new XMLHttpRequest();
    148 
    149     var data = new FormData();
     148    var dataBlock = {};
    150149
    151150    var jsInput = JSON.parse(element.getAttribute("data-jsdata"));
     
    187186
    188187
    189     xmlhttp.open("POST", ajaxurl, true);
    190 
    191 
    192 
    193     data.append("action",    'editFile');
    194 
    195     data.append("directory", jsInput['directory'] );
    196 
    197     data.append("file",      jsInput['file']);
    198 
    199     data.append("themeType", jsInput['themeType'] );
    200 
    201 
    202 
    203     xmlhttp.onreadystatechange = function () {
    204 
    205         if (4 == xmlhttp.readyState) {
    206 
    207             var response = (xmlhttp.responseText.length >= 1 ?
    208 
    209                                 xmlhttp.responseText.left(xmlhttp.responseText.length - 1) :
    210 
    211                                 xmlhttp.responseText);
    212 
    213 
    214 
    215             switch (xmlhttp.status) {
    216 
    217                 case 200: // Everything is okay
    218 
    219                     if (response.length <= 0) {
    220 
    221                         location.reload();
    222 
    223                     } else {
    224 
    225                         /*
    226 
    227                          * Function pas_cth_js_processResponse is in the js_common_fn.js file
    228 
    229                          * which then passes control back to the processEditFile() in this file.
    230 
    231                          */
    232 
    233                         pas_cth_js_processResponse(response);
    234 
    235                     }
    236 
    237                     break;
    238 
    239 
    240 
    241                 case 400:
    242 
    243                     msg = "400 Error:<br>" + xmlhttp.statusText;
    244 
    245                     pas_cth_js_showBox().innerHTML = msg;
    246 
    247                     break;
     188    dataBlock.directory = jsInput['directory'];
     189    dataBlock.file      = jsInput['file'];
     190    dataBlock.themeType = jsInput['themeType'];
     191
     192
     193    pas_cth_js_AJAXCall('editFile', dataBlock, pas_cth_js_successCallback, pas_cth_js_failureCallback);
     194}
     195
     196function captureKeystrokes(element) {
     197
     198    switch (event.keyCode) {
     199
     200        case 9:
     201
     202            event.preventDefault();
     203
     204            insertTextAtCursor(String.fromCharCode(event.keyCode));
     205
     206            editBoxChange();
     207
     208            break;
     209
     210        case 10:
     211
     212        case 13:
     213
     214            event.preventDefault();
     215
     216            insertTextAtCursor(String.fromCharCode(10));
     217
     218            editBoxChange();
     219
     220            break;
     221
     222        case 90: // CAP Z
     223
     224            if (event.ctrlKey) { // CTRL-Z (undo) // doesn't currently work in all cases. Need to rewrite the edit handling to use execCommand.
    248225
    249226            }
    250227
     228            break;
     229
     230        case 16: // left shift
     231
     232        case 8:  // backspace
     233
     234        case 17: // left CTRL
     235
     236            break;
     237
     238        default:
     239
     240            break;
     241
     242    }
     243
     244}
     245
     246function clearSelection() {
     247
     248    var sel = window.getSelection ? window.getSelection() : document.selection;
     249
     250    if (sel) {
     251
     252        if (sel.removeAllRanges) {
     253
     254            sel.removeAllRanges();
     255
     256        } else if (sel.empty) {
     257
     258            sel.empty();
     259
    251260        }
    252261
    253262    }
    254263
    255     xmlhttp.send(data)
    256 
    257 }
    258 
    259 function captureKeystrokes(element) {
    260 
    261     switch (event.keyCode) {
    262 
    263         case 9:
    264 
    265             event.preventDefault();
    266 
    267             insertTextAtCursor(String.fromCharCode(event.keyCode));
    268 
    269             editBoxChange();
    270 
    271             break;
    272 
    273         case 10:
    274 
    275         case 13:
    276 
    277             event.preventDefault();
    278 
    279             insertTextAtCursor(String.fromCharCode(10));
    280 
    281             editBoxChange();
    282 
    283             break;
    284 
    285         case 90: // CAP Z
    286 
    287             if (event.ctrlKey) { // CTRL-Z (undo) // doesn't currently work in all cases. Need to rewrite the edit handling to use execCommand.
    288 
    289             }
    290 
    291             break;
    292 
    293         case 16: // left shift
    294 
    295         case 8:  // backspace
    296 
    297         case 17: // left CTRL
    298 
    299             break;
    300 
    301         default:
    302 
    303             break;
    304 
    305     }
    306 
    307 }
    308 
    309 function clearSelection() {
    310 
    311     var sel = window.getSelection ? window.getSelection() : document.selection;
    312 
    313     if (sel) {
    314 
    315         if (sel.removeAllRanges) {
    316 
    317             sel.removeAllRanges();
    318 
    319         } else if (sel.empty) {
    320 
    321             sel.empty();
    322 
     264}
     265
     266function insertTextAtCursor(text) {
     267
     268    var sel, range, html;
     269
     270    var cursorPosition = saveSelection();
     271
     272
     273
     274    if (window.getSelection) {
     275
     276        sel = window.getSelection();
     277
     278
     279
     280        if (sel.getRangeAt && sel.rangeCount) {
     281
     282            range = sel.getRangeAt(0);
     283
     284            range.deleteContents();
     285
     286            restoreSelection(cursorPosition);
     287
     288            range.insertNode( document.createTextNode(text) );
     289
     290            range.collapse();
     291
     292        }
     293
     294    } else if (document.selection && document.selection.createRange) {
     295
     296        document.selection.createRange().text = text;
     297
     298        document.selection.collapse();
     299
     300    }
     301
     302
     303
     304
     305
     306}
     307
     308function saveSelection() {
     309
     310    if (window.getSelection) {
     311
     312        sel = window.getSelection();
     313
     314        if (sel.getRangeAt && sel.rangeCount) {
     315
     316            return sel.getRangeAt(0);
     317
     318        }
     319
     320    } else if (document.selection && document.selection.createRange) {
     321
     322        return document.selection.createRange();
     323
     324    }
     325
     326    return null;
     327
     328}
     329
     330
     331
     332function restoreSelection(range) {
     333
     334    if (range) {
     335
     336        if (window.getSelection) {
     337
     338            sel = window.getSelection();
     339
     340            sel.removeAllRanges();
     341
     342            sel.addRange(range);
     343
     344        } else if (document.selection && range.select) {
     345
     346            range.select();
     347
     348        }
     349
     350    }
     351
     352}
     353
     354function processEditFile(response) {
     355
     356    var ee = new pas_cth_js_editElements();
     357
     358    var responseSections = parseOutput(response);
     359
     360    responseSections.ARGS = JSON.parse(responseSections.ARGS);
     361
     362
     363
     364    ee.directoryINP.value = responseSections.ARGS['directory'];
     365
     366    ee.filenameINP.value = responseSections.ARGS['file'];
     367
     368    ee.themeTypeINP.value = responseSections.ARGS['themeType'];
     369
     370    ee.readOnlyFlag.value = responseSections.ARGS['readOnlyFlag'];
     371
     372    ee.filenameDisplay.innerHTML = "FILE: " + responseSections.ARGS['directory'] + "/" + responseSections.ARGS['file'];
     373
     374
     375
     376    ee.efSaveButton.disabled = true;
     377
     378
     379
     380    ee.editBox.innerHTML = responseSections.EDITBOX
     381
     382
     383
     384    enableContent(ee);
     385
     386
     387
     388    if (ee.readOnlyFlag.value.toLowerCase() == "true") {
     389
     390        ee.readOnlyMsg.style.display = "inline";
     391
     392    } else {
     393
     394        ee.readOnlyMsg.style.display = "none";
     395
     396    }
     397
     398
     399
     400    ee.editBox.onkeydown = function () { captureKeystrokes(this) }
     401
     402
     403
     404    ee.shield.style.display = "inline";
     405
     406    ee.editFile.style.display = "grid";
     407
     408
     409
     410}
     411
     412function enableContent(elements) {
     413
     414    elements.editBox.contentEditable        = true;
     415
     416
     417
     418    elements.efSaveButton.contentEditable   = false;
     419
     420    elements.efCloseButton.contentEditable  = false;
     421
     422
     423
     424    elements.savePrompt.contentEditable     = false;
     425
     426    elements.spSaveButton.contentEditable   = false;
     427
     428    elements.spCloseButton.contentEditable  = false;
     429
     430}
     431
     432
     433
     434function pas_cth_js_closeEditFile() {
     435
     436    var ee = new pas_cth_js_editElements();
     437
     438
     439
     440    if ( ! ee.efSaveButton.disabled) { // not disabled = visible
     441
     442        ee.savePrompt.style.display = "inline"
     443
     444        ee.efSaveButton.disabled = true;
     445
     446    } else {
     447
     448//      ee.themeGrid.style.display = "inline-grid";
     449
     450        ee.editFile.style.display = "none";
     451
     452        ee.shield.style.display = "none";
     453
     454        ee.editBox.innerHTML = "";
     455
     456        ee.savePrompt.style.display = "none";
     457
     458    }
     459
     460}
     461
     462function pas_cth_js_closeFile() {
     463
     464    var ee = new pas_cth_js_editElements();
     465
     466
     467
     468    ee.efSaveButton.disabled = true;
     469
     470    ee.savePrompt.style.display = "none";
     471
     472    pas_cth_js_closeEditFile();
     473
     474
     475
     476}
     477
     478function editBoxChange() {
     479
     480    if (document.getElementById("themeType").value.toLowerCase() == "child") {
     481
     482        document.getElementById("ef_saveButton").disabled = false;
     483
     484    }
     485
     486}
     487
     488function debug(element) {
     489
     490    var ee = new pas_cth_js_editElements();
     491
     492}
     493
     494function pas_cth_js_saveFile() {
     495
     496    var ee = new pas_cth_js_editElements();
     497
     498
     499
     500    var fileContents = "";
     501
     502    var dataBlock = {};
     503
     504
     505    fileContents = ee.editBox.innerText; // .replace(/&lt;/g, "<").replace(/&gt;/g, ">");
     506
     507
     508
     509    dataBlock.fileContents  = fileContents;
     510    dataBlock.file          = ee.filenameINP.value;
     511    dataBlock.directory     = ee.directoryINP.value;
     512    dataBlock.themeType     = ee.themeTypeINP.value;
     513
     514    ee.efSaveButton.disabled = true; // last possible chance to disable the button.
     515
     516
     517
     518    pas_cth_js_closeEditFile(); // Closing only clears the div and hides it. Not destroyed.
     519
     520
     521    var successCallback = function (response) {
     522        if (response.length) {
     523            pas_cth_js_processResponse(response);
     524            pas_cth_js_hideWait();
    323525        }
    324 
    325     }
    326 
    327 }
    328 
    329 function insertTextAtCursor(text) {
    330 
    331     var sel, range, html;
    332 
    333     var cursorPosition = saveSelection();
    334 
    335 
    336 
    337     if (window.getSelection) {
    338 
    339         sel = window.getSelection();
    340 
    341 
    342 
    343         if (sel.getRangeAt && sel.rangeCount) {
    344 
    345             range = sel.getRangeAt(0);
    346 
    347             range.deleteContents();
    348 
    349             restoreSelection(cursorPosition);
    350 
    351             range.insertNode( document.createTextNode(text) );
    352 
    353             range.collapse();
    354 
    355         }
    356 
    357     } else if (document.selection && document.selection.createRange) {
    358 
    359         document.selection.createRange().text = text;
    360 
    361         document.selection.collapse();
    362 
    363     }
    364 
    365 
    366 
    367 
    368 
    369 }
    370 
    371 function saveSelection() {
    372 
    373     if (window.getSelection) {
    374 
    375         sel = window.getSelection();
    376 
    377         if (sel.getRangeAt && sel.rangeCount) {
    378 
    379             return sel.getRangeAt(0);
    380 
    381         }
    382 
    383     } else if (document.selection && document.selection.createRange) {
    384 
    385         return document.selection.createRange();
    386 
    387     }
    388 
    389     return null;
    390 
    391 }
    392 
    393 
    394 
    395 function restoreSelection(range) {
    396 
    397     if (range) {
    398 
    399         if (window.getSelection) {
    400 
    401             sel = window.getSelection();
    402 
    403             sel.removeAllRanges();
    404 
    405             sel.addRange(range);
    406 
    407         } else if (document.selection && range.select) {
    408 
    409             range.select();
    410 
    411         }
    412 
    413     }
    414 
    415 }
    416 
    417 function processEditFile(response) {
    418 
    419     var ee = new pas_cth_js_editElements();
    420 
    421     var responseSections = parseOutput(response);
    422 
    423     responseSections.ARGS = JSON.parse(responseSections.ARGS);
    424 
    425 
    426 
    427     ee.directoryINP.value = responseSections.ARGS['directory'];
    428 
    429     ee.filenameINP.value = responseSections.ARGS['file'];
    430 
    431     ee.themeTypeINP.value = responseSections.ARGS['themeType'];
    432 
    433     ee.readOnlyFlag.value = responseSections.ARGS['readOnlyFlag'];
    434 
    435     ee.filenameDisplay.innerHTML = "FILE: " + responseSections.ARGS['directory'] + "/" + responseSections.ARGS['file'];
    436 
    437 
    438 
    439     ee.efSaveButton.disabled = true;
    440 
    441 
    442 
    443     ee.editBox.innerHTML = responseSections.EDITBOX
    444 
    445 
    446 
    447     enableContent(ee);
    448 
    449 
    450 
    451     if (ee.readOnlyFlag.value.toLowerCase() == "true") {
    452 
    453         ee.readOnlyMsg.style.display = "inline";
    454 
    455     } else {
    456 
    457         ee.readOnlyMsg.style.display = "none";
    458 
    459     }
    460 
    461 
    462 
    463     ee.editBox.onkeydown = function () { captureKeystrokes(this) }
    464 
    465 
    466 
    467     ee.shield.style.display = "inline";
    468 
    469     ee.editFile.style.display = "grid";
    470 
    471 
    472 
    473 }
    474 
    475 function enableContent(elements) {
    476 
    477     elements.editBox.contentEditable        = true;
    478 
    479 
    480 
    481     elements.efSaveButton.contentEditable   = false;
    482 
    483     elements.efCloseButton.contentEditable  = false;
    484 
    485 
    486 
    487     elements.savePrompt.contentEditable     = false;
    488 
    489     elements.spSaveButton.contentEditable   = false;
    490 
    491     elements.spCloseButton.contentEditable  = false;
    492 
    493 }
    494 
    495 
    496 
    497 function pas_cth_js_closeEditFile() {
    498 
    499     var ee = new pas_cth_js_editElements();
    500 
    501 
    502 
    503     if ( ! ee.efSaveButton.disabled) {
    504 
    505         ee.savePrompt.style.cssText = "display:inline;"
    506 
    507         ee.efSaveButton.disabled = true;
    508 
    509     } else {
    510 
    511 //      ee.themeGrid.style.display = "inline-grid";
    512 
    513         ee.editFile.style.display = "none";
    514 
    515         ee.shield.style.display = "none";
    516 
    517         ee.editBox.innerHTML = "";
    518 
    519         ee.savePrompt.style.display = "none";
    520 
    521     }
    522 
    523 }
    524 
    525 function pas_cth_js_closeFile() {
    526 
    527     var ee = new pas_cth_js_editElements();
    528 
    529 
    530 
    531     ee.efSaveButton.disabled = true;
    532 
    533     ee.savePrompt.style.display = "none";
    534 
    535     pas_cth_js_closeEditFile();
    536 
    537 
    538 
    539 }
    540 
    541 function editBoxChange() {
    542 
    543     if (document.getElementById("themeType").value.toLowerCase() == "child") {
    544 
    545         document.getElementById("ef_saveButton").disabled = false;
    546 
    547     }
    548 
    549 }
    550 
    551 function debug(element) {
    552 
    553     var ee = new pas_cth_js_editElements();
    554 
    555 }
    556 
    557 function pas_cth_js_saveFile() {
    558 
    559     var ee = new pas_cth_js_editElements();
    560 
    561 
    562 
    563     var xmlhttp = new XMLHttpRequest();
    564 
    565     var data = new FormData();
    566 
    567     var fileContents = "";
    568 
    569 
    570 
    571     xmlhttp.open("POST", ajaxurl, true);
    572 
    573 
    574 
    575     fileContents = ee.editBox.innerText; // .replace(/&lt;/g, "<").replace(/&gt;/g, ">");
    576 
    577 
    578 
    579     data.append("fileContents", fileContents);
    580 
    581     data.append("file",         ee.filenameINP.value);
    582 
    583     data.append("directory",    ee.directoryINP.value);
    584 
    585     data.append("themeType",    ee.themeTypeINP.value);
    586 
    587     data.append("action",       "saveFile");
    588 
    589 
    590 
    591     ee.efSaveButton.disabled = true; // last possible chance to disable the button.
    592 
    593 
    594 
    595     pas_cth_js_closeEditFile(); // Closing only clears the div and hides it. Not destroyed.
    596 
    597 
    598 
    599     xmlhttp.onreadystatechange = function () {
    600 
    601         if (4 == xmlhttp.readyState) {
    602 
    603             var response = (xmlhttp.responseText.length >= 1 ?
    604 
    605                                 xmlhttp.responseText.left(xmlhttp.responseText.length - 1) :
    606 
    607                                 xmlhttp.responseText);
    608 
    609 
    610 
    611             switch (xmlhttp.status) {
    612 
    613                 case 200: // Everything is okay
    614 
    615                     if (response.length <= 0) {
    616 
    617 
    618 
    619                     } else {
    620 
    621                         pas_cth_js_processResponse(response);
    622 
    623                     }
    624 
    625                     break;
    626 
    627 
    628 
    629                 case 400:
    630 
    631                 case 500:
    632 
    633                     msg = xmlhttp.status + " Error:<br>" + xmlhttp.statusText;
    634 
    635                     pas_cth_js_showBox().innerHTML = msg;
    636 
    637                     break;
    638 
    639             }
    640 
    641         }
    642 
    643     }
    644 
    645     xmlhttp.send(data);
    646 
     526    }
     527
     528    pas_cth_js_AJAXCall('saveFile', dataBlock, successCallback, pas_cth_js_failureCallback);
    647529}
    648530
  • child-themes-helper/trunk/js/js_common_fn.js

    r2057158 r2074973  
     1"use strict;"
    12if(typeof String.prototype.ltrim == "undefined")
    23
     
    2122
    2223
     24function pas_cth_DOMFunctions() {
     25    var self = this;
     26    this.killElement = function (element) {
     27        if (element == null || element == undefined) { return false; }
     28        var e;
     29        if (typeof element == "string") {
     30            e = document.getElementById(element);
     31        } else {
     32            e = element;
     33        }
     34
     35        if (e.parentNode != null) {
     36            e.parentNode.removeChild(e);
     37        }
     38        e.remove();
     39    }
     40    this.kill = function (element) {
     41        if (element == null || element == undefined) { return false; }
     42        this.killElement(element);
     43    }
     44    this.createBox = function (id, parent = null, bKillFirst = true) {
     45        if (parent == null) { parent = document.getElementsByTagName("body")[0]; }
     46        var box = document.getElementById(id);
     47        if (box != null && bKillFirst) {
     48            this.killElement(box);
     49            box = null;
     50        }
     51       
     52        box = document.createElement("DIV");
     53        box.id = id;
     54
     55        parent.appendChild(box);
     56        return box;
     57    }
     58    this.displayError = function (str) {
     59        var box = this.createBox("popupErrorMessage");
     60        box.onclick = function () {
     61            self.killElement(box);
     62        }
     63        box.innerHTML = str;
     64        return box;
     65    }
     66    this.getPosition = function (element = null) {
     67        if (element == null) { return null; }
     68        var rect = element.getBoundingClientRect();
     69
     70        return {left : rect.left, top: rect.top, width : Math.abs(rect.right - rect.left), height : Math.abs(rect.bottom - rect.top), 'element' : element };
     71    }
     72    this.getElementTree = function (element) {
     73        if (element == null) {
     74            return [];
     75        } else {
     76            return element.getElementsByTagName("*");
     77        }
     78    }
     79    this.searchTree = function (rootElement, tree, pointElement) {
     80        var found = false;
     81
     82        if (rootElement == pointElement) {
     83            return true;
     84        } else {
     85            for (ndx = 0; ndx < tree.length && ! found; ndx++) {
     86                found = (tree[ndx] == pointElement ? true : false);
     87            }
     88            return found;
     89        }
     90    }
     91}
     92
    2393var mousePosition = {x:0, y:0, element:null};
    2494
     95var pas_cth_library = new pas_cth_DOMFunctions();
    2596
    2697
     
    50121
    51122            if (key != "action") {
    52 
    53                 data.append(key, dataBlock[key]);
     123 data.append(key, dataBlock[key]);
     124 }
     125        });
     126
     127    }
     128
     129    xmlhttp.open("POST", ajaxurl, true);
     130
     131    xmlhttp.onreadystatechange = function () {
     132
     133        if (4 == xmlhttp.readyState) {
     134
     135            // The next line strips the admin_ajax.php 1 byte response from the beginning of the response.
     136
     137            // Usually, admin_ajax.php returns a zero. This strips that.
     138
     139            var response = (xmlhttp.responseText.length >= 1 ? xmlhttp.responseText.left(xmlhttp.responseText.length - 1) : "");
     140
     141            if (xmlhttp.status == 200) {
     142
     143                if (callback != null) {
     144
     145                    callback(response);
     146
     147                }
     148
     149            } else {
     150
     151                if (error_callback != null) {
     152
     153                    error_callback(xmlhttp.statusText, response);
     154
     155                } else {
     156
     157                    alert("AJAX Error:\n\n" + xmlhttp.statusText + "\n\n" + response);
     158
     159                }
    54160
    55161            }
    56162
    57         });
    58 
    59     }
    60 
    61     xmlhttp.open("POST", ajaxurl, true);
    62 
    63     xmlhttp.onreadystatechange = function () {
    64 
    65         if (4 == xmlhttp.readyState) {
    66 
    67             // The next line strips the admin_ajax.php 1 byte response from the beginning of the response.
    68 
    69             // Usually, admin_ajax.php returns a zero. This strips that.
    70 
    71             var response = (xmlhttp.responseText.length >= 1 ? xmlhttp.responseText.left(xmlhttp.responseText.length - 1) : "");
    72 
    73             if (xmlhttp.status == 200) {
    74 
    75                 if (callback != null) {
    76 
    77                     callback(response);
    78 
    79                 }
    80 
    81             } else {
    82 
    83                 if (error_callback != null) {
    84 
    85                     error_callback(xmlhttp.statusText, response);
    86 
    87                 } else {
    88 
    89                     alert("AJAX Error:\n\n" + xmlhttp.statusText + "\n\n" + response);
    90 
    91                 }
    92 
    93             }
    94 
    95163        }
    96164
     
    103171if (document.getElementById("childGrid") != null && document.getElementById("parentGrid") != null) {
    104172
    105     window.onresize = function (e) {
    106 
     173    window.addEventListener("resize", function (e) {
    107174        var childGrid = document.getElementById("childGrid")
    108175
     
    126193
    127194    }
    128 
    129 }
    130 
    131 function getElementTree(element) {
    132 
    133     if (element == null) {
    134 
    135         return [];
     195);
     196}
     197
     198var windowFlag = false;
     199
     200
     201
     202if (window.location.href.indexOf("manage_child_themes") >= 0) {
     203    window.addEventListener("click", function (e) {
     204
     205        if (windowFlag) {
     206
     207            windowFlag = false;
     208
     209            return;
     210
     211        }
     212
     213        if (e.clientX == undefined || e.clientY == undefined) {
     214
     215            return;
     216
     217        }
     218
     219
     220
     221        var pointElement    = null;
     222
     223        var actionBox       = document.getElementById("pas_cth_actionBox");
     224
     225        var errorMessageBox = document.getElementsByName("errorMessageBox")[0];
     226
     227
     228
     229        pointElement = document.elementFromPoint(e.clientX, e.clientY);
     230
     231
     232
     233        var tree = pas_cth_library.getElementTree(actionBox);
     234
     235        var found = false;
     236
     237        found = pas_cth_library.searchTree(actionBox, tree, pointElement);
     238
     239
     240
     241        if (! found) {
     242
     243            tree = pas_cth_library.getElementTree(errorMessageBox);
     244
     245            found = pas_cth_library.searchTree(errorMessageBox, tree, pointElement);
     246
     247        }
     248
     249
     250
     251        if (! found) {
     252
     253            pas_cth_library.kill(actionBox);
     254
     255            pas_cth_library.kill(errorMessageBox);
     256
     257        }
     258
     259    });
     260
     261}
     262
     263
     264
     265// KillMe kills the error message boxes.
     266
     267// After the last box has been destroyed, kill the actionBox div too.
     268
     269function pas_cth_js_killMe(element) {
     270
     271    var elements;
     272
     273    if (element.parentNode != null) {
     274
     275        element.parentNode.removeChild(element);
     276
     277    }
     278
     279    element.remove();
     280
     281
     282
     283    elements = document.getElementsByName("errorMessageBox");
     284
     285    if (0 == elements.length) {
     286
     287        var actionBox = document.getElementById("pas_cth_actionBox");
     288
     289        if (actionBox.parentNode != null) {
     290
     291            actionBox.parentNode.removeChild(actionBox);
     292
     293        }
     294
     295        actionBox.remove();
     296
     297    }
     298
     299}
     300
     301function pas_cth_js_popupMessage(abbr, msg) {
     302
     303    var box = document.getElementById("popupMessageBox")
     304
     305    box.innerHTML = msg;
     306
     307    box.style.position = "fixed";
     308
     309    box.style.left = mousePosition.x + 100 + "px";
     310
     311    box.style.top  = mousePosition.y - 40 + "px";
     312
     313    box.style.display = "inline";
     314
     315    setTimeout(function () {
     316
     317                var p = document.getElementById("popupMessageBox")
     318
     319                p.innerHTML = "";
     320
     321                p.style.display = "none";
     322
     323               }, 2000);
     324
     325}
     326
     327// Process the xmlhttp.responseText that was echo'd during the AJAX call
     328
     329function pas_cth_js_processResponse(response) {
     330
     331    if ("ABBREVIATION:{" == response.left("ABBREVIATION:{".length).toUpperCase()) {
     332
     333        abbr = response.right(response.length - "ABBREVIATION:{".length);
     334
     335        abbr = abbr.left(abbr.length - 1);
     336
     337        pas_cth_js_popupMessage(abbr, "color saved");
     338
     339        document.getElementById("popupMessageBox").style.display = "inline";
     340
     341    } else if ("EDITFILEOUTPUT:{" == response.left("EDITFILEOUTPUT:{".length).toUpperCase()) {
     342
     343        response = response.right(response.length - "EDITFILEOUTPUT:{".length);
     344
     345        response = response.left(response.length - 1);
     346
     347        processEditFile(response);
     348
     349    } else if ("DEBUG:{" == response.left("DEBUG:{".length).toUpperCase()) {
     350
     351        pas_cth_library.kill("pas_cth_actionBox");
     352
     353        debugResponse = response.right(response.length - "debug:{".length);
     354
     355        debugResponse = debugResponse.left(debugResponse.length - 1);
     356
     357       
     358        box = pas_cth_js_createBox('debugBox', 'debug');
     359
     360        box.innerHTML = debugResponse;
     361
     362    // Nothing special. We've got output from the PHP function, dump it to the screen.
    136363
    137364    } else {
    138365
    139         return element.getElementsByTagName("*");
    140 
    141     }
    142 
    143 }
    144 
    145 function kill(element) {
    146 
    147     if (element == null) {
    148 
    149         return false;
    150 
    151     }
    152 
    153     if (element.parentNode != null) {
    154 
    155         element.parentNode.removeChild(element);
    156 
    157     }
    158 
    159     element.remove();
    160 
    161     return true;
    162 
    163 }
    164 
    165 function searchTree(rootElement, tree, pointElement) {
    166 
    167     var found = false;
    168 
    169 
    170 
    171     if (rootElement == pointElement) {
    172 
    173         return true;
    174 
     366        if (response.length > 0) {
     367
     368            pas_cth_js_createBox("pas_cth_actionBox", "").innerHTML = response;
     369
     370            windowFlag = true;
     371
     372        }
     373
     374    }
     375
     376}
     377
     378function pas_cth_js_showBox() {
     379
     380    return pas_cth_library.createBox("pas_cth_actionBox");
     381}
     382
     383function pas_cth_js_createBox(id, className = "", parent = document.getElementsByTagName("body")[0], clickClose = false) {
     384
     385    var box = pas_cth_library.createBox(id, parent);
     386
     387    if (className.trim.length > 0) {
     388
     389        box.className = className;
     390
     391    }
     392
     393
     394
     395    if (clickClose) {
     396
     397        box.onclick= function () {
     398 pas_cth_library.kill(this); }
    175399    } else {
    176400
    177         for (ndx = 0; ndx < tree.length && ! found; ndx++) {
    178 
    179             found = (tree[ndx] == pointElement ? true : false);
    180 
    181         }
    182 
    183         return found;
    184 
    185     }
    186 
    187 }
    188 
    189 var windowFlag = false;
    190 
    191 
    192 
    193 if (window.location.href.indexOf("manage_child_themes") >= 0) {
    194 
    195     window.onclick = function (e) {
    196 
    197         if (windowFlag) {
    198 
    199             windowFlag = false;
    200 
    201             return;
    202 
    203         }
    204 
    205         if (e.clientX == undefined || e.clientY == undefined) {
    206 
    207             return;
    208 
    209         }
    210 
    211 
    212 
    213         var pointElement = null;
    214 
    215         var actionBox = document.getElementById("pas_cth_actionBox");
    216 
    217         var errorMessageBox = document.getElementsByName("errorMessageBox")[0];
    218 
    219 
    220 
    221         pointElement = document.elementFromPoint(e.clientX, e.clientY);
    222 
    223 
    224 
    225         var tree = getElementTree(actionBox);
    226 
    227         var found = false;
    228 
    229         found = searchTree(actionBox, tree, pointElement);
    230 
    231 
    232 
    233         if (! found) {
    234 
    235             tree = getElementTree(errorMessageBox);
    236 
    237             found = searchTree(errorMessageBox, tree, pointElement);
    238 
    239         }
    240 
    241 
    242 
    243         if (! found) {
    244 
    245             kill(actionBox);
    246 
    247             kill(errorMessageBox);
    248 
    249         }
    250 
    251     }
    252 
    253 }
    254 
    255 
    256 
    257 // KillMe kills the error message boxes.
    258 
    259 // After the last box has been destroyed, kill the actionBox div too.
    260 
    261 function pas_cth_js_killMe(element) {
    262 
    263     var elements;
    264 
    265     if (element.parentNode != null) {
    266 
    267         element.parentNode.removeChild(element);
    268 
    269     }
    270 
    271     element.remove();
    272 
    273 
    274 
    275     elements = document.getElementsByName("errorMessageBox");
    276 
    277     if (0 == elements.length) {
    278 
    279         var actionBox = document.getElementById("pas_cth_actionBox");
    280 
    281         if (actionBox.parentNode != null) {
    282 
    283             actionBox.parentNode.removeChild(actionBox);
    284 
    285         }
    286 
    287         actionBox.remove();
    288 
    289     }
    290 
    291 }
    292 
    293 function pas_cth_js_popupMessage(abbr, msg) {
    294 
    295     var box = document.getElementById("popupMessageBox")
    296 
    297     box.innerHTML = msg;
    298 
    299     box.style.position = "fixed";
    300 
    301     box.style.left = mousePosition.x + 100 + "px";
    302 
    303     box.style.top  = mousePosition.y - 40 + "px";
    304 
    305     box.style.display = "inline";
    306 
    307     setTimeout(function () {
    308 
    309                 var p = document.getElementById("popupMessageBox")
    310 
    311                 p.innerHTML = "";
    312 
    313                 p.style.display = "none";
    314 
    315                }, 2000);
    316 
    317 }
    318 
    319 // Process the xmlhttp.responseText that was echo'd during the AJAX call
    320 
    321 function pas_cth_js_processResponse(response) {
    322 
    323     if ("ABBREVIATION:{" == response.left("ABBREVIATION:{".length).toUpperCase()) {
    324 
    325         abbr = response.right(response.length - "ABBREVIATION:{".length);
    326 
    327         abbr = abbr.left(abbr.length - 1);
    328 
    329         pas_cth_js_popupMessage(abbr, "color saved");
    330 
    331         document.getElementById("popupMessageBox").style.display = "inline";
    332 
    333     } else if ("EDITFILEOUTPUT:{" == response.left("EDITFILEOUTPUT:{".length).toUpperCase()) {
    334 
    335         response = response.right(response.length - "EDITFILEOUTPUT:{".length);
    336 
    337         response = response.left(response.length - 1);
    338 
    339         processEditFile(response);
    340 
    341     } else if ("DEBUG:{" == response.left("DEBUG:{".length).toUpperCase()) {
    342 
    343         actionBox = document.getElementById("pas_cth_actionBox");
    344 
    345         if (actionBox != null && actionBox != undefined) {
    346 
    347             if (actionBox.parentNode != null) {
    348 
    349                 actionBox.parentNode.removeChild(actionBox);
    350 
    351             }
    352 
    353             actionBox.remove();
    354 
    355         }
    356 
    357         debugResponse = response.right(response.length - "debug:{".length);
    358 
    359         debugResponse = debugResponse.left(debugResponse.length - 1);
    360 
    361         box = pas_cth_js_createBox('debugBox', 'debug');
    362 
    363         box.innerHTML = debugResponse;
    364 
    365     // Nothing special. We've got output from the PHP function, dump it to the screen.
     401        var dismissBTN = document.createElement("p")
     402
     403        dismissBTN.setAttribute("id", "dismissBox");
     404
     405        box.appendChild(dismissBTN);
     406
     407        dismissBTN.innerHTML = "DISMISS";
     408
     409        dismissBTN.onclick = function () {
     410
     411            pas_cth_library.kill("pas_cth_actionBox");
     412        }
     413
     414    }
     415
     416    return box;
     417
     418}
     419
     420function pas_cth_js_addCloseButton(id, parent, text) {
     421
     422    var element = document.createElement("p");
     423
     424    element.setAttribute("id", id);
     425
     426
     427    parent.appendChild(element);
     428
     429    element.innerHTML = text;
     430
     431    element.onclick = function () {
     432
     433        var myParent = this.parentNode;
     434
     435        var myGrandParent = myParent.parentNode;
     436
     437
     438
     439        if (myGrandParent != null) {
     440
     441            myGrandParent.removeChild(myParent);
     442
     443            myParent.remove();
     444
     445        }
     446
     447    }
     448
     449}
     450
     451function getTopLeftPosition(obj = null) {
     452
     453    if (obj != null) {
     454
     455        return pas_cth_library.getPosition(obj);
    366456
    367457    } else {
    368458
    369         if (response.length > 0) {
    370 
    371             pas_cth_js_createBox("pas_cth_actionBox", "").innerHTML = response;
    372 
    373             windowFlag = true;
    374 
    375         }
    376 
    377     }
    378 
    379 }
    380 
    381 function pas_cth_js_showBox() {
    382 
    383     return pas_cth_js_createBox("pas_cth_actionBox", "");
    384 
    385 }
    386 
    387 function pas_cth_js_createBox(id, className = "", parent = document.getElementsByTagName("body")[0], clickClose = false) {
    388 
    389     var box = document.getElementById(id);
    390 
    391     if (box != null && box != undefined) {
    392 
    393         if (box.parentNode != null) {
    394 
    395             box.parentNode.removeChild(box);
    396 
    397         }
    398 
    399         box.remove();
    400 
    401     }
    402 
    403     box = document.createElement("div");
    404 
    405     box.setAttribute("id", id);
    406 
    407     if (className.trim.length > 0) {
    408 
    409         box.className = className;
    410 
    411     }
    412 
    413 
    414 
    415     parent.appendChild(box);
    416 
    417 
    418 
    419     if (clickClose) {
    420 
    421         box.onclick= function () {
    422 
    423             if (this.parentNode != null) {
    424 
    425                 this.parentNode.removeChild(this);
    426 
    427             }
    428 
    429             this.remove();
    430 
    431         }
    432 
    433     } else {
    434 
    435         var dismissBTN = document.createElement("p")
    436 
    437         dismissBTN.setAttribute("id", "dismissBox");
    438 
    439         box.appendChild(dismissBTN);
    440 
    441         dismissBTN.innerHTML = "DISMISS";
    442 
    443         dismissBTN.onclick = function () {
    444 
    445             var ab = document.getElementById("pas_cth_actionBox");
    446 
    447             if (ab.parentNode != null) {
    448 
    449                 ab.parentNode.removeChild(ab);
    450 
    451             }
    452 
    453             ab.remove();
    454 
    455         }
    456 
    457 
    458 
    459 
    460 
    461 /*
    462 
    463         box.oncontextmenu = function () {
    464 
    465             box.style.width = "100%";
    466 
    467             box.style.height = "100%";
    468 
    469             box.style.position = "absolute";
    470 
    471             box.style.left = "180px";
    472 
    473             box.style.top  = "40px";
    474 
    475             box.style.zIndex = 9999999;
    476 
    477             box.style.overflow = "scroll";
    478 
    479             box.style.marginTop = "0px";
    480 
    481             box.style.marginLeft = "0px";
    482 
    483             return false;
    484 
    485         }
    486 
    487 */
    488 
    489     }
    490 
    491     return box;
    492 
    493 }
    494 
    495 /*
    496 
    497 function findPos(obj) {
    498 
    499     var curleft = curtop = 0;
    500 
    501     if (obj.offsetParent) {
    502 
    503         do {
    504 
    505             curleft += obj.offsetLeft;
    506 
    507             curtop += obj.offsetTop;
    508 
    509         } while (obj = obj.offsetParent);
    510 
    511     }
    512 
    513     return {left:curleft ,top:curtop};
    514 
    515 }
    516 
    517 */
    518 
    519 function getPosition(element) {
    520 
    521     var rect = element.getBoundingClientRect();
    522 
    523 
    524 
    525     return {left : rect.left, top: rect.top, width : Math.abs(rect.right - rect.left), height : Math.abs(rect.bottom - rect.top) };
    526 
    527 }
    528 
    529 function pas_cth_js_addCloseButton(id, parent, text) {
    530 
    531     var element = document.createElement("p");
    532 
    533     element.setAttribute("id", id);
    534 
    535 //  element.setAttribute("contentEditable", false);
    536 
    537     parent.appendChild(element);
    538 
    539     element.innerHTML = text;
    540 
    541     element.onclick = function () {
    542 
    543         var myParent = this.parentNode;
    544 
    545         var myGrandParent = myParent.parentNode;
    546 
    547 
    548 
    549         if (myGrandParent != null) {
    550 
    551             myGrandParent.removeChild(myParent);
    552 
    553             myParent.remove();
    554 
    555         }
    556 
    557     }
    558 
    559 }
    560 
    561 function getTopLeftPosition(obj = null) {
    562 
    563     if (obj != null) {
    564 
    565         return getPosition(obj);
    566 
    567     } else {
    568 
    569459        return null;
    570460
     
    572462
    573463}
    574 
    575 function displayError(str) {
    576 
    577     var box = document.getElementById("popupErrorMessage");
    578 
    579     var theBody = document.getElementsByTagName("body")[0];
    580 
    581     if (box != null) {
    582 
    583         if (box.parentNode != null) { box.parentNode.removeChild(box); }
    584 
    585         box.remove();
    586 
    587     }
    588 
    589     box = pas_cth_js_createBox("popupErrorMessage", "", theBody, true);
    590 
    591     box.appendChild(document.createTextNode(str));
    592 
    593     return box;
    594 
    595 }
  • child-themes-helper/trunk/js/menu.js

    r2057158 r2074973  
    155155    var jsdata = JSON.parse(element.getAttribute("data-jsdata"));
    156156
    157     var elementID = Date.now();
     157    var elementID = Date.now(); // clock ticks since midnight at the epoch. Guarantees a unique ID number.
    158158
    159159    var childGrid = document.getElementById("childGrid");
  • child-themes-helper/trunk/js/pasChildThemes.js

    r2057158 r2074973  
     1"use strict;"
    12/* pasChildThemes.js
    23
    34 * This file contains nearly pure JavaScript code.
    45
    5  * With the exception of XMLHttpRequest() and JSON, no other WordPress core, nor 3rd party JavaScript
    6 
    7  * libraries are used, herein.
    8 
    96 */
    107
     
    1714 */
    1815
     16if (typeof(String.prototype.trim) == "undefined") {
     17    String.prototype.trim = function () {
     18        return this.ltrim().rtrim();
     19    }
     20}
    1921function pas_cth_js_selectFile(event) {
    2022
    2123    var element = document.getElementById(event.srcElement.dataset.elementid);
    2224
    23     var xmlhttp = new XMLHttpRequest();
    24 
    25     var data = new FormData();
    26 
    2725    var jsInput;
    2826
     
    107105}
    108106
     107function pas_cth_js_showWait() {
     108    var body = document.getElementsByTagName("body")[0];
     109    body.style.cursor = "wait";
     110}
     111function pas_cth_js_hideWait() {
     112    var body = document.getElementsByTagName("body")[0];
     113    body.style.cursor = "";
     114}
     115var pas_cth_js_spinTimer = 0;
     116var pas_cth_js_spinPosition = 0;
     117
     118function pas_cth_js_spin() {
     119}
     120
    109121
    110122
     
    121133function pas_cth_js_removeChildFile(element) {
    122134
    123     var xmlhttp = new XMLHttpRequest();
    124 
    125     var data = new FormData();
    126 
    127135    var jsInput = JSON.parse(element.getAttribute("data-jsdata"));
    128136
    129 
    130 
    131 /* AJAX call to pas_cth_AJAXFunctions::verifyRemoveFile()
    132 
    133  * in 'classes/class_ajax_functions.php'
     137    var dataBlock = {};
     138
     139    pas_cth_js_showWait();
     140
     141
     142    // $_POST[] values in pas_cth_AJAXFunctions::verifyRemoveFile()
     143    dataBlock.directory = jsInput['directory'];
     144    dataBlock.file      = jsInput['file'];
     145
     146    var successCallback = function (response) {
     147        if (response.length) {
     148            pas_cth_js_processResponse(response);
     149            pas_cth_js_hideWait();
     150        } else {
     151            location.reload();
     152        }
     153    }
     154    var failureCallback = function (status, response) {
     155        var msg = "400 Error:<br>" + status;
     156        pas_cth_js_showBox().innerHTML = msg;
     157        pas_cth_js_hideWait();
     158    }
     159
     160    pas_cth_js_AJAXCall(jsInput['action'], dataBlock, successCallback, failureCallback);
     161}
     162
     163/* pas_cth_js_deleteChildFile() is called from an onclick event in a popup error box
     164
     165 * set up in pas_cth_AJAXFunctions::verifyRemoveFile() in 'classes/class_ajax_functions.php'
     166
     167 *
    134168
    135169 */
    136170
    137     xmlhttp.open("POST", ajaxurl, true);
    138 
    139 
    140 
    141     data.append("action", jsInput['action']); // verifyRemoveFile
    142 
    143 
    144 
    145     // $_POST[] values in pas_cth_AJAXFunctions::verifyRemoveFile()
    146 
    147     data.append("directory",    jsInput['directory'] );
    148 
    149     data.append("file",         jsInput['file']);
    150 
    151 
    152 
    153 
    154 
    155     xmlhttp.onreadystatechange = function () {
    156 
    157         if (4 == xmlhttp.readyState) {
    158 
    159             var response = (xmlhttp.responseText.length >= 1 ?
    160 
    161                                 xmlhttp.responseText.left(xmlhttp.responseText.length - 1) :
    162 
    163                                 xmlhttp.responseText);
    164 
    165 
    166 
    167             switch (xmlhttp.status) {
    168 
    169                 case 200: // Everything is okay
    170 
    171                     if (response.length <= 0) {
    172 
    173                         location.reload();
    174 
    175                     } else {
    176 
    177                         pas_cth_js_processResponse(response);
    178 
    179                     }
    180 
    181                     break;
    182 
    183 
    184 
    185                 case 400:
    186 
    187                     msg = "400 Error:<br>" + xmlhttp.statusText;
    188 
    189                     pas_cth_js_showBox().innerHTML = msg;
    190 
    191                     break;
    192 
     171function pas_cth_js_deleteChildFile(element) {
     172
     173    var jsInput = JSON.parse(element.getAttribute("data-jsdata"));
     174
     175    var dataBlock = {};
     176
     177    pas_cth_js_showWait();
     178
     179
     180    // $_POST[] values in pas_cth_AJAXFunctions::deleteFile()
     181
     182    dataBlock.directory = jsInput['directory'];
     183    dataBlock.file      = jsInput['file'];
     184
     185    var successCallback = function (response) {
     186        if (response.length) {
     187            pas_cth_js_processResponse(response);
     188            pas_cth_js_hideWait();
     189        } else {
     190            location.reload();
     191        }
     192    }
     193    var failureCallback = function(status, response) {
     194        var msg = "400 Error:<br>" + status;
     195        pas_cth_js_showBox().innerHTML = msg;
     196        pas_cth_js_hideWait();
     197    }
     198
     199    pas_cth_js_AJAXCall
     200(jsInput['action'], dataBlock, successCallback, failureCallback);
     201}
     202
     203function pas_cth_js_successCallback(response) {
     204    if (response.length) {
     205        pas_cth_js_processResponse(response);
     206        pas_cth_js_hideWait();
     207    } else {
     208        location.reload();
     209    }
     210}
     211function pas_cth_js_failureCallback(status, response) {
     212    var msg = "400 Error:<br>" + status;
     213    pas_cth_js_showBox().innerHTML = msg;
     214    pas_cth_js_hideWait();
     215}
     216/*
     217
     218 * pas_cth_js_copyTemplateFile() responds to an onclick event set up pas_cth_AJAXFunctions::selectFile()
     219
     220 * in 'classes/class_ajax_functions.php' when a user clicks a file in the template theme files list.
     221
     222 */
     223
     224function pas_cth_js_copyTemplateFile(element) {
     225
     226    var jsInput = JSON.parse(element.getAttribute("data-jsdata"));
     227
     228    var dataBlock = {};
     229
     230
     231    // $_POST[] values in pas_cth_AJAXFunctions::verifyCopyFile()
     232
     233    dataBlock.directory = jsInput['directory'];
     234    dataBlock.file      = jsInput['file'];
     235
     236    pas_cth_js_showWait();
     237
     238    var successCallback = function (response) {
     239        if (response.length) {
     240            pas_cth_js_processResponse(response);
     241            pas_cth_js_hideWait();
     242        } else {
     243            location.reload();
     244        }
     245    }
     246    var failureCallback = function (status, response) {
     247        var msg = "400 Error:<br>" + status + "<HR>" + response;
     248        pas_cth_js_showBox().innerHTML = msg;
     249        pas_cth_js_hideWait();
     250    }
     251
     252    pas_cth_js_AJAXCall(jsInput['action'], dataBlock, successCallback, failureCallback);
     253}
     254
     255function pas_cth_js_overwriteFile(element) {
     256
     257    var jsInput = JSON.parse(element.getAttribute("data-jsdata"));
     258
     259    var dataBlock = {};
     260
     261    pas_cth_js_showWait();
     262
     263
     264    dataBlock.directory = jsInput['directory'];
     265    dataBlock.file      = jsInput['file'];
     266
     267    // copyFile
     268    pas_cth_js_AJAXCall(jsInput['action'], dataBlock, pas_cth_js_successCallback, pas_cth_js_failureCallback);
     269}
     270
     271function pas_cth_js_resetChildThemeForm(frm) {
     272    var formElements = frm.elements, ndx;
     273    for (ndx = 0; ndx < formElements.length; ndx++) {
     274        formElements[ndx].style.backgroundColor = "";
     275    }
     276    frm.reset();
     277}
     278/* The pas_cth_js_createChildTheme() function processes the form in
     279
     280 * pas_cth_ChildThemesHelper::manage_child_themes() in file 'classes/class_childThemesHelper.php'
     281
     282 * without actually executing a "Submit" on that form. This prevents the page refresh and allows
     283
     284 * us to redirect to the admin_url("themes.php") page once the child theme has been created.
     285
     286 */
     287
     288function pas_cth_js_createChildTheme(element) {
     289    var ndx = 0,
     290
     291        frm = element.form,
     292        formElements = frm.elements,
     293        dataBlock = {},
     294        jsInput,
     295        action,
     296        e, err = 0;
     297
     298    pas_cth_js_showWait();
     299
     300    // Used to validate the data in the form before making the AJAX call to save the data and create the child theme.
     301    this.test = function (elementValue = "", elementPattern = "", elementRequiredFlag = false) {
     302        var re;
     303        var result = false;
     304
     305        if (elementRequiredFlag) {
     306            if (elementValue.length) {
     307                if (elementPattern.length) { // element is required, value is not blank, pattern exists, return true if value matches pattern.
     308                    re = new RegExp(elementPattern);
     309                    result = re.test(elementValue);
     310                } else { // element is required, value is not blank, no pattern specified, so any value will do, return true
     311                    result = true;
     312                }
     313            } else  { // element is required, value is blank, return false;
     314                result = false;
    193315            }
    194 
    195         }
    196 
    197     }
    198 
    199     xmlhttp.send(data)
    200 
    201 }
    202 
    203 /* pas_cth_js_deleteChildFile() is called from an onclick event in a popup error box
    204 
    205  * set up in pas_cth_AJAXFunctions::verifyRemoveFile() in 'classes/class_ajax_functions.php'
    206 
    207  *
    208 
    209  */
    210 
    211 function pas_cth_js_deleteChildFile(element) {
    212 
    213     var xmlhttp = new XMLHttpRequest();
    214 
    215     var data = new FormData();
    216 
    217     var jsInput = JSON.parse(element.getAttribute("data-jsdata"));
    218 
    219 
    220 
    221     // AJAX call to pas_cth_AJAXFunctions::deleteFile() in 'classes/class_ajax_functions.php'
    222 
    223     xmlhttp.open("POST", ajaxurl, true);
    224 
    225     data.append("action",       jsInput['action']);
    226 
    227 
    228 
    229     // $_POST[] values in pas_cth_AJAXFunctions::deleteFile()
    230 
    231     data.append("directory",    jsInput['directory'] );
    232 
    233     data.append("file",         jsInput['file']);
    234 
    235 
    236 
    237 
    238 
    239     xmlhttp.onreadystatechange = function () {
    240 
    241         if (4 == xmlhttp.readyState) {
    242 
    243             var response = (xmlhttp.responseText.length >= 1 ?
    244 
    245                                 xmlhttp.responseText.left(xmlhttp.responseText.length - 1) :
    246 
    247                                 xmlhttp.responseText);
    248 
    249 
    250 
    251             switch (xmlhttp.status) {
    252 
    253                 case 200: // Everything is okay
    254 
    255                     if (response.length <= 0) {
    256 
    257                         location.reload();
    258 
    259                     } else {
    260 
    261                         pas_cth_js_processResponse(response);
    262 
    263                     }
    264 
    265                     break;
    266 
    267 
    268 
    269                 case 400:
    270 
    271                     msg = "400 Error:<br>" + xmlhttp.statusText;
    272 
    273                     pas_cth_js_showBox().innerHTML = msg;
    274 
    275                     break;
    276 
     316        } else {
     317            if (elementPattern.length) {
     318                if (elementValue.length) { // element is NOT required, value is not blank, pattern exists, return true if value matches pattern
     319                    re = new RegExp(elementPattern);
     320                    result = re.test(elementValue);
     321                } else { // element is NOT required. value is blank. return true;
     322                    result = true;
     323                }
     324            } else { // element is NOT required, pattern is blank, return true
     325                result = true;
    277326            }
    278 
    279         }
    280 
    281     }
    282 
    283     xmlhttp.send(data);
    284 
    285 }
    286 
    287 /*
    288 
    289  * pas_cth_js_copyTemplateFile() responds to an onclick event set up pas_cth_AJAXFunctions::selectFile()
    290 
    291  * in 'classes/class_ajax_functions.php' when a user clicks a file in the template theme files list.
    292 
    293  */
    294 
    295 function pas_cth_js_copyTemplateFile(element) {
    296 
    297     var xmlhttp = new XMLHttpRequest();
    298 
    299     var data = new FormData();
    300 
    301     var jsInput = JSON.parse(element.getAttribute("data-jsdata"));
    302 
    303 
    304 
    305     // AJAX call to pas_cth_AJAXFunctions::verifyCopyFile() in 'classes/class_ajax_functions.php'
    306 
    307     xmlhttp.open("POST", ajaxurl, true);
    308 
    309     data.append("action",               jsInput['action']);
    310 
    311 
    312 
    313     // $_POST[] values in pas_cth_AJAXFunctions::verifyCopyFile()
    314 
    315     data.append("directory",    jsInput['directory'] );
    316 
    317     data.append("file",         jsInput['file']);
    318 
    319 
    320 
    321     xmlhttp.onreadystatechange = function () {
    322 
    323         if (4 == xmlhttp.readyState) {
    324 
    325             var response = (1 <= xmlhttp.responseText.length ?
    326 
    327                                 xmlhttp.responseText.left(xmlhttp.responseText.length - 1) :
    328 
    329                                 xmlhttp.responseText);
    330 
    331 
    332 
    333             switch (xmlhttp.status) {
    334 
    335                 case 200: // Everything is okay
    336 
    337                     if (response.length <= 0) {
    338 
    339                         location.reload();
    340 
    341                     } else {
    342 
    343                         pas_cth_js_processResponse(response);
    344 
    345                     }
    346 
    347                     break;
    348 
    349 
    350 
    351                 case 400:
    352 
    353                     msg = "400 Error:<br>" + xmlhttp.statusText + "<HR>" + response;
    354 
    355                     pas_cth_js_showBox().innerHTML = msg;
    356 
    357                     break;
    358 
    359             }
    360 
    361         }
    362 
    363     }
    364 
    365     xmlhttp.send(data);
    366 
    367 }
    368 
    369 function pas_cth_js_overwriteFile(element) {
    370 
    371     var xmlhttp = new XMLHttpRequest();
    372 
    373     var data = new FormData();
    374 
    375     var jsInput = JSON.parse(element.getAttribute("data-jsdata"));
    376 
    377 
    378 
    379     // AJAX call to pas_cth_AJAXFunctions::copyFile() in 'classes/class_ajax_functions.php'
    380 
    381     xmlhttp.open("POST", ajaxurl, true);
    382 
    383     data.append("action",       jsInput["action"]); // copyFile
    384 
    385 
    386 
    387     // $_POST[] values in pas_cth_AJAXFunctions::copyFile()
    388 
    389     data.append("directory",    jsInput["directory"]);
    390 
    391     data.append("file",         jsInput["file"]);
    392 
    393 
    394 
    395     xmlhttp.onreadystatechange = function () {
    396 
    397         if (4 == xmlhttp.readyState) {
    398 
    399             var response = (xmlhttp.responseText.length >= 1 ?
    400 
    401                                 xmlhttp.responseText.left(xmlhttp.responseText.length - 1) :
    402 
    403                                 xmlhttp.responseText);
    404 
    405 
    406 
    407             switch (xmlhttp.status) {
    408 
    409                 case 200: // Everything is okay
    410 
    411                     if (response.length <= 0) {
    412 
    413                         location.reload();
    414 
    415                     } else {
    416 
    417                         pas_cth_js_processResponse(response);
    418 
    419                     }
    420 
    421                     break;
    422 
    423 
    424 
    425                 case 400: // There was an error
    426 
    427                     msg = "400 Error:<br>" + xmlhttp.statusText;
    428 
    429                     pas_cth_js_showBox().innerHTML = msg;
    430 
    431                     break;
    432 
    433             }
    434 
    435         }
    436 
    437     }
    438 
    439 
    440 
    441     xmlhttp.send(data);
    442 
    443 }
    444 
    445 /* The pas_cth_js_createChildTheme() function processes the form in
    446 
    447  * pas_cth_ChildThemesHelper::manage_child_themes() in file 'classes/class_childThemesHelper.php'
    448 
    449  * without actually executing a "Submit" on that form. This prevents the page refresh and allows
    450 
    451  * us to redirect to the admin_url("themes.php") page once the child theme has been created.
    452 
    453  */
    454 
    455 function pas_cth_js_createChildTheme(element) {
    456 
    457     var frm = element.form;
    458 
    459     var formElements = frm.elements;
    460 
    461     var xmlhttp = new XMLHttpRequest();
    462 
    463     var data = new FormData();
    464 
    465     var jsInput;
     327        }
     328        return result;
     329    }
     330
     331    var outputMessage = "";
     332
     333    for (ndx = 0; ndx < formElements.length; ndx++) {
     334        e = formElements[ndx];
     335        if (! this.test(e.value, e.dataset.pattern, e.required) ) {
     336            e.style.backgroundColor = "#FFFF90";
     337            outputMessage += (outputMessage.length ? "<hr>" + e.dataset.message : e.dataset.message);
     338            err++;
     339        }
     340    }
     341    if (err) {
     342        var errorBox = pas_cth_library.displayError(outputMessage);
     343        errorBox.style.width = "300px";
     344        errorBox.style.height = "300px";
     345        errorBox.style.overflowY = "scroll";
     346        errorBox.style.marginLeft = "-150px";
     347        errorBox.style.marginTop = "-150px";
     348
     349        pas_cth_js_hideWait();
     350
     351        return;
     352    }
     353
    466354
    467355
     
    482370
    483371            case "INPUT":
    484 
    485                 data.append(formElements[ndx].name,
    486 
    487                             formElements[ndx].value);
    488 
     372                if (formElements[ndx].name.toLowerCase() == "action") {
     373                    action = formElements[ndx].value;
     374                } else {
     375                    dataBlock[formElements[ndx].name] = formElements[ndx].value;
     376                }
    489377                break;
    490 
    491378            case "TEXTAREA":
    492 
    493                 data.append(formElements[ndx].name,
    494 
    495                             formElements[ndx].value);
    496 
     379                dataBlock[formElements[ndx].name] = formElements[ndx].value;
    497380                break;
    498 
    499381            case "SELECT":
    500 
    501                 data.append(formElements[ndx].name,
    502 
    503                             formElements[ndx].options[formElements[ndx].selectedIndex].value);
    504 
     382                dataBlock[formElements[ndx].name] = formElements[ndx].options[formElements[ndx].selectedIndex].value;
    505383                break;
    506 
    507384            case "BUTTON":
    508 
    509385                // ignore
    510 
    511386                break;
    512 
    513         }
    514 
    515     }
    516 
     387        }
     388
     389    }
     390    var successCallback = function (response) {
     391        if ("SUCCESS:" == response.left("SUCCESS:".length)) {
     392            location.href='/wp-admin/themes.php';
     393        } else if (response.length >= 1) {
     394            pas_cth_js_processResponse(response);
     395            pas_cth_js_hideWait();
     396        }
     397    }
    517398    // AJAX call to pas_cth_AJAXFunctions::createChildTheme() in 'classes/class_ajax_functions.php'
    518 
    519     xmlhttp.open("POST", ajaxurl, true);
    520 
    521 
    522 
    523     xmlhttp.onreadystatechange = function () {
    524 
    525         if (4 == xmlhttp.readyState) {
    526 
    527             // strip the AJAX zero from wp_die() WORDPRESS ONLY
    528 
    529             var response = (xmlhttp.responseText.length >= 1 ?
    530 
    531                                 xmlhttp.responseText.left(xmlhttp.responseText.length - 1) :
    532 
    533                                 xmlhttp.responseText);
    534 
    535 
    536 
    537             switch (xmlhttp.status) {
    538 
    539                 case 200: // Everything is Okay
    540 
    541                     /* If responseText is not empty, there might be a request to overwrite
    542 
    543                      * or a request to delete that needs to be displayed.
    544 
    545                      * else, reload the page.
    546 
    547                      * <= 1 accounts for the AJAX return of zero that sometimes shows up
    548 
    549                      * despite my best efforts to avoid that.
    550 
    551                      */
    552 
    553                     if ("SUCCESS:" == response.left("SUCCESS:".length)) {
    554 
    555                         location.href="/wp-admin/themes.php";
    556 
    557                     } else if (response.length >= 1) {
    558 
    559                         pas_cth_js_processResponse(response);
    560 
    561                     }
    562 
    563                     break;
    564 
    565 
    566 
    567                 case 400: // There was an error
    568 
    569                     msg = "400 Error:<br>" + xmlhttp.statusText + "<br>" + response;
    570 
    571                     pas_cth_js_showBox().innerHTML = msg;
    572 
    573                     break;
    574 
    575             }
    576 
    577         }
    578 
    579     }
    580 
    581     xmlhttp.send(data);
     399    pas_cth_js_AJAXCall(action, dataBlock, successCallback, pas_cth_js_failureCallback);
    582400
    583401}
     
    600418
    601419    }
     420    pas_cth_js_hideWait();
    602421
    603422}
     
    620439
    621440    }
     441    pas_cth_js_hideWait();
    622442
    623443}
     
    629449function pas_cth_js_SetOption(element) {
    630450
    631     var xmlhttp = new XMLHttpRequest();
    632 
    633     var data = new FormData();
    634 
    635 
    636 
    637     data.append('action', 'saveOptions');
    638 
    639     data.append('optionName', element.name);
    640 
    641     data.append('optionValue', element.value);
    642 
    643 
    644 
    645     xmlhttp.open("POST", ajaxurl, true);
    646 
    647     xmlhttp.onreadystatechange = function () {
    648 
    649         if (4 == xmlhttp.readyState) {
    650 
    651             // strip the AJAX zero from wp_die() WORDPRESS ONLY
    652 
    653             var response = (xmlhttp.responseText.length >= 1 ?
    654 
    655                                 xmlhttp.responseText.left(xmlhttp.responseText.length - 1) :
    656 
    657                                 xmlhttp.responseText);
    658 
    659 
    660 
    661             switch (xmlhttp.status) {
    662 
    663                 case 200: // Everything is Okay
    664 
    665                     /* If responseText is not empty, there might be a request to overwrite
    666 
    667                      * or a request to delete that needs to be displayed.
    668 
    669                      * else, reload the page.
    670 
    671                      * <= 1 accounts for the AJAX return of zero that sometimes shows up
    672 
    673                      * despite my best efforts to avoid that.
    674 
    675                      */
    676 
    677                     if ("SUCCESS:" == response.left("SUCCESS:".length)) {
    678 
    679                         location.href="/wp-admin/themes.php"
    680 
    681                     } else if (response.length >= 1) {
    682 
    683                         pas_cth_js_showBox().innerHTML = response;
    684 
    685                     }
    686 
    687                     break;
    688 
    689 
    690 
    691                 case 400: // There was an error
    692 
    693                     msg = "400 Error:<br>" + xmlhttp.statusText + "<br>" + response;
    694 
    695                     pas_cth_js_showBox().innerHTML = msg;
    696 
    697                     break;
    698 
    699             }
    700 
    701         }
    702 
    703     }
    704 
    705     xmlhttp.send(data);
    706 
    707 }
    708 
    709 function pas_cth_js_mouseOver(element) {
    710 
    711     var jsdata = JSON.parse(element.getAttribute("data-jsdata"));
    712 
    713     var themeType = jsdata['themeType'];
    714 
    715     var filename = jsdata['file'];
    716 
    717     var msg;
    718 
    719     var mID = document.getElementById("hoverPrompt");
    720 
    721 
    722 
    723 
    724 
    725     switch (themeType.toLowerCase()) {
    726 
    727         case "child":
    728 
    729             msg = "File: <font class='fileHighlight'>" + filename + "</font><br>" +
    730 
    731                   "<div id='innerLine'>" +
    732 
    733                   "  <font class='actionPrompt'>Left Click</font> to <font class='redHighlight'>Remove</font> from the Child Theme.<br>" +
    734 
    735                   "  <br>" +
    736 
    737                   "  <font class='actionPrompt'>Right Click</font> to <font class='redHighlight'>Edit</font> the file." +
    738 
    739                   "</div>";
     451    var dataBlock = {};
     452
     453
     454    dataBlock.optionName    = element.name;
     455    dataBlock.optionValue   = element.value;
     456
     457    var successCallback = function (response) {
     458        alert("Here");
     459        if ("SUCCESS:" == response.left("SUCCESS:".length)) {
     460            location.href = "/wp-admin/themes.php";
     461        } else if (response.length >= 1) {
     462            pas_cth_js_showBox().innerHTML = response;
     463        }
     464        pas_cth_js_hideWait();
     465    }
     466
     467    pas_cth_js_AJAXCall('saveOptions', dataBlock, successCallback, pas_cth_js_failureCallback);
     468}
     469
     470function showChild() {
     471
     472    document.getElementById("childGrid").style.display = "inline";
     473
     474    document.getElementById("parentGrid").style.display = "none";
     475
     476}
     477
     478function showParent() {
     479
     480    document.getElementById("childGrid").style.display = "none";
     481
     482    document.getElementById("parentGrid").style.display = "inline";
     483
     484}
     485
     486function debugTip(action, msg) {
     487
     488    switch (action.toLowerCase()) {
     489
     490        case "show":
     491
     492            var tipBox = document.createElement("div")
     493
     494            tipBox.setAttribute("id", "tipBox")
     495
     496            tipBox.setAttribute("class", "tipBox");
     497
     498            tipBox.innerHTML = msg;
     499
     500
     501
     502            tipBox.style.left = (mousePosition.x + 10) + "px";
     503
     504            tipBox.style.top  = (mousePosition.y + 10) + "px";
     505
     506            document.getElementsByTagName("body")[0].appendChild(tipBox);
    740507
    741508            break;
    742509
    743         case "parent":
    744 
    745             msg = "File: <font class='fileHighlight'>" + filename + "</font><br>" +
    746 
    747                   "<div id='innerLine'>" +
    748 
    749                   "  <font class='actionPrompt'>Left Click</font> to <font class='redHighlight'>Copy</font> to the Child Theme.<br>" +
    750 
    751                   "  <br>" +
    752 
    753                   "  <font class='actionPrompt'>Right Click</font> to <font class='redHighlight'>Edit</font> the file." +
    754 
    755                   "</div>";
     510        case "hide":
     511
     512            kill(document.getElementById("tipBox"));
    756513
    757514            break;
     
    759516    }
    760517
    761     mID.innerHTML = msg;
    762 
    763     mID.style.cssText = "visibility:visible;";
    764 
    765     mID.style.left = mousePosition["x"] + 25 + "px";
    766 
    767     mID.style.top = mousePosition["y"] + "px";
    768 
    769 }
    770 
    771 function pas_cth_js_mouseOut(element) {
    772 
    773     var mID = document.getElementById("hoverPrompt");
    774 
    775     mID.style.visibility = "hidden";
    776 
    777     mID.innerHTML = "";
    778 
    779 }
    780 
    781 function showChild() {
    782 
    783     document.getElementById("childGrid").style.display = "inline";
    784 
    785     document.getElementById("parentGrid").style.display = "none";
    786 
    787 }
    788 
    789 function showParent() {
    790 
    791     document.getElementById("childGrid").style.display = "none";
    792 
    793     document.getElementById("parentGrid").style.display = "inline";
    794 
    795 }
    796 
    797 function debugTip(action, msg) {
    798 
    799     switch (action.toLowerCase()) {
    800 
    801         case "show":
    802 
    803             var tipBox = document.createElement("div")
    804 
    805             tipBox.setAttribute("id", "tipBox")
    806 
    807             tipBox.setAttribute("class", "tipBox");
    808 
    809             tipBox.innerHTML = msg;
    810 
    811 
    812 
    813             tipBox.style.left = (mousePosition.x + 10) + "px";
    814 
    815             tipBox.style.top  = (mousePosition.y + 10) + "px";
    816 
    817             document.getElementsByTagName("body")[0].appendChild(tipBox);
    818 
    819             break;
    820 
    821         case "hide":
    822 
    823             kill(document.getElementById("tipBox"));
    824 
    825             break;
    826 
    827     }
    828 
    829 }
    830 
    831 function pas_cth_validateField(element) {
    832 
    833     if (element.value.trim().length == 0) {
    834 
     518}
     519
     520function pas_cth_validateField(element = null) {
     521
     522    if (element == null) {
    835523        return;
    836 
    837     }
    838 
    839     if (element.pattern.trim().length == 0) {
     524    }
     525    var strValue    = element.value.trim();
     526    var ptrn        = element.dataset.pattern.trim();
     527    if (strValue.length == 0 || ptrn.length == 0) {
    840528
    841529        return;
     
    843531    }
    844532
    845     var re = new RegExp(element.pattern);
     533    var re = new RegExp(ptrn);
    846534
    847535    var box;
     
    857545
    858546
    859     if (! re.test(element.value)) {
     547    if (! re.test(strValue)) {
    860548
    861549        box = pas_cth_js_createBox(boxID, className, parent, onclickFunction);
    862550
    863         box.innerHTML = element.getAttribute("data-message") + "<br><br>Click on this messagebox to close it";
     551        box.innerHTML = element.dataset.message + "<br><br>Click on this messagebox to close it";
    864552
    865553    }
  • child-themes-helper/trunk/js/tabs.js

    r2057158 r2074973  
    9696        }
    9797    }
     98    document.getElementsByTagName("body")[0].style.cursor = "wait";
    9899    pas_cth_js_AJAXCall("setDefaultChildTheme", dataBlock, reloadFN);
    99100}
  • child-themes-helper/trunk/readme.txt

    r2073439 r2074973  
    66Requires at least: 4.7.0
    77Tested up to: 5.1.1
    8 Stable tag: 2.1.1
     8Stable tag: 2.2
    99Requires PHP: 5.6.31
    1010License: GPLv2 or later
     
    1515== Description ==
    16161. **The Child Themes Helper is a tool....**
    17     ...developed for those child theme developers who write or modify PHP code in the development of their child themes. Previous versions of the Child Themes Helper required the child theme being modified be the activated theme. That is no longer the case. However, you will still need to set a child theme to be an "Active Theme" on the Options tab, but it does not have to be the activated theme.
     17    ...developed for those child theme developers who **write or modify PHP code in the development of their child themes**. Previous versions of the Child Themes Helper required the child theme being modified be the activated theme. That is no longer the case. However, you will still need to set a child theme to be an "Active Theme" on the Options tab, but it does not have to be the activated theme.
    1818
    19191. **Copy files from Parent Theme to Child Theme**
     
    3737
    38381. **Notes**
    39     - *PHP Versions*
    40         The Child Themes Helper plugin has been tested and found to work with PHP 5.6.31, PHP 7.2.7, and PHP 7.3.0.
    41 
    4239    - *Troubleshooting Installation Issues*
    43         The primary filename and primary folder name of the Child Themes Helper changed (in v2.1) from pasChildThemes and pasChildThemes.php to child-themes-helper and child-themes-helper.php. This *may* cause some problems during the installation. If you experience problems, I suggest that you deactivate the plugin and delete it. Then reinstall the Child Themes Helper v2.1 from the WordPress Plugins repository.
    44 
    45     - *What would you like to see in this plugin?*
     40        If you are upgrading the Child Themes Helper from a version prior to version 2.0, you might have problems installing the upgrade.
     41        The most frequent problem is that the upgrade fails and displays a nasty message at the top of the plugins page. WordPress then politely deactivates the Child Themes Helper plugin.
     42        If you experience this problem, the solution is to: **deactivate the plugin** if it isn't already deactivated. **Delete the plugin**. And then **reinstall the Child Themes Helper** directly from the WordPress plugins repository.
     43       
     44        New with Child Themes Helper v2.0, the primary folder name ("~/plugins/pasChildThemes) and the primary file name (pasChildThemes.php) were changed to (~/plugins/child-themes-helper) and (child-themes-helper.php) to make the plugin match the WordPress assigned slug.
     45        Under certain circumstances, probably due to either browser caching or website caching, this causes the upgrade to fail.
     46
     47    - *PHP Developer Tool*
     48        The Child Themes Helper is meant as a PHP developer's tool to help the WordPress PHP developer make direct changes to a child theme's PHP code. It is **NOT** a GUI, drag -n- drop tool to help non-developers build a child theme.
     49   
     50    - *Child Themes Helper on GitHub*
     51        The GitHub repository for this plugin can be found [here](https://github.com/PaulSwarthout/pasChildThemes). Stable versions are usually found on the WordPress SVN repository. Intermediate versions are often found on GitHub.
     52
     53    - *Child Themes Helper access*
     54        The Child Themes Helper is accessed from the WordPress dashboard under the heading "Child Themes Helper". The menu item may be found immediately below the *Appearance* Dashboard menu item.
     55
     56    - *Platform Support*
     57        The Child Themes Helper was developed on Microsoft IIS 10 and tested on both Windows' and Linux -based web servers.
     58
     59    - *If you like the Child Themes Helper plugin, please consider writing a review [here](https://wordpress.org/support/plugin/child-themes-helper/reviews/#new-post). Thank you.*
     60
     61    - *Development versions*
     62        Versions 2\.1, 1\.2 are available for download and install.
    4663
    4764    - *Screenshot*
     
    5673        In a future release, there will be a lock feature on the options page to prevent accidental overwrites of the screenshot file. Also, in a future release, there will be the ability to select an existing graphic and crop it as necessary, instead of generating one.
    5774
    58     - *Child Themes Helper access*
    59         The Child Themes Helper is accessed from the WordPress dashboard under the heading "Child Themes Helper". The menu item may be found immediately below the *Appearance* Dashboard menu item.
    60 
    61     - *Platform Support*
    62         The Child Themes Helper plugin has been tested with both WordPress running on a Windows server and with WordPress running on a Linux server. Development is done on a Windows platform. If you find any compatibility issues with Linux, please let me know.
    63    
    64     - *Child Themes Helper on GitHub*
    65         The GitHub repository for this plugin can be found [here](https://github.com/PaulSwarthout/pasChildThemes). Stable versions are usually found on the WordPress SVN repository. Intermediate versions are often found on GitHub.
    66 
    67     - *Development versions*
    68         Versions 1\.2, 1\.1\.3 and 1\.0 are available for download and install.
    69 
    7075    - *Known Bug*
    7176        Although the Child Themes Helper plugin is mostly responsive, the Edit File functionality doesn't work very well on small screens. But does anybody actually modify themes on smartphones and tablets? (Please say 'No').
     
    7681- This plugin may be installed through the usual method of installing and activating WordPress plugins. The first time you open the Child Themes Helper plugin page on your dashboard, it will look a bit different from the previous version. Instead of a stack of menu options on the dashboard menu, there is a single menu option "Child Themes Helper" and it opens to a page featuring tabs across the top -- one for each area of functionality. Previous versions worked on the currently active Child Theme, but effective with this release, you are free to modify any child theme that has been created. You will still need to specify the "active" theme, but it does not have to be the "activated" theme. The first time you use it, you will only be able to set an active theme on the Options tab, or create a new child theme.
    7782
    78 - If you experience problems installing or activating version 2.1, after having an earlier version installed, please deactivate it, delete it, and then reinstall it. The primary folder name and the primary plugin filename changed with this release. It may conflict with an earlier version and crash upon install.
     83- If you experience problems installing or activating version 2.1 or later, after having an earlier version installed, please deactivate it, delete it, and then reinstall it. The primary folder name and the primary plugin filename changed with this release. It may conflict with an earlier version and crash upon install.
    7984
    8085- The Child Themes Helper plugin requires an active theme be specified (Options tab). Unlike previous versions, this "active theme" does NOT have to be the currently "Activated" theme.
     
    8994== Frequently Asked Questions ==
    9095
     96= Do I have to keep the Child Themes Helper installed and/or activated? =
     97
     98No. You should at least deactivate all plugins and themes that you are not using. That will decrease your website's load times. The Child Themes Helper leaves nothing behind that is required for you to be able to use your child themes or temporary graphics files. Feel free to uninstall it and/or deactivate it once you've completed your child theme.
     99
    91100= What is next? =
    92101
     
    100109= Where I can see the Child Themes Helper in action? =
    101110
    102 I am glad you asked. Starting with version 1.2 (version 2.1 is not yet installed on that page), you can visit [my demo page](http://www.1acsi.com) and take it for a test drive. Create your own child theme. Copy files to the newly created child theme. Generate screenshots. Change the Screenshot options. In short, put it through its paces. And don't worry about screwing up the website. It's there for that purpose.
     111I am glad you asked. Starting with version 1.2 (version 2.2 is not yet installed on that page), you can visit [my demo page](http://www.1acsi.com) and take it for a test drive. Create your own child theme. Copy files to the newly created child theme. Generate screenshots. Change the Screenshot options. In short, put it through its paces. And don't worry about screwing up the website. It's there for that purpose.
    103112
    104113= I generated a screenshot but it didn't change. Why not? =
     
    106115You did nothing wrong. Your browser will cache the screenshot file to help your website to load more quickly. The solution is to clear your browser's image cache. [Here's a good article](https://kb.iu.edu/d/ahic) that I found that gives great directions on how to accomplish that.
    107116
    108 = What does the "Generate ScreenShot" option do? =
    109 
    110 The WordPress Themes page displays a graphic for each theme. A newly created child theme does not have a graphic. The Generate ScreenShot menu option creates a temporary graphic. Generally, developers will use a copy of a header image for their screenshot. But rather than leaving it blank until later, the Child Themes Helper plugin will create a temporary graphic which displays the child theme name, the parent theme name, a message indicating that the child theme was created using the Child Themes Helper and the Child Themes Helper's developer's web address. It is expected that the developer will want to replace this temporary graphic with their own custom graphic at a later time. Please check out [my demo page](http://www.1acsi.com) where you are welcome to take the Child Themes Helper plugin for a test drive.
    111 
    112117= Why create a screenshot? I'm just going to delete it later anyway. =
    113118
     
    116121== Screenshots ==
    117122
    118 1. The files for the Child Theme are displayed in the left-hand pane. The name, 'MyChildTheme' for example
    119 is the name of your Child Theme. The page scrolls.
    120 2. The files for the Template / Parent Theme's, or the Child Theme's parent theme, are displayed in the right-hand pane.
    121 For this example, the Child Theme was created as a child of the 'Twenty Sixteen' theme and it's name appears at the top. The page scrolls.
     1231. When you first install the Child Themes Helper, and attempt to open the dashboard page, Child Themes Helper, you will see a long description, which you can hide by click the "Expert Mode" checkbox at the top. Below the description will be a list of your installed themes.
     1242. If you don't already have a Child Theme, you can click the Create Child Theme tab at the top and create one.
     1253. Once you have created a child theme, the first dialog will list the installed themes plus your new child theme. Click the large radio button to select your child theme. Note: this does NOT activate your child theme.
     1264. If your screen is wide enough, you will see the child theme files listed on the left and the parent theme files listed on the right. If you are using a mobile device or a tablet that is not wide enough, then you will only see the child theme files list or the parent theme files list, and a button where you can switch back and forth.
     1275. Right click on a file in either the child theme files or the parent theme files to open a popup menu. On the child theme files list, you will see the ability to remove a file from the child theme or edit the file. On the parent theme files list, you will see the ability to copy the file to the child theme or view the contents of the file.
     1286. Choosing Edit Child Theme file will let you open the file in a simple editor.
     1297. After copying the footer.php file from the parent theme to the child theme, we have opened it in the simple editor.
     1308. The Screenshot tab lets you create a temporary graphic that will display on the Dashboard >> Appearance >> Themes page for your child theme. Most developers will replace this image during their child theme development, but it makes a nice placeholder in the meantime.
     1319. You can change the font, the text color, and the background color of your temporary graphic. You can add fonts to the plugin's ~/assets/fonts folder and they will be automatically available. Click the Generate Screenshot button and a window will open with a copy of your new temporary graphic. Go to the website's themes page to see it as it was intended to be used.
    122132
    123133== Changelog ==
     134
     135= 2.2 =
     136 - Added "wait" cursors in the places where there is a delay in processing ... i.e., it's not immediate. It's lightning fast in the test environment, but not as fast when it has to move large quantities of data through the Internet.
     137 
     138 - Modified the AJAX calls to be consistent.
     139
     140 - I discovered that some of my vanilla Javascript function names conflicted with function names in other plugins. I created a vanilla Javascript library which contains those functions. From a structural perspective, think "CLASS", but Javascript doesn't support classes.
    124141
    125142= 2.1.1 =
Note: See TracChangeset for help on using the changeset viewer.