Yuki Takei 6 лет назад
Родитель
Сommit
a8fe8d9da9

+ 12 - 5
packages/growi-plugin-attachment-refs/README.md

@@ -117,12 +117,19 @@ $refsimg(/somewhere/page, regexp=/^.*\.png$/, max-width=200)
 - *`max-height`* : max-height
 - *`max-height`* : max-height
   - e.g. `max-height=100px`
   - e.g. `max-height=100px`
 - *`display`* : `display` property for image (use `display: block` when undefined)
 - *`display`* : `display` property for image (use `display: block` when undefined)
+  - This option is disabled when `grid` option is set.
 - *`grid`* : Grid layout settings
 - *`grid`* : Grid layout settings
-  - `col-6` : Grid layout with `col-6` by Bootstrap
-  - `col-4` : Grid layout with `col-4` by Bootstrap
-  - `col-3` : Grid layout with `col-3` by Bootstrap
-  - `col-2` : Grid layout with `col-2` by Bootstrap
-  - `col-1` : Grid layout with `col-1` by Bootstrap
+  - `autofill` : Grid layout with auto filling with 100px tracks
+  - `autofill-2x` : Grid layout with auto filling with 200px tracks
+  - `autofill-3x` : Grid layout with auto filling with 300px tracks
+  - `autofill-4x` : Grid layout with auto filling with 400px tracks
+  - `col-2` : Grid layout with 2 columns
+  - `col-3` : Grid layout with 3 columns
+  - `col-4` : Grid layout with 4 columns
+  - `col-5` : Grid layout with 5 columns
+  - `col-6` : Grid layout with 6 columns
+- *`grid-gap`* : Grid gap
+  - e.g. `grid-gap=1px`
 
 
 TODO
 TODO
 -----
 -----

+ 35 - 45
packages/growi-plugin-attachment-refs/src/client/js/components/ExtractedAttachments.jsx

@@ -13,23 +13,6 @@ const AttachmentLink = Attachment;
  */
  */
 export default class ExtractedAttachments extends React.PureComponent {
 export default class ExtractedAttachments extends React.PureComponent {
 
 
-  /**
-   * Splits an array into an array of smaller arrays containing `chunkSize` members
-   * @see https://gist.github.com/webinista/11240585#gistcomment-1421302
-   * @param {Array} array
-   * @param {number} chunkSize
-   */
-  splitToChunks(array, chunkSize) {
-    const sets = [];
-    const chunks = array.length / chunkSize;
-
-    for (let i = 0, j = 0; i < chunks; i++, j += chunkSize) {
-      sets[i] = array.slice(j, j + chunkSize);
-    }
-
-    return sets;
-  }
-
   getClassesAndStyles() {
   getClassesAndStyles() {
     const { refsContext } = this.props;
     const { refsContext } = this.props;
     const { options } = refsContext;
     const { options } = refsContext;
@@ -40,34 +23,37 @@ export default class ExtractedAttachments extends React.PureComponent {
       'max-width': maxWidth,
       'max-width': maxWidth,
       'max-height': maxHeight,
       'max-height': maxHeight,
       display = 'block',
       display = 'block',
+      grid,
     } = options;
     } = options;
 
 
-    let anchorClasses = [];
     let imageClasses = [];
     let imageClasses = [];
     const anchorStyles = {
     const anchorStyles = {
-      width, height, maxWidth, maxHeight,
+      maxWidth, maxHeight,
     };
     };
     const imageStyles = {
     const imageStyles = {
-      height, maxHeight,
+      maxWidth, maxHeight,
     };
     };
 
 
-    const columnSize = refsContext.getOptColumnSize();
     // grid mode
     // grid mode
-    if (columnSize != null) {
-      anchorClasses = anchorClasses.concat([`col-sm-${columnSize}`]);
+    if (grid != null) {
       // fit image to the parent
       // fit image to the parent
-      imageClasses = imageClasses.concat(['w-100']);
+      imageClasses = imageClasses.concat(['w-100', 'h-100']);
       Object.assign(imageStyles, { objectFit: 'cover' });
       Object.assign(imageStyles, { objectFit: 'cover' });
+      Object.assign(anchorStyles, {
+        width: refsContext.getOptGridWidth(),
+        height: refsContext.getOptGridHeight(),
+      });
     }
     }
     else {
     else {
-      // init width/maxWidth
-      Object.assign(imageStyles, { width, maxWidth });
+      // set width/height
+      Object.assign(anchorStyles, { width, height });
+      Object.assign(imageStyles, { width, height });
+      // set display
+      Object.assign(anchorStyles, { display });
     }
     }
 
 
-    Object.assign(anchorStyles, { display });
 
 
     return {
     return {
-      anchorClasses,
       imageClasses,
       imageClasses,
       anchorStyles,
       anchorStyles,
       imageStyles,
       imageStyles,
@@ -84,11 +70,11 @@ export default class ExtractedAttachments extends React.PureComponent {
 
 
     // get styles
     // get styles
     const {
     const {
-      anchorClasses, imageClasses, anchorStyles, imageStyles,
+      imageClasses, anchorStyles, imageStyles,
     } = this.getClassesAndStyles();
     } = this.getClassesAndStyles();
 
 
     return (
     return (
-      <a key={attachment._id} href="#" className={anchorClasses.join(' ')} style={anchorStyles}>
+      <a key={attachment._id} href="#" style={anchorStyles}>
         <img src={attachment.filePathProxied} alt={alt} className={imageClasses.join(' ')} style={imageStyles} />
         <img src={attachment.filePathProxied} alt={alt} className={imageClasses.join(' ')} style={imageStyles} />
       </a>
       </a>
     );
     );
@@ -96,6 +82,7 @@ export default class ExtractedAttachments extends React.PureComponent {
 
 
   render() {
   render() {
     const { refsContext } = this.props;
     const { refsContext } = this.props;
+    const { grid, 'grid-gap': gridGap } = refsContext.options;
 
 
     const contents = this.props.attachments.map((attachment) => {
     const contents = this.props.attachments.map((attachment) => {
       const isImage = attachment.fileFormat.startsWith('image/');
       const isImage = attachment.fileFormat.startsWith('image/');
@@ -105,23 +92,26 @@ export default class ExtractedAttachments extends React.PureComponent {
         : <AttachmentLink key={attachment._id} attachment={attachment} />;
         : <AttachmentLink key={attachment._id} attachment={attachment} />;
     });
     });
 
 
-    const columnSize = refsContext.getOptColumnSize();
-    let contentChunks; // [[c1, c2, c3], [c4, c5, c6], ...]
-    if (columnSize != null) {
-      contentChunks = this.splitToChunks(contents, 12 / columnSize);
-    }
-    else {
-      contentChunks = [contents];
+    const styles = {};
+
+    let gridTemplateColumns;
+    if (grid != null) {
+      gridTemplateColumns = (refsContext.isOptGridColumnEnabled())
+        ? `repeat(${refsContext.getOptGridColumnsNum()}, 1fr)`
+        : `repeat(auto-fill, ${refsContext.getOptGridWidth()})`;
+      Object.assign(styles, {
+        display: 'grid',
+        gridTemplateColumns,
+        gridAutoRows: '1fr',
+        gridGap,
+      });
     }
     }
 
 
-    return contentChunks.map((chunk, index) => {
-      return (
-        // eslint-disable-next-line react/no-array-index-key
-        <div key={`row-chunk-${index}`} className="row mt-5">
-          {chunk}
-        </div>
-      );
-    });
+    return (
+      <div style={styles}>
+        {contents}
+      </div>
+    );
   }
   }
 
 
 }
 }

+ 65 - 13
packages/growi-plugin-attachment-refs/src/client/js/util/RefsContext.js

@@ -111,32 +111,84 @@ export default class RefsContext extends TagContext {
     return OptionParser.parseRange(this.options.depth);
     return OptionParser.parseRange(this.options.depth);
   }
   }
 
 
-  getOptColumnSize() {
+  isOptGridColumnEnabled() {
     const { grid } = this.options;
     const { grid } = this.options;
+    return (grid != null) && grid.startsWith('col-');
+  }
+
+  getOptGridWidth() {
+    const { grid, width } = this.options;
+
+    // when Grid column mode
+    if (this.isOptGridColumnEnabled()) {
+      // not specify and ignore width
+      return undefined;
+    }
+
+    // when width is specified
+    if (width != null) {
+      return width;
+    }
+
+    // when Grid autofill mode
+    let autofillMagnification = 1;
+
+    switch (grid) {
+      case 'autofill-4x':
+        autofillMagnification = 4;
+        break;
+      case 'autofill-3x':
+        autofillMagnification = 3;
+        break;
+      case 'autofill-2x':
+        autofillMagnification = 2;
+        break;
+      case 'autofill':
+      default:
+        break;
+    }
+
+    return `${autofillMagnification * 100}px`;
+  }
+
+  getOptGridHeight() {
+    const { height } = this.options;
+
+    // when height is specified
+    if (height != null) {
+      return height;
+    }
+
+    // return the value which is same to width
+    return this.getOptGridWidth();
+  }
 
 
-    let columnSize = null;
+  getOptGridColumnsNum() {
+    const { grid } = this.options;
+
+    let columnsNum = null;
 
 
     if (grid != null) {
     if (grid != null) {
       switch (grid) {
       switch (grid) {
-        case 'col-6':
-          columnSize = 6;
-          break;
-        case 'col-4':
-          columnSize = 4;
+        case 'col-2':
+          columnsNum = 2;
           break;
           break;
         case 'col-3':
         case 'col-3':
-          columnSize = 3;
+          columnsNum = 3;
           break;
           break;
-        case 'col-2':
-          columnSize = 2;
+        case 'col-4':
+          columnsNum = 4;
+          break;
+        case 'col-5':
+          columnsNum = 5;
           break;
           break;
-        case 'col-1':
-          columnSize = 1;
+        case 'col-6':
+          columnsNum = 6;
           break;
           break;
       }
       }
     }
     }
 
 
-    return columnSize;
+    return columnsNum;
   }
   }
 
 
   /**
   /**