From 4cf74a029153c21d998304713ad42f493dd61696 Mon Sep 17 00:00:00 2001 From: ache Date: Thu, 8 Nov 2018 02:26:08 +0100 Subject: 0.8.0 --- .babelrc | 4 +-- dist/index.js | 102 ++++++++++++++++++++++++++++++++-------------------------- package.json | 21 ++++++------ 3 files changed, 70 insertions(+), 57 deletions(-) diff --git a/.babelrc b/.babelrc index 1aa4b7b..cf18521 100644 --- a/.babelrc +++ b/.babelrc @@ -1,6 +1,6 @@ { - "presets": ["env"], + "presets": ["@babel/env"], "plugins": [ - ["transform-object-rest-spread", { "useBuiltIns": true }] + ["@babel/plugin-proposal-object-rest-spread"] ] } diff --git a/dist/index.js b/dist/index.js index ab2f4a2..fd8eaef 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1,17 +1,22 @@ 'use strict'; +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + var parseAttr = require('md-attr-parser'); + var htmlElemAttr = require('html-element-attributes'); var supportedElements = ['link', 'atxHeading', 'strong', 'emphasis', 'deletion', 'code', 'setextHeading', 'fencedCode']; var blockElements = ['atxHeading', 'setextHeading']; var particularElements = ['fencedCode']; - var particularTokenize = {}; var DOMEventHandler = require('./dom-event-handler.js'); - /* Table convertion between type and HTML tagName */ + + var convTypeTag = { image: 'img', link: 'a', @@ -23,7 +28,6 @@ var convTypeTag = { code: 'code', '*': '*' }; - /* This function is a generic function that transform * the tokenize function a node type to a version that understand * attributes. @@ -43,58 +47,59 @@ var convTypeTag = { * - The config is the configuration of this plugin * */ + function tokenizeGenerator(prefix, oldParser, config) { function token(eat, value, silent) { // This we call the old tokenize var self = this; var eaten = oldParser.call(self, eat, value, silent); - var index = 0; - var parsedAttr = void 0; + var parsedAttr; var length = value.length; - if (!eaten || !eaten.position) { return undefined; } var type = convTypeTag[eaten.type]; + index = eaten.position.end.offset - eaten.position.start.offset; // Then we check for attributes - index = eaten.position.end.offset - eaten.position.start.offset; - - // Then we check for attributes if (index + prefix.length < length && value.charAt(index + prefix.length) === '{') { // If any, parse it parsedAttr = parseAttr(value, index + prefix.length, config.mdAttrConfig); - } + } // If parsed configure the node + - // If parsed configure the node if (parsedAttr) { if (config.scope && config.scope !== 'none') { var filtredProp = filterAttributes(parsedAttr.prop, config, type); + if (filtredProp !== {}) { if (eaten.data) { eaten.data.hProperties = filtredProp; } else { - eaten.data = { hProperties: filtredProp }; + eaten.data = { + hProperties: filtredProp + }; } } } + eaten = eat(prefix + parsedAttr.eaten)(eaten); } return eaten; - } - // Return the new tokenizer function + } // Return the new tokenizer function + + return token; -} +} // A generic function to parse attributes + -// A generic function to parse attributes function filterAttributes(prop, config, type) { var scope = config.scope; var extend = config.extend; var allowDangerousDOMEventHandlers = config.allowDangerousDOMEventHandlers; - var specific = htmlElemAttr; var extendTag = function (extend) { @@ -103,9 +108,9 @@ function filterAttributes(prop, config, type) { t[convTypeTag[p]] = extend[p]; }); return t; - }(extend); + }(extend); // Delete empty key/class/id attributes + - // Delete empty key/class/id attributes Object.getOwnPropertyNames(prop).forEach(function (p) { if (p !== 'key' && p !== 'class' && p !== 'id') { prop[p] = prop[p] || ''; @@ -115,29 +120,32 @@ function filterAttributes(prop, config, type) { var isDangerous = function isDangerous(p) { return DOMEventHandler.indexOf(p) >= 0; }; + var isSpecific = function isSpecific(p) { return type in specific && specific[type].indexOf(p) >= 0; }; + var isGlobal = function isGlobal(p) { return htmlElemAttr['*'].indexOf(p) >= 0 || p.match(/^aria-[a-z]{3,24}$/); }; var inScope = function inScope(_) { return false; - }; + }; // Function used to `or combine` two other function. + - // Function used to `or combine` two other function. var orFunc = function orFunc(fun, fun2) { return function (x) { return fun(x) || fun2(x); }; - }; + }; // Respect the scope configuration + - // Respect the scope configuration switch (scope) { case 'none': // Plugin is disabled break; + case 'permissive': case 'every': if (allowDangerousDOMEventHandlers) { @@ -149,60 +157,65 @@ function filterAttributes(prop, config, type) { return !isDangerous(x); }; } + break; + case 'extended': default: inScope = function inScope(p) { return extendTag && type in extendTag && extendTag[type].indexOf(p) >= 0; }; + inScope = orFunc(inScope, function (p) { return '*' in extendTag && extendTag['*'].indexOf(p) >= 0; }); // Or if it in the specific scope, fallthrough + case 'specific': inScope = orFunc(inScope, isSpecific); // Or if it in the global scope fallthrough + case 'global': inScope = orFunc(inScope, isGlobal); + if (allowDangerousDOMEventHandlers) { // If allowed add dangerous attributes to global scope inScope = orFunc(inScope, isDangerous); } - } - // If an attributes isn't in the scope, delete it + } // If an attributes isn't in the scope, delete it + + Object.getOwnPropertyNames(prop).forEach(function (p) { if (!inScope(p)) { delete prop[p]; } }); - return prop; } - /* This is a special modification of the function tokenizeGenerator * to parse the fencedCode info string and the fallback * customAttr parser * * It's only temporary */ + + function tokenizeFencedCode(oldParser, config) { var prefix = '\n'; + function token(eat, value, silent) { // This we call the old tokenize var self = this; var eaten = oldParser.call(self, eat, value, silent); - - var parsedAttr = void 0; + var parsedAttr; var parsedByCustomAttr = false; if (!eaten || !eaten.position) { return undefined; } - var type = convTypeTag[eaten.type]; - - // First, parse the info string + var type = convTypeTag[eaten.type]; // First, parse the info string // which is the 'lang' attributes of 'eaten'. if (eaten.lang) { @@ -215,44 +228,43 @@ function tokenizeFencedCode(oldParser, config) { // Bad hack, will be deleted soon parsedAttr = parseAttr(value, value.indexOf(' ')); } - } + } // If parsed configure the node + - // If parsed configure the node if (parsedAttr) { if (config.scope && config.scope !== 'none') { var filtredProp = filterAttributes(parsedAttr.prop, config, type); if (filtredProp !== {}) { if (eaten.data) { - eaten.data.hProperties = Object.assign({}, eaten.data.hProperties, filtredProp); + eaten.data.hProperties = _objectSpread({}, eaten.data.hProperties, filtredProp); } else { - eaten.data = { hProperties: filtredProp }; + eaten.data = { + hProperties: filtredProp + }; } } } + if (parsedByCustomAttr) { eaten = eat(prefix + parsedAttr.eaten)(eaten); } } return eaten; - } + } // Return the new tokenizer function - // Return the new tokenizer function return token; } particularTokenize.fencedCode = tokenizeFencedCode; - remarkAttr.SUPPORTED_ELEMENTS = supportedElements; - module.exports = remarkAttr; - /* Function that is exported */ + function remarkAttr(userConfig) { var parser = this.Parser; - var defaultConfig = { allowDangerousDOMEventHandlers: false, elements: supportedElements, @@ -260,16 +272,16 @@ function remarkAttr(userConfig) { scope: 'extended', mdAttrConfig: undefined }; - var config = Object.assign({}, defaultConfig, userConfig); + + var config = _objectSpread({}, defaultConfig, userConfig); if (!isRemarkParser(parser)) { throw new Error('Missing parser to attach `remark-attr` [link] (to)'); } var tokenizers = parser.prototype.inlineTokenizers; - var tokenizersBlock = parser.prototype.blockTokenizers; + var tokenizersBlock = parser.prototype.blockTokenizers; // For each elements, replace the old tokenizer by the new one - // For each elements, replace the old tokenizer by the new one config.elements.forEach(function (elem) { if (supportedElements.indexOf(elem) >= 0) { if (blockElements.indexOf(elem) >= 0) { diff --git a/package.json b/package.json index daae4cf..90f60e0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "remark-attr", - "version": "0.7.1", + "version": "0.8.0", "description": "Add support of custom attributes to Markdown syntax.", "main": "dist/index.js", "scripts": { @@ -15,24 +15,25 @@ "plugin" ], "author": "ache ", - "license": "MIT", + "license": "GPL-3.0-or-later", "bugs": { "url": "https://github.com/arobase-che/remark-attr/issues" }, "homepage": "https://github.com/arobase-che/remark-attr#readme", "devDependencies": { + "@babel/cli": "^7.1.5", + "@babel/core": "^7.1.5", + "@babel/plugin-proposal-object-rest-spread": "^7.0.0", + "@babel/preset-env": "^7.1.5", "ava": "^0.25.0", - "babel-cli": "^6.26.0", - "babel-plugin-transform-object-rest-spread": "^6.26.0", - "babel-preset-env": "^1.6.1", - "cross-env": "^5.1.4", + "cross-env": "^5.2.0", "del-cli": "^1.1.0", - "parse5": "^5.0.0", + "parse5": "^5.1.0", "rehype-raw": "^3.0.0", "rehype-stringify": "^4.0.0", - "remark-parse": "^5.0.0", + "remark-parse": "^6.0.1", "remark-rehype": "^3.0.1", - "unified": "^7.0.0", + "unified": "^7.0.1", "xo": "^0.23.0" }, "xo": { @@ -46,6 +47,6 @@ }, "dependencies": { "html-element-attributes": "^2.0.0", - "md-attr-parser": "^1.1.6" + "md-attr-parser": "^1.2.0" } } -- cgit v1.2.3