Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement src attribute for popovers #1780

Merged
merged 27 commits into from
Mar 10, 2022
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 14 additions & 15 deletions docs/userGuide/syntax/popovers.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,30 +85,29 @@ This is the same <trigger for="pop:trigger_id">trigger</trigger> as last one.
<include src="extra/triggers.md" />
</panel><p/>

****Options****

Name | Type | Default | Description
---- | ---- | ------- | ------
trigger | `String` | `hover` | How the Popover is triggered.<br>Supports: `click`, `focus`, `hover`.
header{{slot_info_trigger}} | `String` | `''` | Popover header, supports MarkDown text.
content{{slot_info_trigger}} | `String` | `''` | Popover content, supports MarkDown text.
src | `String` | | The url to the remote page to be loaded as the content of the popover. Both .md and .html are accepted.
placement | `String` | `top` | How to position the Popover.<br>Supports: `top`, `left`, `right`, `bottom`.
\***\*Options\*\***
jovyntls marked this conversation as resolved.
Show resolved Hide resolved

| Name | Type | Default | Description |
| ---------------------------- | -------- | ------- | ------------------------------------------------------------------------------------------------------- |
| trigger | `String` | `hover` | How the Popover is triggered.<br>Supports: `click`, `focus`, `hover`. |
| header{{slot_info_trigger}} | `String` | `''` | Popover header, supports MarkDown text. |
| content{{slot_info_trigger}} | `String` | `''` | Popover content, supports MarkDown text. |
| src | `String` | | The url to the remote page to be loaded as the content of the popover. Both .md and .html are accepted. |
jovyntls marked this conversation as resolved.
Show resolved Hide resolved
| placement | `String` | `top` | How to position the Popover.<br>Supports: `top`, `left`, `right`, `bottom`. |

jovyntls marked this conversation as resolved.
Show resolved Hide resolved
<span id="short" class="d-none">

```html
Hover over the <trigger for="pop:context-target">keyword</trigger> to see the popover.
Hover over the <trigger for="pop:context-target">keyword</trigger> to see the
popover.
jovyntls marked this conversation as resolved.
Show resolved Hide resolved

<popover id="pop:context-target" header="Popover header" placement="top">
<div slot="content">

description :+1:

</div>
<div slot="content">
description :+1:
</div>
</popover>
```

jovyntls marked this conversation as resolved.
Show resolved Hide resolved
</span>

<span id="examples" class="d-none">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
</template>
<button class="btn btn-secondary">Trigger should not have `algolia-no-index` class</button>
</popover>
<popover effect="fade" placement="top"><template #content>Content should have <code class="hljs inline no-lang" v-pre>algolia-no-index</code> class</template><template #header>Title</template>
<popover placement="top"><template #content>Content should have <code class="hljs inline no-lang" v-pre>algolia-no-index</code> class</template><template #header>Title</template>
<button class="btn btn-secondary">Trigger should not have `algolia-no-index` class</button>
</popover>
<p><strong>Tooltip content should have algolia-no-index class</strong></p>
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 6 additions & 4 deletions packages/core/src/html/MdAttributeRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,9 @@ class MdAttributeRenderer {
const hasAttribute = _.has(node.attribs, attribute);
if (hasAttribute) {
logger.warn(`${node.name} has a ${slotName} slot, '${attribute}' attribute has no effect.`);
delete node.attribs[attribute];
}

delete node.attribs[attribute];

return hasAttribute;
}

Expand All @@ -83,9 +82,12 @@ class MdAttributeRenderer {
return;
}

if (!_.has(node.attribs, 'src')) {
this.processAttributeWithoutOverride(node, 'content', true);
if (_.has(node.attribs, 'content') && _.has(node.attribs, 'src')) {
logger.warn(`${node.name} has a 'content' attribute, 'src' attribute has no effect.`);
delete node.attribs.src;
}

this.processAttributeWithoutOverride(node, 'content', true);
}

processTooltip(node) {
Expand Down
4 changes: 4 additions & 0 deletions packages/core/src/html/elements.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,8 @@ module.exports = {
createEmptyNode() {
return cheerio.parseHTML('<div></div>', true)[0];
},

createSlotTemplateNode(content) {
return cheerio.parseHTML(`<template #content>${content}</template>`, true);
jovyntls marked this conversation as resolved.
Show resolved Hide resolved
},
};
28 changes: 15 additions & 13 deletions packages/core/src/html/includePanelProcessor.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const url = require('url');

const { createErrorNode, createEmptyNode } = require('./elements');
const { CyclicReferenceError } = require('../errors');
const { appendSlotNode } = require('./vueSlotSyntaxProcessor');

const fsUtil = require('../utils/fsUtil');
const logger = require('../utils/logger');
Expand Down Expand Up @@ -270,10 +271,7 @@ function processPopoverSrc(node, context, pageSources, variableProcessor, render
const error = new Error(`Empty src attribute in include in: ${context.cwf}`);
logger.error(error);
cheerio(node).replaceWith(createErrorNode(node, error));
}

if (_.has(node.attribs, 'content')) {
logger.warn(`${node.name} has a 'src' attribute, 'content' attribute has no effect.`);
return context;
}

const {
Expand All @@ -283,17 +281,19 @@ function processPopoverSrc(node, context, pageSources, variableProcessor, render
actualFilePath,
} = _getSrcFlagsAndFilePaths(node, config);

// No need to process url contents
if (isUrl) {
const error = new Error('URLs are not allowed in the \'src\' attribute');
logger.error(error);
cheerio(node).replaceWith(createErrorNode(node, error));
return context;
}

const fileExistsNode = _getFileExistsNode(node, context, actualFilePath, pageSources);
if (fileExistsNode) {
return fileExistsNode;
}

// No need to process url contents
if (isUrl) {
delete node.attribs.src;
return node;
}

pageSources.staticIncludeSrc.push({
from: context.cwf,
to: actualFilePath,
Expand Down Expand Up @@ -322,7 +322,9 @@ function processPopoverSrc(node, context, pageSources, variableProcessor, render
+ `Missing reference in ${context.cwf}`);
logger.error(error);

actualContent = cheerio.html(createErrorNode(node, error));
cheerio(node).replaceWith(createErrorNode(node, error));

return context;
}
}

Expand All @@ -335,11 +337,11 @@ function processPopoverSrc(node, context, pageSources, variableProcessor, render
const error = new CyclicReferenceError(childContext.callStack);
logger.error(error);
cheerio(node).replaceWith(createErrorNode(node, error));
return context;
}
}

const attributeSlotElement = cheerio.parseHTML(`<template #content>${actualContent}</template>`, true);
node.children = node.children ? attributeSlotElement.concat(node.children) : attributeSlotElement;
appendSlotNode(node, actualContent);

delete node.attribs.src;

Expand Down
8 changes: 8 additions & 0 deletions packages/core/src/html/vueSlotSyntaxProcessor.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ const _ = {};
_.has = require('lodash/has');
_.find = require('lodash/find');

const { createSlotTemplateNode } = require('./elements');

function appendSlotNode(node, content) {
const attributeSlotElement = createSlotTemplateNode(content);
node.children = node.children ? attributeSlotElement.concat(node.children) : attributeSlotElement;
}
jovyntls marked this conversation as resolved.
Show resolved Hide resolved

function getVslotShorthandName(node) {
if (!node.attribs) {
return '';
Expand Down Expand Up @@ -68,6 +75,7 @@ function transformOldSlotSyntax(node) {
}

module.exports = {
appendSlotNode,
getVslotShorthandName,
shiftSlotNodeDeeper,
transformOldSlotSyntax,
Expand Down