Răsfoiți Sursa

Merge pull request #113 from weseek/imprv/impl-useful-buttons

Imprv/impl useful buttons
Yuki Takei 8 ani în urmă
părinte
comite
d20fde5a24

+ 9 - 0
resource/css/_page.scss

@@ -108,6 +108,15 @@
         color: #999;
         font-size: 1rem;
       }
+
+      // hide .btn
+      .btn {
+        visibility: hidden;
+      }
+      // show .btn when hover
+      &:hover .btn {
+        visibility: unset;
+      }
     }
 
     .content-main {

+ 2 - 1
resource/css/_page_crowi-plus.scss

@@ -25,9 +25,10 @@
         margin-bottom: 10px;
       }
     }
+
   }
 
-  // hide authors from affix
+  // hide authors in affix
   .main #page-header.affix {
     .authors {
       display: none !important;

+ 8 - 4
resource/css/_wiki.scss

@@ -40,15 +40,19 @@ div.body {
 
 .revision-head {
 
-  .revision-head-link {
-    display: none;
+  .revision-head-link,
+  .revision-head-edit-button {
+    visibility: hidden;
     font-size: 0.6em;
     padding-top: 4px;
     padding-left: 10px;
   }
-  &:hover .revision-head-link {
-    display: inline-block;
+  &:hover .revision-head-link,
+  &:hover .revision-head-edit-button {
+    visibility: unset;
   }
+
+
 }
 
 .wiki {

+ 10 - 1
resource/js/components/Page/RevisionPath.js

@@ -65,7 +65,7 @@ export default class RevisionPath extends React.Component {
   }
 
   render() {
-    // define style
+    // define styles
     const rootStyle = {
       marginRight: "0.2em",
     }
@@ -73,6 +73,12 @@ export default class RevisionPath extends React.Component {
       marginLeft: "0.2em",
       marginRight: "0.2em",
     }
+    const editButtonStyle = {
+      fontSize: "0.6em",
+      marginLeft: "0.5em",
+      padding: "0 2px",
+      border: 'none',
+    };
 
     const pageLength = this.state.pages.length;
 
@@ -102,6 +108,9 @@ export default class RevisionPath extends React.Component {
         {afterElements}
         <CopyButton buttonId="btnCopyRevisionPath" text={this.props.pagePath}
             buttonClassName="btn btn-default" iconClassName="fa fa-clone text-muted" />
+        <a href="#edit-form" className="btn btn-default" style={editButtonStyle}>
+          <i className="fa fa-edit text-muted"></i>
+        </a>
       </span>
     );
   }

+ 39 - 0
resource/js/legacy/crowi-form.js

@@ -56,6 +56,45 @@
     $('.content-main').removeClass('on-edit');
   });
 
+  // detect mutations for #edit-form
+  const targetSelector = '#edit-form';
+  var mo = new MutationObserver(function(mutations){
+    // initialize caret position when '#edit-form' activated
+    if (mutations[0].target.classList.contains('active')) {
+      initCaretPosition();
+    }
+  });
+  mo.observe(
+    document.querySelector(targetSelector),
+    {
+      attributes: true,
+      attributeFilter: ['class'],
+    }
+  );
+
+  /**
+   * scroll the textarea named '#form-body' according to the attribute 'data-caret-position'
+   *  that is set in Crowi.setScrollPositionToFormBody
+   */
+  function initCaretPosition() {
+    const textarea = document.querySelector('#form-body');
+    const position = textarea.getAttribute('data-caret-position');
+
+    if (position !== null) {
+      // focus
+      textarea.blur();
+      textarea.focus();
+      // scroll to the bottom for a moment
+      textarea.scrollTop = textarea.scrollHeight;
+      // set caret to the target position
+      textarea.selectionStart = position;
+      textarea.selectionEnd = position;
+
+      // remove attribute
+      textarea.removeAttribute('data-caret-position');
+    }
+  }
+
 /**
  * DOM ready
  */

+ 40 - 0
resource/js/legacy/crowi.js

@@ -30,6 +30,45 @@ Crowi.correctHeaders = function(contentId) {
   });
 };
 
+/**
+ * append buttons to section headers
+ */
+Crowi.appendEditSectionButtons = function(contentId, markdown) {
+  const $content = $(contentId || '#revision-body-content');
+  $('h1,h2,h3,h4,h5,h6', $content).each(function(idx, elm) {
+    // get header text string
+    const text = $(this).text();
+
+    // search pos for '# ...'
+    // https://regex101.com/r/y5rpO5/1
+    const regexp = new RegExp(`[^\r\n]*#+[^\r\n]*${text}[^\r\n]*`);
+    let position = markdown.search(regexp);
+    if (position < 0) { // if not found, search text only
+      position = markdown.search(text);
+    }
+
+    // add button
+    $(this).append(`
+      <span class="revision-head-edit-button">
+        <a href="#edit-form" onClick="Crowi.setCaretPositionToFormBody(${position})">
+          <i class="fa fa-edit"></i>
+        </a>
+      </span>
+      `
+    );
+  });
+};
+
+/**
+ * set 'data-caret-position' attribute that will be processed in crowi-form.js
+ * @param {number} position
+ */
+Crowi.setCaretPositionToFormBody = function(position) {
+  const formBody = document.querySelector('#form-body');
+  formBody.setAttribute('data-caret-position', position);
+}
+
+
 Crowi.revisionToc = function(contentId, tocId) {
   var $content = $(contentId || '#revision-body-content');
   var $tocId = $(tocId || '#revision-toc');
@@ -460,6 +499,7 @@ $(function() {
           });
 
           Crowi.correctHeaders('#revision-body-content');
+          Crowi.appendEditSectionButtons('#revision-body-content', markdown);
           Crowi.revisionToc('#revision-body-content', '#revision-toc');
 
           Promise.resolve($('#revision-body-content'));