diff --git a/src/code_manager/model/HtmlGenerator.js b/src/code_manager/model/HtmlGenerator.js index ca8858a1c..e93d5e58b 100644 --- a/src/code_manager/model/HtmlGenerator.js +++ b/src/code_manager/model/HtmlGenerator.js @@ -2,22 +2,49 @@ import Backbone from 'backbone'; export default Backbone.Model.extend({ build(model, opts = {}) { - const models = model.get('components'); + const models = model.components(); + const htmlOpts = {}; + const { em } = opts; + + // Remove unnecessary IDs + if (opts.cleanId && em) { + const rules = em.get('CssComposer').getAll(); + const idRules = rules + .toJSON() + .map(rule => { + const sels = rule.selectors; + const sel = sels && sels.length === 1 && sels.models[0]; + return sel && sel.isId() && sel.get('name'); + }) + .filter(i => i); + + htmlOpts.attributes = (mod, attrs) => { + const { id } = attrs; + if ( + id && + id[0] === 'i' && // all autogenerated IDs start with 'i' + !mod.get('script') && // if the component has script, we have to leave the ID + idRules.indexOf(id) < 0 // we shouldn't have any rule with this ID + ) { + delete attrs.id; + } + return attrs; + }; + } if (opts.exportWrapper) { return model.toHTML({ + ...htmlOpts, ...(opts.wrapperIsBody && { tag: 'body' }) }); } - return this.buildModels(models); + return this.buildModels(models, htmlOpts); }, - buildModels(models) { + buildModels(models, opts = {}) { let code = ''; - models.each(model => { - code += model.toHTML(); - }); + models.forEach(mod => (code += mod.toHTML(opts))); return code; } }); diff --git a/src/editor/config/config.js b/src/editor/config/config.js index aa724b04a..65de1a58f 100644 --- a/src/editor/config/config.js +++ b/src/editor/config/config.js @@ -119,6 +119,12 @@ export default { // The wrapper, if visible, will be shown as a `
` wrapperIsBody: 1, + // Pass default available options wherever `editor.getHtml()` is called + optsHtml: {}, + + // Pass default available options wherever `editor.getCss()` is called + optsCss: {}, + // Usually when you update the `style` of the component this changes the // element's `style` attribute. Unfortunately, inline styling doesn't allow // use of media queries (@media) or even pseudo selectors (eg. :hover). diff --git a/src/editor/index.js b/src/editor/index.js index 55def9ae0..421bb326a 100644 --- a/src/editor/index.js +++ b/src/editor/index.js @@ -198,7 +198,7 @@ export default (config = {}) => { /** * Returns configuration object * @param {string} [prop] Property name - * @return {any} Returns the configuration object or + * @returns {any} Returns the configuration object or * the value of the specified property */ getConfig(prop) { @@ -207,7 +207,9 @@ export default (config = {}) => { /** * Returns HTML built inside canvas - * @return {string} HTML string + * @param {Object} [opts={}] Options + * @param {Boolean} [opts.cleanId=false] Remove unnecessary IDs (eg. those created automatically) + * @returns {string} HTML string */ getHtml(opts) { return em.getHtml(opts); @@ -217,7 +219,7 @@ export default (config = {}) => { * Returns CSS built inside canvas * @param {Object} [opts={}] Options * @param {Boolean} [opts.avoidProtected=false] Don't include protected CSS - * @return {string} CSS string + * @returns {string} CSS string */ getCss(opts) { return em.getCss(opts); @@ -225,7 +227,7 @@ export default (config = {}) => { /** * Returns JS of all components - * @return {string} JS string + * @returns {string} JS string */ getJs() { return em.getJs(); diff --git a/src/editor/model/Editor.js b/src/editor/model/Editor.js index 8278c357a..a835cbe5f 100644 --- a/src/editor/model/Editor.js +++ b/src/editor/model/Editor.js @@ -493,18 +493,22 @@ export default Backbone.Model.extend({ /** * Returns HTML built inside canvas - * @return {string} HTML string + * @param {Object} [opts={}] Options + * @returns {string} HTML string * @private */ - getHtml() { + getHtml(opts = {}) { const config = this.config; + const { optsHtml } = config; const exportWrapper = config.exportWrapper; const wrapperIsBody = config.wrapperIsBody; const js = config.jsInHtml ? this.getJs() : ''; var wrp = this.get('DomComponents').getComponent(); var html = this.get('CodeManager').getCode(wrp, 'html', { exportWrapper, - wrapperIsBody + wrapperIsBody, + ...optsHtml, + ...opts }); html += js ? `` : ''; return html; @@ -513,11 +517,12 @@ export default Backbone.Model.extend({ /** * Returns CSS built inside canvas * @param {Object} [opts={}] Options - * @return {string} CSS string + * @returns {string} CSS string * @private */ getCss(opts = {}) { const config = this.config; + const { optsCss } = config; const wrapperIsBody = config.wrapperIsBody; const avoidProt = opts.avoidProtected; const keepUnusedStyles = !isUndefined(opts.keepUnusedStyles) @@ -532,7 +537,8 @@ export default Backbone.Model.extend({ this.get('CodeManager').getCode(wrp, 'css', { cssc, wrapperIsBody, - keepUnusedStyles + keepUnusedStyles, + ...optsCss }) ); }, diff --git a/src/selector_manager/model/Selector.js b/src/selector_manager/model/Selector.js index 5c0c03956..bea0338e3 100644 --- a/src/selector_manager/model/Selector.js +++ b/src/selector_manager/model/Selector.js @@ -48,6 +48,14 @@ const Selector = Model.extend( this.em = config.em; }, + isId() { + return this.get('type') === TYPE_ID; + }, + + isClass() { + return this.get('type') === TYPE_CLASS; + }, + /** * Get full selector name * @return {string}