Fossil

Check-in [c6ee75a9]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:More initialization and diff options for skin editing.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256:c6ee75a912be27491cdc47bd71258960a6f4156e618faaf783e58f5bda92914b
User & Date: drh 2017-12-04 16:13:52
Context
2017-12-04
16:23
Add a side-by-side diff option to the skin editor. check-in: 523c548b user: drh tags: trunk
16:13
More initialization and diff options for skin editing. check-in: c6ee75a9 user: drh tags: trunk
13:55
Fix the auto-backup mechanism that runs when publishing a new skin. check-in: 205a748e user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/skins.c.

617
618
619
620
621
622
623



























































624
625
626
627
628
629
630
...
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652

653
654
655
656
657
658
659
...
670
671
672
673
674
675
676


677
678

679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695






696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
...
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
...
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
  }
  db_finalize(&q);

  @ </table>
  style_footer();
  db_end_transaction(0);
}




























































/*
** WEBPAGE: setup_skinedit
**
** Edit aspects of a skin determined by the w= query parameter.
** Requires Setup privileges.
**
................................................................................
    const char *zSubmenu;
  } aSkinAttr[] = {
    /* 0 */ { "css",     "CSS",             "CSS",     },
    /* 1 */ { "footer",  "Page Footer",     "Footer",  },
    /* 2 */ { "header",  "Page Header",     "Header",  },
    /* 3 */ { "details", "Display Details", "Details", },
  };
  const char *zBasis;
  const char *zContent;
  char *zDflt;
  char *zKey;
  char *zTitle;
  int iSkin;
  int ii;
  int j;


  login_check_credentials();

  /* Figure out which skin we are editing */
  iSkin = atoi(PD("sk","1"));
  if( iSkin<1 || iSkin>9 ) iSkin = 1;

................................................................................
      glob_free(pAllowedEditors);
    }
  }

  /* figure out which file is to be edited */
  ii = atoi(PD("w","0"));
  if( ii<0 || ii>count(aSkinAttr) ) ii = 0;


  zKey = mprintf("draft%d-%s", iSkin, aSkinAttr[ii].zFile);
  zTitle = mprintf("%s for Draft%d", aSkinAttr[ii].zTitle, iSkin);


  zBasis = PD("basis","default");
  zDflt = mprintf("skins/%s/%s.txt", zBasis, aSkinAttr[ii].zFile);
  db_begin_transaction();
  style_header("%s", zTitle);
  for(j=0; j<count(aSkinAttr); j++){
    if( j==ii ) continue;
    style_submenu_element(aSkinAttr[j].zSubmenu,
          "%R/setup_skinedit?w=%d&basis=%h&sk=%d",j,zBasis,iSkin);
  }
  @ <form action="%s(g.zTop)/setup_skinedit" method="post"><div>
  login_insert_csrf_secret();
  @ <input type='hidden' name='w' value='%d(ii)'>
  @ <input type='hidden' name='sk' value='%d(iSkin)'>
  @ <h2>Edit %s(zTitle):</h2>
  zContent = textarea_attribute("", 10, 80, zKey,
                        aSkinAttr[ii].zFile, builtin_text(zDflt), 0);






  @ <br />
  @ <input type="submit" name="submit" value="Apply Changes" />
  @ <hr />
  @ Baseline: <select size='1' name='basis'>
  for(j=0; j<count(aBuiltinSkin); j++){
    cgi_printf("<option value='%h'%s>%h</option>\n",
       aBuiltinSkin[j].zLabel,
       fossil_strcmp(zBasis,aBuiltinSkin[j].zLabel)==0 ? " selected" : "",
       aBuiltinSkin[j].zDesc
    );
  }
  @ </select>
  @ <input type="submit" name="diff" value="Diff" />
  if( P("diff")!=0 ){
    u64 diffFlags = construct_diff_flags(0,0) |
                        DIFF_STRIP_EOLCR;
    Blob from, to, out;
    blob_init(&to, zContent, -1);
    blob_init(&from, builtin_text(zDflt), -1);
    blob_zero(&out);
    if( diffFlags & DIFF_SIDEBYSIDE ){
      text_diff(&from, &to, &out, 0, diffFlags | DIFF_HTML | DIFF_NOTTOOBIG);
      @ %s(blob_str(&out))
    }else{
      text_diff(&from, &to, &out, 0,
             diffFlags | DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG);
................................................................................
/*
** Try to initialize draft skin iSkin to the built-in or preexisting
** skin named by zTemplate.
*/
static void skin_initialize_draft(int iSkin, const char *zTemplate){
  int i;
  if( zTemplate==0 ) return;
  if( strcmp(zTemplate, "current")==0 ){
    for(i=0; i<count(azSkinFile); i++){
      db_set_mprintf("draft%d-%s", db_get(azSkinFile[i],""), 0,
                     iSkin, azSkinFile[i]);
    }
    return;
  }
  for(i=0; i<count(aBuiltinSkin); i++){
    if( strcmp(zTemplate, aBuiltinSkin[i].zLabel)==0 ){
      for(i=0; i<count(azSkinFile); i++){
        char *zKey = mprintf("skins/%s/%s.txt", zTemplate, azSkinFile[i]);
        db_set_mprintf("draft%d-%s", builtin_text(zKey), 0,
                       iSkin, azSkinFile[i]);
      }
      return;
    }
  }
}

/*
** Publish the draft skin iSkin as the new default.
*/
static void skin_publish(int iSkin){
................................................................................
    @ <p>Initialize the draft%d(iSkin) skin to one of the built-in skins
    @ or a preexisting skin, to use as a baseline.</p>
    @
    @ <form method='POST' action='%R/setup_skin#step4' id='f03'>
    @ <p class='skinInput'>
    @ <input type='hidden' name='sk' value='%d(iSkin)'>
    @ Initialize skin <b>draft%d(iSkin)</b> using
    @ <select size='1' name='initskin'>
    @ <option value='current'>Currently In Use</option>
    for(i=0; i<count(aBuiltinSkin); i++){
      @ <option value='%s(aBuiltinSkin[i].zLabel)'>\
      @ %h(aBuiltinSkin[i].zDesc) (built-in)</option>
    }
    @ </select>
    @ <input type='submit' name='init3' value='Go'>
    @ </p>
    @ </form>
  }
  @
  @ <a name='step4'></a>
  @ <h1>Step 4: Make Edits</h1>







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|
|
|
|
|
|
|
|
>







 







>
>
|

>

<
<












|
|
>
>
>
>
>
>



|
|
<
<
<
<
<
<
<






|







 







<
|
<
|
<
<
<
<
<
<
<
<
|
<
<
<







 







|
<
<
<
<
<
<







617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
...
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
...
730
731
732
733
734
735
736
737
738
739
740
741
742


743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767







768
769
770
771
772
773
774
775
776
777
778
779
780
781
...
795
796
797
798
799
800
801

802

803








804



805
806
807
808
809
810
811
...
965
966
967
968
969
970
971
972






973
974
975
976
977
978
979
  }
  db_finalize(&q);

  @ </table>
  style_footer();
  db_end_transaction(0);
}

/*
** Generate HTML for a <select> that lists all the available skin names,
** except for zExcept if zExcept!=NULL.
*/
static void skin_emit_skin_selector(
  const char *zVarName,      /* Variable name for the <select> */
  const char *zDefault,      /* The default value, if not NULL */
  const char *zExcept        /* Omit this skin if not NULL */
){
  int i;
  @ <select size='1' name='%s(zVarName)'>
  if( fossil_strcmp(zExcept, "current")!=0 ){
    @ <option value='current'>Currently In Use</option>
  }
  for(i=0; i<count(aBuiltinSkin); i++){
    const char *zName = aBuiltinSkin[i].zLabel;
    if( fossil_strcmp(zName, zExcept)==0 ) continue;
    if( fossil_strcmp(zDefault, zName)==0 ){
      @ <option value='%s(zName)' selected>\
      @ %h(aBuiltinSkin[i].zDesc) (built-in)</option>
    }else{
      @ <option value='%s(zName)'>\
      @ %h(aBuiltinSkin[i].zDesc) (built-in)</option>
    }
  }
  for(i=1; i<=9; i++){
    char zName[20];
    sqlite3_snprintf(sizeof(zName), zName, "draft%d", i);
    if( fossil_strcmp(zName, zExcept)==0 ) continue;
    if( fossil_strcmp(zDefault, zName)==0 ){
      @ <option value='%s(zName)' selected>%s(zName)</option>
    }else{
      @ <option value='%s(zName)'>%s(zName)</option>
    }
  }
  @ </select>
}

/*
** Return the text of one of the skin files.
*/
static const char *skin_file_content(const char *zLabel, const char *zFile){
  const char *zResult;
  if( fossil_strcmp(zLabel, "current")==0 ){
    zResult = db_get(zFile, "");
  }else if( sqlite3_strglob("draft[1-9]", zLabel)==0 ){
    zResult = db_get_mprintf("%s-%s", "", zLabel, zFile);
  }else{
    while( 1 ){
      char *zKey = mprintf("skins/%s/%s.txt", zLabel, zFile);
      zResult = builtin_text(zKey);
      fossil_free(zKey);
      if( zResult!=0 || fossil_strcmp(zLabel,"default")==0 ) break;
    }
  }
  return zResult;
}


/*
** WEBPAGE: setup_skinedit
**
** Edit aspects of a skin determined by the w= query parameter.
** Requires Setup privileges.
**
................................................................................
    const char *zSubmenu;
  } aSkinAttr[] = {
    /* 0 */ { "css",     "CSS",             "CSS",     },
    /* 1 */ { "footer",  "Page Footer",     "Footer",  },
    /* 2 */ { "header",  "Page Header",     "Header",  },
    /* 3 */ { "details", "Display Details", "Details", },
  };
  const char *zBasis;         /* The baseline file */
  const char *zContent;       /* Content after editing */
  char *zDraft;               /* Which draft:  "draft%d" */
  char *zKey;                 /* CONFIG table key name: "draft%d-%s" */
  char *zTitle;               /* Title of this page */
  const char *zFile;          /* One of "css", "footer", "header", "details" */
  int iSkin;                  /* draft number.  1..9 */
  int ii;                     /* Index in aSkinAttr[] of this file */
  int j;                      /* Loop counter */

  login_check_credentials();

  /* Figure out which skin we are editing */
  iSkin = atoi(PD("sk","1"));
  if( iSkin<1 || iSkin>9 ) iSkin = 1;

................................................................................
      glob_free(pAllowedEditors);
    }
  }

  /* figure out which file is to be edited */
  ii = atoi(PD("w","0"));
  if( ii<0 || ii>count(aSkinAttr) ) ii = 0;
  zFile = aSkinAttr[ii].zFile;
  zDraft = mprintf("draft%d", iSkin);
  zKey = mprintf("draft%d-%s", iSkin, zFile);
  zTitle = mprintf("%s for Draft%d", aSkinAttr[ii].zTitle, iSkin);
  zBasis = PD("basis","current");



  db_begin_transaction();
  style_header("%s", zTitle);
  for(j=0; j<count(aSkinAttr); j++){
    if( j==ii ) continue;
    style_submenu_element(aSkinAttr[j].zSubmenu,
          "%R/setup_skinedit?w=%d&basis=%h&sk=%d",j,zBasis,iSkin);
  }
  @ <form action="%s(g.zTop)/setup_skinedit" method="post"><div>
  login_insert_csrf_secret();
  @ <input type='hidden' name='w' value='%d(ii)'>
  @ <input type='hidden' name='sk' value='%d(iSkin)'>
  @ <h2>Edit %s(zTitle):</h2>
  zContent = textarea_attribute(
        "",                      /* Text label */
        10, 80,                  /* Height and width of the edit area */
        zKey,                    /* Name of CONFIG table entry */
        zFile,                              /* CGI query parameter name */
        skin_file_content(zBasis, zFile),   /* Default value of the text */
        0                                   /* Disabled flag */
  );
  @ <br />
  @ <input type="submit" name="submit" value="Apply Changes" />
  @ <hr />
  @ Baseline: \
  skin_emit_skin_selector("basis", zBasis, zDraft);







  @ <input type="submit" name="diff" value="Diff" />
  if( P("diff")!=0 ){
    u64 diffFlags = construct_diff_flags(0,0) |
                        DIFF_STRIP_EOLCR;
    Blob from, to, out;
    blob_init(&to, zContent, -1);
    blob_init(&from, skin_file_content(zBasis, zFile), -1);
    blob_zero(&out);
    if( diffFlags & DIFF_SIDEBYSIDE ){
      text_diff(&from, &to, &out, 0, diffFlags | DIFF_HTML | DIFF_NOTTOOBIG);
      @ %s(blob_str(&out))
    }else{
      text_diff(&from, &to, &out, 0,
             diffFlags | DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG);
................................................................................
/*
** Try to initialize draft skin iSkin to the built-in or preexisting
** skin named by zTemplate.
*/
static void skin_initialize_draft(int iSkin, const char *zTemplate){
  int i;
  if( zTemplate==0 ) return;

  for(i=0; i<count(azSkinFile); i++){

    const char *z = skin_file_content(zTemplate, azSkinFile[i]);








    db_set_mprintf("draft%d-%s", z, 0, iSkin, azSkinFile[i]);



  }
}

/*
** Publish the draft skin iSkin as the new default.
*/
static void skin_publish(int iSkin){
................................................................................
    @ <p>Initialize the draft%d(iSkin) skin to one of the built-in skins
    @ or a preexisting skin, to use as a baseline.</p>
    @
    @ <form method='POST' action='%R/setup_skin#step4' id='f03'>
    @ <p class='skinInput'>
    @ <input type='hidden' name='sk' value='%d(iSkin)'>
    @ Initialize skin <b>draft%d(iSkin)</b> using
    skin_emit_skin_selector("initskin", "current", 0);






    @ <input type='submit' name='init3' value='Go'>
    @ </p>
    @ </form>
  }
  @
  @ <a name='step4'></a>
  @ <h1>Step 4: Make Edits</h1>