diff --git a/css/sass/shortcode-ui-editor-styles.scss b/css/sass/shortcode-ui-editor-styles.scss index 6c602c9b..b20e13e0 100644 --- a/css/sass/shortcode-ui-editor-styles.scss +++ b/css/sass/shortcode-ui-editor-styles.scss @@ -23,3 +23,25 @@ body#wpview-iframe-sandbox { width: 100%; overflow: hidden; } + +.test-editable-blockquote { + + padding: 20px; + border: 1px solid #E1e1e1; + background: #f5f5f5; + + [contentEditable]:focus { + outline: none; + } + + blockquote { + font-size: 24px; + line-height: 1.5; + } + + p { + font-size: 16px; + line-height: 1.5; + font-style: italic; + } +} diff --git a/css/sass/shortcode-ui.scss b/css/sass/shortcode-ui.scss index 228107cf..72b77718 100644 --- a/css/sass/shortcode-ui.scss +++ b/css/sass/shortcode-ui.scss @@ -81,11 +81,11 @@ padding: 10px; border-top: 1px solid #ddd; } - + a.wp-color-result { border-bottom: 1px solid #ccc; } - + .media-toolbar { position: relative; height: auto; diff --git a/css/shortcode-ui-editor-styles.css b/css/shortcode-ui-editor-styles.css index 0a2e4c2d..6c42f54f 100644 --- a/css/shortcode-ui-editor-styles.css +++ b/css/shortcode-ui-editor-styles.css @@ -13,4 +13,18 @@ body#wpview-iframe-sandbox { width: 100%; overflow: hidden; } +.test-editable-blockquote { + padding: 20px; + border: 1px solid #E1e1e1; + background: #f5f5f5; } + .test-editable-blockquote [contentEditable]:focus { + outline: none; } + .test-editable-blockquote blockquote { + font-size: 24px; + line-height: 1.5; } + .test-editable-blockquote p { + font-size: 16px; + line-height: 1.5; + font-style: italic; } + /*# sourceMappingURL=shortcode-ui-editor-styles.css.map */ \ No newline at end of file diff --git a/css/shortcode-ui-editor-styles.css.map b/css/shortcode-ui-editor-styles.css.map index 8518dbc8..643e36e9 100644 --- a/css/shortcode-ui-editor-styles.css.map +++ b/css/shortcode-ui-editor-styles.css.map @@ -5,6 +5,6 @@ "../shortcode-ui-editor-styles.scss" ], "sourcesContent": [], - "mappings": "AAGA,AAAY,AAA0B;EACnC,AAAS;AAIZ,AAAa;EACX,AAAO;EACP,AAAa;AAGf,AAAa;EACX,AAAa;EACb,AAAO;EACP,AAAW;;AAIb,AAAI;EACH,AAAS;EACT,AAAO;EACP,AAAU", + "mappings": "AAGA,AAAY,AAA0B;EACnC,AAAS;AAIZ,AAAa;EACX,AAAO;EACP,AAAa;AAGf,AAAa;EACX,AAAa;EACb,AAAO;EACP,AAAW;;AAIb,AAAI;EACH,AAAS;EACT,AAAO;EACP,AAAU;;AAGX;EAEC,AAAS;EACT,AAAQ;EACR,AAAY;EAEb,AAA0B,AAAiB;IACzC,AAAS;EAGX,AAA0B;IACxB,AAAW;IACX,AAAa;EAGf,AAA0B;IACxB,AAAW;IACX,AAAa;IACb,AAAY", "names": [] } \ No newline at end of file diff --git a/inc/templates/edit-form.tpl.php b/inc/templates/edit-form.tpl.php index 83cf677a..fb43a380 100644 --- a/inc/templates/edit-form.tpl.php +++ b/inc/templates/edit-form.tpl.php @@ -135,3 +135,13 @@ <# } #> + + + + + diff --git a/js-tests/build/specs.js b/js-tests/build/specs.js index 11a40a67..a2d6539c 100644 --- a/js-tests/build/specs.js +++ b/js-tests/build/specs.js @@ -288,7 +288,7 @@ describe( "MCE View Constructor", function() { } ); }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./../../../js/src/models/shortcode.js":10,"./../../../js/src/utils/shortcode-view-constructor.js":11,"./../../../js/src/utils/sui.js":12}],5:[function(require,module,exports){ +},{"./../../../js/src/models/shortcode.js":10,"./../../../js/src/utils/shortcode-view-constructor.js":12,"./../../../js/src/utils/sui.js":13}],5:[function(require,module,exports){ var Shortcodes = require('./../../../js/src/collections/shortcodes.js'); var sui = require('./../../../js/src/utils/sui.js'); @@ -305,7 +305,7 @@ describe( "SUI Util", function() { } ); -},{"./../../../js/src/collections/shortcodes.js":7,"./../../../js/src/utils/sui.js":12}],6:[function(require,module,exports){ +},{"./../../../js/src/collections/shortcodes.js":7,"./../../../js/src/utils/sui.js":13}],6:[function(require,module,exports){ (function (global){ var Backbone = (typeof window !== "undefined" ? window.Backbone : typeof global !== "undefined" ? global.Backbone : null); var ShortcodeAttribute = require('./../models/shortcode-attribute.js'); @@ -485,10 +485,26 @@ module.exports = Shortcode; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"./../collections/shortcode-attributes.js":6,"./inner-content.js":8}],11:[function(require,module,exports){ +var getEditView = function ( id ) { + + var views = { + 'default': require('./../views/edit-shortcode-form.js'), + 'shortcake_dev': require('./../views/edit-shortcode-form-test.js'), + } + + return ( id in views ) ? views[ id ] : views['default']; + +} + +module.exports = getEditView; + +},{"./../views/edit-shortcode-form-test.js":17,"./../views/edit-shortcode-form.js":18}],12:[function(require,module,exports){ (function (global){ var sui = require('./sui.js'), wp = (typeof window !== "undefined" ? window.wp : typeof global !== "undefined" ? global.wp : null), - $ = (typeof window !== "undefined" ? window.jQuery : typeof global !== "undefined" ? global.jQuery : null); + $ = (typeof window !== "undefined" ? window.jQuery : typeof global !== "undefined" ? global.jQuery : null), + getEditView = require('./get-edit-view.js'); + // send_to_editor = require( 'sui-utils/sendtoeditor'); /** * Generic shortcode mce view constructor. @@ -498,7 +514,7 @@ var shortcodeViewConstructor = { initialize: function( options ) { this.shortcodeModel = this.getShortcodeModel( this.shortcode ); - this.fetch(); + this.renderPreview(); }, /** @@ -545,34 +561,20 @@ var shortcodeViewConstructor = { * * @return undefined */ - fetch : function() { - - var self = this; - - if ( ! this.fetching ) { - - this.fetching = true; + renderPreview : function() { - wp.ajax.post( 'do_shortcode', { - post_id: $( '#post_ID' ).val(), - shortcode: this.shortcodeModel.formatShortcode(), - nonce: shortcodeUIData.nonces.preview, - }).done( function( response ) { + var view; - if ( '' === response ) { - self.content = '' + self.shortcodeModel.formatShortcode() + ''; - } else { - self.content = response; - } + var shortcode = this.shortcodeModel; + view = getEditView( shortcode.get('shortcode_tag') ); + view = new view( { model: shortcode } ); - }).fail( function() { - self.content = '' + shortcodeUIData.strings.mce_view_error + ''; - } ).always( function() { - delete self.fetching; - self.render( null, true ); - } ); + this.content = view.render().$el; + this.render( null, true ); - } + shortcode.on('change', function() { + console.log( shortcode.formatShortcode() ); + } ); }, @@ -687,138 +689,710 @@ var shortcodeViewConstructor = { if ( switchEditors && switchEditors.pre_wpautop ) { content = switchEditors.pre_wpautop( content ); } - return content; + }, + +}; +module.exports = shortcodeViewConstructor; + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"./get-edit-view.js":11,"./sui.js":13}],13:[function(require,module,exports){ +var Shortcodes = require('./../collections/shortcodes.js'); + +window.Shortcode_UI = window.Shortcode_UI || { + shortcodes: new Shortcodes, + views: {}, + controllers: {}, +}; + +module.exports = window.Shortcode_UI; + +},{"./../collections/shortcodes.js":7}],14:[function(require,module,exports){ +var sui = require('./../utils/sui.js'); + +var editAttributeFieldAttachment = sui.views.editAttributeField.extend( { + + events: { + 'click .add' : '_openMediaFrame', + 'click .remove' : '_removeAttachment', + 'selectAttachment' : '_selectAttachment', }, - // Backwards compatability for Pre WP 4.2. - View: { + /** + * Update the field attachment. + * Re-renders UI. + * If ID is empty - does nothing. + * + * @param {int} id Attachment ID + */ + updateValue: function( id ) { - overlay: true, + if ( ! id ) { + return; + } - initialize: function( options ) { - this.shortcode = this.getShortcode( options ); - this.fetch(); - }, + this.setValue( id ); - getShortcode: function( options ) { + var self = this; - var shortcodeModel, shortcode; + if ( editAttributeFieldAttachment.getFromCache( id ) ) { + self._renderPreview( editAttributeFieldAttachment.getFromCache( id ) ); + return; - shortcodeModel = sui.shortcodes.findWhere( { shortcode_tag: options.shortcode.tag } ); + // Call the updateValue() function, to trigger any listeners + // hooked on it. + self.triggerCallbacks(); + } - if (!shortcodeModel) { - return; + this.$container.addClass( 'loading' ); + + wp.ajax.post( 'get-attachment', { + 'id': id + } ).done( function( attachment ) { + // Cache for later. + editAttributeFieldAttachment.setInCache( id, attachment ); + self._renderPreview( attachment ); + self.$container.removeClass( 'loading' ); + + // Call the updateValue() function, to trigger any listeners + // hooked on it. + self.triggerCallbacks(); + } ); + }, + + render: function() { + + // Set model default values. + for ( var arg in ShortcakeImageFieldData.defaultArgs ) { + if ( ! this.model.get( arg ) ) { + this.model.set( arg, ShortcakeImageFieldData.defaultArgs[ arg ] ); } + } - shortcode = shortcodeModel.clone(); + this.$el.html( this.template( this.model.toJSON() ) ); - shortcode.get('attrs').each( - function(attr) { + this.$container = this.$el.find( '.shortcake-attachment-preview' ); + var $addButton = this.$container.find( 'button.add' ); - if (attr.get('attr') in options.shortcode.attrs.named) { - attr.set('value', - options.shortcode.attrs.named[attr - .get('attr')]); - } + this.frame = wp.media( { + multiple: false, + title: this.model.get( 'frameTitle' ), + library: { + type: this.model.get( 'libraryType' ), + }, + } ); - }); + // Add initial Attachment if available. + this.updateValue( this.model.get( 'value' ) ); + + }, + + /** + * Renders attachment preview in field. + * @param {object} attachment model + * @return null + */ + _renderPreview: function( attachment ) { + + var $thumbnail = jQuery('
'); + + if ( 'image' !== attachment.type ) { + + jQuery( '', { + src: attachment.icon, + alt: attachment.title, + } ).appendTo( $thumbnail ); + + jQuery( '
', { + class: 'filename', + html: '
' + attachment.title + '
', + } ).appendTo( $thumbnail ); + + } else { + + attachmentThumb = (typeof attachment.sizes.thumbnail !== 'undefined') ? + attachment.sizes.thumbnail : + _.first( _.sortBy( attachment.sizes, 'width' ) ); + + jQuery( '', { + src: attachmentThumb.url, + width: attachmentThumb.width, + height: attachmentThumb.height, + alt: attachment.alt, + } ) .appendTo( $thumbnail ) + + } + + $thumbnail.find( 'img' ).wrap( '
' ); + this.$container.append( $thumbnail ); + this.$container.toggleClass( 'has-attachment', true ); - if ('content' in options.shortcode) { - var inner_content = shortcode.get('inner_content'); - if ( inner_content ) { - inner_content.set('value', options.shortcode.content) + }, + + /** + * Open media frame when add button is clicked. + * + */ + _openMediaFrame: function(e) { + e.preventDefault(); + this.frame.open(); + + var self = this; + this.frame.on( 'select', function() { + self.$el.trigger( 'selectAttachment' ); + } ); + + }, + + /** + * When an attachment is selected from the media frame, update the model value. + * + */ + _selectAttachment: function(e) { + var selection = this.frame.state().get('selection'); + attachment = selection.first(); + + this.updateValue( attachment.id ); + this.frame.close(); + }, + + /** + * Remove the attachment. + * Render preview & Update the model. + */ + _removeAttachment: function(e) { + e.preventDefault(); + + this.model.set( 'value', null ); + + this.$container.toggleClass( 'has-attachment', false ); + this.$container.find( '.thumbnail' ).remove(); + }, + +}, { + + _idCache: {}, + + /** + * Store attachments in a cache for quicker loading. + */ + setInCache: function( id, attachment ) { + this._idCache[ id ] = attachment; + }, + + /** + * Retrieve an attachment from the cache. + */ + getFromCache: function( id ){ + if ( 'undefined' === typeof this._idCache[ id ] ) { + return false; + } + return this._idCache[ id ]; + }, + +}); + +module.exports = sui.views.editAttributeFieldAttachment = editAttributeFieldAttachment; + + +},{"./../utils/sui.js":13}],15:[function(require,module,exports){ +( function( $ ) { + + var sui = window.Shortcode_UI; + + // Cached Data. + var postSelectCache = {}; + + sui.views.editAttributeFieldPostSelect = sui.views.editAttributeField.extend( { + + events: { + 'change .shortcode-ui-post-select': 'inputChanged', + }, + + inputChanged: function(e) { + this.setValue( e.val ); + this.triggerCallbacks(); + }, + + render: function() { + + var self = this, + defaults = { multiple: false }; + + for ( var arg in defaults ) { + if ( ! this.model.get( arg ) ) { + this.model.set( arg, defaults[ arg ] ); } } - return shortcode; + var data = this.model.toJSON(); + data.id = 'shortcode-ui-' + this.model.get( 'attr' ) + '-' + this.model.cid; + + this.$el.html( this.template( data ) ); + + var ajaxData = { + action : 'shortcode_ui_post_field', + nonce : shortcodeUiPostFieldData.nonce, + shortcode : this.shortcode.get( 'shortcode_tag'), + attr : this.model.get( 'attr' ) + }; + + var $field = this.$el.find( '.shortcode-ui-post-select' ); + + $field.select2({ + + placeholder: "Search", + multiple: this.model.get( 'multiple' ), + ajax: { + url: ajaxurl, + dataType: 'json', + quietMillis: 250, + data: function (term, page) { + ajaxData.s = term; + ajaxData.page = page; + return ajaxData; + }, + results: function ( response, page ) { + + if ( ! response.success ) { + return { results: {}, more: false }; + } + + // Cache data for quicker rendering later. + postSelectCache = $.extend( postSelectCache, response.data.posts ); - }, + var more = ( page * response.data.posts_per_page ) < response.data.found_posts; // whether or not there are more results available + return { results: response.data.posts, more: more }; - fetch : function() { + }, + }, + + /** + * Initialize Callback + * Used to set render the initial value. + * Has to make a request to get the title for the current ID. + */ + initSelection: function(element, callback) { + + var ids, parsedData = [], cached; - var self = this; + // Convert stored value to array of IDs (int). + ids = $(element) + .val() + .split(',') + .map( function (str) { return str.trim(); } ) + .map( function (str) { return parseInt( str ); } ) + + if ( ids.length < 1 ) { + return; + } + + // Check if there is already cached data. + for ( var i = 0; i < ids.length; i++ ) { + if ( cached = _.find( postSelectCache, _.matches( { id: ids[i] } ) ) ) { + parsedData.push( cached ); + } + }; + + // If not multiple - return single value if we have one. + if ( parsedData.length && ! self.model.get( 'multiple' ) ) { + callback( parsedData[0] ); + return; + } - if ( ! this.parsed ) { + var uncachedIds = _.difference( ids, _.pluck( parsedData, 'id' ) ); + + if ( ! uncachedIds.length ) { + + callback( parsedData ); - wp.ajax.post( 'do_shortcode', { - post_id: $( '#post_ID' ).val(), - shortcode: this.shortcode.formatShortcode(), - nonce: shortcodeUIData.nonces.preview, - }).done( function( response ) { - if ( response.indexOf( ' ids.indexOf( b.id ) ) return 1; + if ( ids.indexOf( a.id ) < ids.indexOf( b.id ) ) return -1; + return 0; + }); + + callback( parsedData ); + return; + + } ); + } - }).fail( function() { - self.parsed = '' + shortcodeUIData.strings.mce_view_error + ''; - self.render( true ); - } ); + }, + + } ); + + // Make multiple values sortable. + if ( this.model.get( 'multiple' ) ) { + $field.select2('container').find('ul.select2-choices').sortable({ + containment: 'parent', + start: function() { $('.shortcode-ui-post-select').select2('onSortStart'); }, + update: function() { $('.shortcode-ui-post-select').select2('onSortEnd'); } + }); } + return this; + + } + + } ); + + /** + * Extending SUI Media Controller to hide Select2 UI Drop-Down when menu + * changes in Meida modal + * 1. going back/forth between different shortcakes (refresh) + * 2. changing the menu in left column (deactivate) + * 3. @TODO closing the modal. + */ + var mediaController = sui.controllers.MediaController; + sui.controllers.MediaController = mediaController.extend({ + + refresh: function(){ + mediaController.prototype.refresh.apply( this, arguments ); + this.destroySelect2UI(); }, - /** - * Render the shortcode - * - * To ensure consistent rendering - this makes an ajax request to the - * admin and displays. - * - * @return string html - */ - getHtml : function() { - return this.parsed; + //doesn't need to call parent as it already an "abstract" method in parent to provide callback + deactivate: function() { + this.destroySelect2UI(); }, - /** - * Returns an array of tags for stylesheets applied to the TinyMCE editor. + destroySelect2UI: function() { + $('.shortcode-ui-post-select.select2-container').select2( "close" ); + } + + }); + + /** + * Extending the SUI Tabbed View to hide Select2 UI dropdown when previewing the shortcake + */ + var tabbedView = sui.views.TabbedView; + sui.views.TabbedView = tabbedView.extend({ + tabSwitcher: function() { + tabbedView.prototype.tabSwitcher.apply( this, arguments ); + $('.shortcode-ui-post-select.select2-container').select2( "close" ); + } + }); + +} )( jQuery ); + +},{}],16:[function(require,module,exports){ +(function (global){ +var Backbone = (typeof window !== "undefined" ? window.Backbone : typeof global !== "undefined" ? global.Backbone : null), + sui = require('./../utils/sui.js'), + $ = (typeof window !== "undefined" ? window.jQuery : typeof global !== "undefined" ? global.jQuery : null); + +var editAttributeField = Backbone.View.extend( { + + tagName: "div", + + events: { + 'keyup input[type="text"]': 'inputChanged', + 'keyup textarea': 'inputChanged', + 'change select': 'inputChanged', + 'change input[type=checkbox]': 'inputChanged', + 'change input[type=radio]': 'inputChanged', + 'change input[type=email]': 'inputChanged', + 'change input[type=number]': 'inputChanged', + 'change input[type=date]': 'inputChanged', + 'change input[type=url]': 'inputChanged', + }, + + render: function() { + + var data = jQuery.extend( { + id: 'shortcode-ui-' + this.model.get( 'attr' ) + '-' + this.model.cid, + }, this.model.toJSON() ); + + // Convert meta JSON to attribute string. + var _meta = []; + for ( var key in data.meta ) { + + // Boolean attributes can only require attribute key, not value. + if ( 'boolean' === typeof( data.meta[ key ] ) ) { + + // Only set truthy boolean attributes. + if ( data.meta[ key ] ) { + _meta.push( _.escape( key ) ); + } + + } else { + + _meta.push( _.escape( key ) + '="' + _.escape( data.meta[ key ] ) + '"' ); + + } + + } + + data.meta = _meta.join( ' ' ); + + this.$el.html( this.template( data ) ); + this.triggerCallbacks(); + + return this + }, + + /** + * Input Changed Update Callback. + * + * If the input field that has changed is for content or a valid attribute, + * then it should update the model. If a callback function is registered + * for this attribute, it should be called as well. + */ + inputChanged: function( e ) { + + if ( this.model.get( 'attr' ) ) { + var $el = this.$el.find( '[name="' + this.model.get( 'attr' ) + '"]' ); + } else { + var $el = this.$el.find( '[name="inner_content"]' ); + } + + if ( 'radio' === this.model.attributes.type ) { + this.setValue( $el.filter(':checked').first().val() ); + } else if ( 'checkbox' === this.model.attributes.type ) { + this.setValue( $el.is( ':checked' ) ); + } else { + this.setValue( $el.val() ); + } + + this.triggerCallbacks(); + }, + + getValue: function() { + return this.model.get( 'value' ); + }, + + setValue: function( val ) { + this.model.set( 'value', val ); + }, + + triggerCallbacks: function() { + + var shortcodeName = this.shortcode.attributes.shortcode_tag, + attributeName = this.model.get( 'attr' ), + hookName = [ shortcodeName, attributeName ].join( '.' ), + changed = this.model.changed, + collection = _.flatten( _.values( this.views.parent.views._views ) ), + shortcode = this.shortcode; + + /* + * Action run when an attribute value changes on a shortcode * - * @method getEditorStyles - * @returns {Array} + * Called as `{shortcodeName}.{attributeName}`. + * + * @param changed (object) + * The update, ie. { "changed": "newValue" } + * @param viewModels (array) + * The collections of views (editAttributeFields) + * which make up this shortcode UI form + * @param shortcode (object) + * Reference to the shortcode model which this attribute belongs to. */ - getEditorStyles: function() { + wp.shortcake.hooks.doAction( hookName, changed, collection, shortcode ); + + } - var styles = ''; +}, { - this.getNodes( function ( editor, node, content ) { - var dom = editor.dom, - bodyClasses = editor.getBody().className || '', - iframe, iframeDoc, i, resize; + /** + * Get an attribute field from a shortcode by name. + * + * Usage: `sui.views.editAttributeField.getField( collection, 'title')` + * + * @param array collection of editAttributeFields + * @param string attribute name + * @return editAttributeField The view corresponding to the matching field + */ + getField: function( collection, attr ) { + return _.find( collection, + function( viewModel ) { + return attr === viewModel.model.get('attr'); + } + ); + } +}); - tinymce.each( dom.$( 'link[rel="stylesheet"]', editor.getDoc().head ), function( link ) { - if ( link.href && link.href.indexOf( 'skins/lightgray/content.min.css' ) === -1 && - link.href.indexOf( 'skins/wordpress/wp-content.css' ) === -1 ) { +sui.views.editAttributeField = editAttributeField; +module.exports = editAttributeField; - styles += dom.getOuterHTML( link ) + '\n'; - } +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"./../utils/sui.js":13}],17:[function(require,module,exports){ +(function (global){ +var wp = (typeof window !== "undefined" ? window.wp : typeof global !== "undefined" ? global.wp : null), + sui = require('./../utils/sui.js'), + backbone = (typeof window !== "undefined" ? window.Backbone : typeof global !== "undefined" ? global.Backbone : null), + EditAttributeField = require('./edit-attribute-field.js'), + EditShortcodeForm = require('./edit-shortcode-form.js'), + $ = (typeof window !== "undefined" ? window.jQuery : typeof global !== "undefined" ? global.jQuery : null); - }); +/** + * Single edit shortcode content view. + */ +var EditShortcodeFormTest = EditShortcodeForm.extend({ + + template: wp.template( 'shortcode-ui-test-inline-edit' ), + + events: { + 'keyup input[type="text"]': 'inputChanged', + 'keyup textarea': 'inputChanged', + 'keyup [contenteditable]': 'inputChanged', + 'change select': 'inputChanged', + 'change input[type=checkbox]': 'inputChanged', + 'change input[type=radio]': 'inputChanged', + 'change input[type=email]': 'inputChanged', + 'change input[type=number]': 'inputChanged', + 'change input[type=date]': 'inputChanged', + 'change input[type=url]': 'inputChanged', + }, - } ); + initialize: function() {}, - return styles; - }, + render: function() { + console.log( this.model.toJSON() ); + this.$el.html( this.template( this.model.toJSON() ) ); + return this; }, -}; + inputChanged: _.debounce( function(e) { -module.exports = shortcodeViewConstructor; + var val, attr, targetAttr; + + attr = e.target.getAttribute( 'name' ); + + if ( e.target.hasAttribute( 'contenteditable' ) ) { + val = $(e.target).html(); + } else { + val = e.target.value; + } + + if ( 'content' === attr ) { + targetAttr = this.model.get( 'inner_content' ); + } else { + targetAttr = this.model.get( 'attrs' ).findWhere( { attr: attr } ); + } + + if ( targetAttr ) { + targetAttr.set( 'value', val ); + this.model.trigger('change'); + this.model.trigger('changed'); + } + + + }, 250 ), + +}); + +module.exports = EditShortcodeFormTest; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./sui.js":12}],12:[function(require,module,exports){ -var Shortcodes = require('./../collections/shortcodes.js'); +},{"./../utils/sui.js":13,"./edit-attribute-field.js":16,"./edit-shortcode-form.js":18}],18:[function(require,module,exports){ +(function (global){ +var wp = (typeof window !== "undefined" ? window.wp : typeof global !== "undefined" ? global.wp : null), + sui = require('./../utils/sui.js'), + backbone = (typeof window !== "undefined" ? window.Backbone : typeof global !== "undefined" ? global.Backbone : null), + editAttributeField = require('./edit-attribute-field.js'), -window.Shortcode_UI = window.Shortcode_UI || { - shortcodes: new Shortcodes, - views: {}, - controllers: {}, -}; + // Additional attribute field types: these fields are all standalone in functionality, + // but bundled here for simplicity to save an HTTP request. + editAttributeFieldAttachment = require('./edit-attribute-field-attachment.js'), + editAttributeFieldPostSelect = require('./edit-attribute-field-post-select.js'); -module.exports = window.Shortcode_UI; -},{"./../collections/shortcodes.js":7}]},{},[1,2,3,4,5]); +/** + * Single edit shortcode content view. + */ +var EditShortcodeForm = wp.Backbone.View.extend({ + template: wp.template('shortcode-default-edit-form'), + + initialize: function() { + + var t = this; + + var innerContent = this.model.get( 'inner_content' ); + if ( innerContent && typeof innerContent.attributes.type !== 'undefined' ) { + + // add UI for inner_content + var view = new editAttributeField( { model: innerContent } ); + + view.shortcode = t.model; + view.template = wp.media.template( 'shortcode-ui-content' ); + + t.views.add( '.edit-shortcode-form-fields', view ); + + } + + this.model.get( 'attrs' ).each( function( attr ) { + + // Get the field settings from localization data. + var type = attr.get('type'); + + if ( ! shortcodeUIFieldData[ type ] ) { + return; + } + + var templateData = { + value: attr.get('value'), + attr_raw: { + name: attr.get('value') + } + } + + var viewObjName = shortcodeUIFieldData[ type ].view; + var tmplName = shortcodeUIFieldData[ type ].template; + + var view = new sui.views[viewObjName]( { model: attr } ); + view.template = wp.media.template( tmplName ); + view.shortcode = t.model; + + t.views.add( '.edit-shortcode-form-fields', view ); + + } ); + + if ( 0 == this.model.get( 'attrs' ).length && ( ! innerContent || typeof innerContent == 'undefined' ) ) { + var messageView = new Backbone.View({ + tagName: 'div', + className: 'notice updated', + }); + messageView.render = function() { + this.$el.append( '

' ); + this.$el.find('p').text( shortcodeUIData.strings.media_frame_no_attributes_message ); + return this; + }; + t.views.add( '.edit-shortcode-form-fields', messageView ); + } + + }, + +}); + +module.exports = EditShortcodeForm; + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"./../utils/sui.js":13,"./edit-attribute-field-attachment.js":14,"./edit-attribute-field-post-select.js":15,"./edit-attribute-field.js":16}]},{},[1,2,3,4,5]); diff --git a/js/build/shortcode-ui.js b/js/build/shortcode-ui.js index 970a335b..cc2cddf2 100644 --- a/js/build/shortcode-ui.js +++ b/js/build/shortcode-ui.js @@ -89,7 +89,7 @@ sui.controllers.MediaController = MediaController; module.exports = MediaController; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./../collections/shortcodes.js":2,"./../utils/sui.js":9}],4:[function(require,module,exports){ +},{"./../collections/shortcodes.js":2,"./../utils/sui.js":10}],4:[function(require,module,exports){ (function (global){ var Backbone = (typeof window !== "undefined" ? window.Backbone : typeof global !== "undefined" ? global.Backbone : null); @@ -264,11 +264,27 @@ $(document).ready(function(){ }); }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./collections/shortcodes.js":2,"./utils/shortcode-view-constructor.js":8,"./utils/sui.js":9,"./views/media-frame.js":16}],8:[function(require,module,exports){ +},{"./collections/shortcodes.js":2,"./utils/shortcode-view-constructor.js":9,"./utils/sui.js":10,"./views/media-frame.js":18}],8:[function(require,module,exports){ +var getEditView = function ( id ) { + + var views = { + 'default': require('./../views/edit-shortcode-form.js'), + 'shortcake_dev': require('./../views/edit-shortcode-form-test.js'), + } + + return ( id in views ) ? views[ id ] : views['default']; + +} + +module.exports = getEditView; + +},{"./../views/edit-shortcode-form-test.js":14,"./../views/edit-shortcode-form.js":15}],9:[function(require,module,exports){ (function (global){ var sui = require('./sui.js'), wp = (typeof window !== "undefined" ? window.wp : typeof global !== "undefined" ? global.wp : null), - $ = (typeof window !== "undefined" ? window.jQuery : typeof global !== "undefined" ? global.jQuery : null); + $ = (typeof window !== "undefined" ? window.jQuery : typeof global !== "undefined" ? global.jQuery : null), + getEditView = require('./get-edit-view.js'); + // send_to_editor = require( 'sui-utils/sendtoeditor'); /** * Generic shortcode mce view constructor. @@ -278,7 +294,7 @@ var shortcodeViewConstructor = { initialize: function( options ) { this.shortcodeModel = this.getShortcodeModel( this.shortcode ); - this.fetch(); + this.renderPreview(); }, /** @@ -325,34 +341,20 @@ var shortcodeViewConstructor = { * * @return undefined */ - fetch : function() { + renderPreview : function() { - var self = this; + var view; - if ( ! this.fetching ) { + var shortcode = this.shortcodeModel; + view = getEditView( shortcode.get('shortcode_tag') ); + view = new view( { model: shortcode } ); - this.fetching = true; + this.content = view.render().$el; + this.render( null, true ); - wp.ajax.post( 'do_shortcode', { - post_id: $( '#post_ID' ).val(), - shortcode: this.shortcodeModel.formatShortcode(), - nonce: shortcodeUIData.nonces.preview, - }).done( function( response ) { - - if ( '' === response ) { - self.content = '' + self.shortcodeModel.formatShortcode() + ''; - } else { - self.content = response; - } - - }).fail( function() { - self.content = '' + shortcodeUIData.strings.mce_view_error + ''; - } ).always( function() { - delete self.fetching; - self.render( null, true ); - } ); - - } + shortcode.on('change', function() { + console.log( shortcode.formatShortcode() ); + } ); }, @@ -467,122 +469,7 @@ var shortcodeViewConstructor = { if ( switchEditors && switchEditors.pre_wpautop ) { content = switchEditors.pre_wpautop( content ); } - return content; - - }, - - // Backwards compatability for Pre WP 4.2. - View: { - - overlay: true, - - initialize: function( options ) { - this.shortcode = this.getShortcode( options ); - this.fetch(); - }, - - getShortcode: function( options ) { - - var shortcodeModel, shortcode; - - shortcodeModel = sui.shortcodes.findWhere( { shortcode_tag: options.shortcode.tag } ); - - if (!shortcodeModel) { - return; - } - - shortcode = shortcodeModel.clone(); - - shortcode.get('attrs').each( - function(attr) { - - if (attr.get('attr') in options.shortcode.attrs.named) { - attr.set('value', - options.shortcode.attrs.named[attr - .get('attr')]); - } - - }); - - if ('content' in options.shortcode) { - var inner_content = shortcode.get('inner_content'); - if ( inner_content ) { - inner_content.set('value', options.shortcode.content) - } - } - - return shortcode; - - }, - - fetch : function() { - - var self = this; - - if ( ! this.parsed ) { - - wp.ajax.post( 'do_shortcode', { - post_id: $( '#post_ID' ).val(), - shortcode: this.shortcode.formatShortcode(), - nonce: shortcodeUIData.nonces.preview, - }).done( function( response ) { - if ( response.indexOf( ''; - self.render( true ); - } ); - - } - - }, - - /** - * Render the shortcode - * - * To ensure consistent rendering - this makes an ajax request to the - * admin and displays. - * - * @return string html - */ - getHtml : function() { - return this.parsed; - }, - - /** - * Returns an array of tags for stylesheets applied to the TinyMCE editor. - * - * @method getEditorStyles - * @returns {Array} - */ - getEditorStyles: function() { - - var styles = ''; - - this.getNodes( function ( editor, node, content ) { - var dom = editor.dom, - bodyClasses = editor.getBody().className || '', - iframe, iframeDoc, i, resize; - - tinymce.each( dom.$( 'link[rel="stylesheet"]', editor.getDoc().head ), function( link ) { - if ( link.href && link.href.indexOf( 'skins/lightgray/content.min.css' ) === -1 && - link.href.indexOf( 'skins/wordpress/wp-content.css' ) === -1 ) { - - styles += dom.getOuterHTML( link ) + '\n'; - } - - }); - - } ); - - return styles; - }, - }, }; @@ -590,7 +477,7 @@ var shortcodeViewConstructor = { module.exports = shortcodeViewConstructor; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./sui.js":9}],9:[function(require,module,exports){ +},{"./get-edit-view.js":8,"./sui.js":10}],10:[function(require,module,exports){ var Shortcodes = require('./../collections/shortcodes.js'); window.Shortcode_UI = window.Shortcode_UI || { @@ -601,7 +488,7 @@ window.Shortcode_UI = window.Shortcode_UI || { module.exports = window.Shortcode_UI; -},{"./../collections/shortcodes.js":2}],10:[function(require,module,exports){ +},{"./../collections/shortcodes.js":2}],11:[function(require,module,exports){ var sui = require('./../utils/sui.js'); var editAttributeFieldAttachment = sui.views.editAttributeField.extend( { @@ -789,7 +676,7 @@ var editAttributeFieldAttachment = sui.views.editAttributeField.extend( { module.exports = sui.views.editAttributeFieldAttachment = editAttributeFieldAttachment; -},{"./../utils/sui.js":9}],11:[function(require,module,exports){ +},{"./../utils/sui.js":10}],12:[function(require,module,exports){ ( function( $ ) { var sui = window.Shortcode_UI; @@ -995,7 +882,7 @@ module.exports = sui.views.editAttributeFieldAttachment = editAttributeFieldAtta } )( jQuery ); -},{}],12:[function(require,module,exports){ +},{}],13:[function(require,module,exports){ (function (global){ var Backbone = (typeof window !== "undefined" ? window.Backbone : typeof global !== "undefined" ? global.Backbone : null), sui = require('./../utils/sui.js'), @@ -1135,7 +1022,77 @@ sui.views.editAttributeField = editAttributeField; module.exports = editAttributeField; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./../utils/sui.js":9}],13:[function(require,module,exports){ +},{"./../utils/sui.js":10}],14:[function(require,module,exports){ +(function (global){ +var wp = (typeof window !== "undefined" ? window.wp : typeof global !== "undefined" ? global.wp : null), + sui = require('./../utils/sui.js'), + backbone = (typeof window !== "undefined" ? window.Backbone : typeof global !== "undefined" ? global.Backbone : null), + EditAttributeField = require('./edit-attribute-field.js'), + EditShortcodeForm = require('./edit-shortcode-form.js'), + $ = (typeof window !== "undefined" ? window.jQuery : typeof global !== "undefined" ? global.jQuery : null); + +/** + * Single edit shortcode content view. + */ +var EditShortcodeFormTest = EditShortcodeForm.extend({ + + template: wp.template( 'shortcode-ui-test-inline-edit' ), + + events: { + 'keyup input[type="text"]': 'inputChanged', + 'keyup textarea': 'inputChanged', + 'keyup [contenteditable]': 'inputChanged', + 'change select': 'inputChanged', + 'change input[type=checkbox]': 'inputChanged', + 'change input[type=radio]': 'inputChanged', + 'change input[type=email]': 'inputChanged', + 'change input[type=number]': 'inputChanged', + 'change input[type=date]': 'inputChanged', + 'change input[type=url]': 'inputChanged', + }, + + initialize: function() {}, + + render: function() { + console.log( this.model.toJSON() ); + + this.$el.html( this.template( this.model.toJSON() ) ); + return this; + }, + + inputChanged: _.debounce( function(e) { + + var val, attr, targetAttr; + + attr = e.target.getAttribute( 'name' ); + + if ( e.target.hasAttribute( 'contenteditable' ) ) { + val = $(e.target).html(); + } else { + val = e.target.value; + } + + if ( 'content' === attr ) { + targetAttr = this.model.get( 'inner_content' ); + } else { + targetAttr = this.model.get( 'attrs' ).findWhere( { attr: attr } ); + } + + if ( targetAttr ) { + targetAttr.set( 'value', val ); + this.model.trigger('change'); + this.model.trigger('changed'); + } + + + }, 250 ), + +}); + +module.exports = EditShortcodeFormTest; + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"./../utils/sui.js":10,"./edit-attribute-field.js":13,"./edit-shortcode-form.js":15}],15:[function(require,module,exports){ (function (global){ var wp = (typeof window !== "undefined" ? window.wp : typeof global !== "undefined" ? global.wp : null), sui = require('./../utils/sui.js'), @@ -1218,7 +1175,7 @@ var EditShortcodeForm = wp.Backbone.View.extend({ module.exports = EditShortcodeForm; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./../utils/sui.js":9,"./edit-attribute-field-attachment.js":10,"./edit-attribute-field-post-select.js":11,"./edit-attribute-field.js":12}],14:[function(require,module,exports){ +},{"./../utils/sui.js":10,"./edit-attribute-field-attachment.js":11,"./edit-attribute-field-post-select.js":12,"./edit-attribute-field.js":13}],16:[function(require,module,exports){ (function (global){ var wp = (typeof window !== "undefined" ? window.wp : typeof global !== "undefined" ? global.wp : null); @@ -1252,7 +1209,7 @@ var insertShortcodeListItem = wp.Backbone.View.extend({ module.exports = insertShortcodeListItem; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],15:[function(require,module,exports){ +},{}],17:[function(require,module,exports){ (function (global){ var wp = (typeof window !== "undefined" ? window.wp : typeof global !== "undefined" ? global.wp : null); var Backbone = (typeof window !== "undefined" ? window.Backbone : typeof global !== "undefined" ? global.Backbone : null); @@ -1298,7 +1255,7 @@ var insertShortcodeList = wp.Backbone.View.extend({ module.exports = insertShortcodeList; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./../collections/shortcodes.js":2,"./insert-shortcode-list-item.js":14}],16:[function(require,module,exports){ +},{"./../collections/shortcodes.js":2,"./insert-shortcode-list-item.js":16}],18:[function(require,module,exports){ (function (global){ var wp = (typeof window !== "undefined" ? window.wp : typeof global !== "undefined" ? global.wp : null), $ = (typeof window !== "undefined" ? window.jQuery : typeof global !== "undefined" ? global.jQuery : null), @@ -1425,7 +1382,7 @@ var mediaFrame = postMediaFrame.extend( { module.exports = mediaFrame; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./../controllers/media-controller.js":3,"./media-toolbar":17,"./shortcode-ui":20}],17:[function(require,module,exports){ +},{"./../controllers/media-controller.js":3,"./media-toolbar":19,"./shortcode-ui":22}],19:[function(require,module,exports){ (function (global){ var wp = (typeof window !== "undefined" ? window.wp : typeof global !== "undefined" ? global.wp : null); @@ -1457,7 +1414,7 @@ var Toolbar = wp.media.view.Toolbar.extend({ module.exports = Toolbar; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],18:[function(require,module,exports){ +},{}],20:[function(require,module,exports){ (function (global){ var wp = (typeof window !== "undefined" ? window.wp : typeof global !== "undefined" ? global.wp : null); sui = require('./../utils/sui.js'); @@ -1504,7 +1461,7 @@ var SearchShortcode = wp.media.view.Search.extend({ sui.views.SearchShortcode = SearchShortcode; module.exports = SearchShortcode; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./../utils/sui.js":9}],19:[function(require,module,exports){ +},{"./../utils/sui.js":10}],21:[function(require,module,exports){ (function (global){ var Backbone = (typeof window !== "undefined" ? window.Backbone : typeof global !== "undefined" ? global.Backbone : null), $ = (typeof window !== "undefined" ? window.jQuery : typeof global !== "undefined" ? global.jQuery : null); @@ -1692,13 +1649,13 @@ var ShortcodePreview = Backbone.View.extend({ module.exports = ShortcodePreview; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],20:[function(require,module,exports){ +},{}],22:[function(require,module,exports){ (function (global){ var Backbone = (typeof window !== "undefined" ? window.Backbone : typeof global !== "undefined" ? global.Backbone : null), insertShortcodeList = require('./insert-shortcode-list.js'), TabbedView = require('./tabbed-view.js'), ShortcodePreview = require('./shortcode-preview.js'), - EditShortcodeForm = require('./edit-shortcode-form.js'), + getEditView = require('./../utils/get-edit-view.js'), Toolbar = require('./media-toolbar.js'), SearchShortcode = require('./search-shortcode.js'), sui = require('./../utils/sui.js'), @@ -1760,11 +1717,13 @@ var Shortcode_UI = Backbone.View.extend({ renderEditShortcodeView: function() { var shortcode = this.controller.props.get( 'currentShortcode' ); + var editView = getEditView( shortcode.get( 'shortcode_tag' ) ); var view = new TabbedView({ tabs: { + edit: { label: shortcodeUIData.strings.edit_tab_label, - content: new EditShortcodeForm({ model: shortcode }) + content: new editView({ model: shortcode }) }, preview: { @@ -1774,6 +1733,7 @@ var Shortcode_UI = Backbone.View.extend({ this.render(); } } + }, styles: { @@ -1820,7 +1780,7 @@ var Shortcode_UI = Backbone.View.extend({ module.exports = Shortcode_UI; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./../utils/sui.js":9,"./edit-shortcode-form.js":13,"./insert-shortcode-list.js":15,"./media-toolbar.js":17,"./search-shortcode.js":18,"./shortcode-preview.js":19,"./tabbed-view.js":21}],21:[function(require,module,exports){ +},{"./../utils/get-edit-view.js":8,"./../utils/sui.js":10,"./insert-shortcode-list.js":17,"./media-toolbar.js":19,"./search-shortcode.js":20,"./shortcode-preview.js":21,"./tabbed-view.js":23}],23:[function(require,module,exports){ (function (global){ var Backbone = (typeof window !== "undefined" ? window.Backbone : typeof global !== "undefined" ? global.Backbone : null); var sui = require('./../utils/sui.js'); @@ -1946,4 +1906,4 @@ sui.views.TabbedView = TabbedView; module.exports = TabbedView; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./../utils/sui.js":9}]},{},[7]); +},{"./../utils/sui.js":10}]},{},[7]); diff --git a/js/src/utils/get-edit-view.js b/js/src/utils/get-edit-view.js new file mode 100644 index 00000000..11262f15 --- /dev/null +++ b/js/src/utils/get-edit-view.js @@ -0,0 +1,12 @@ +var getEditView = function ( id ) { + + var views = { + 'default': require('sui-views/edit-shortcode-form'), + 'shortcake_dev': require( 'sui-views/edit-shortcode-form-test' ), + } + + return ( id in views ) ? views[ id ] : views['default']; + +} + +module.exports = getEditView; diff --git a/js/src/utils/sendtoeditor.js b/js/src/utils/sendtoeditor.js new file mode 100644 index 00000000..d4e2b14b --- /dev/null +++ b/js/src/utils/sendtoeditor.js @@ -0,0 +1,32 @@ +send_to_editor = function( html ) { + + var editor, + hasTinymce = typeof tinymce !== 'undefined', + hasQuicktags = typeof QTags !== 'undefined'; + + if ( ! wpActiveEditor ) { + if ( hasTinymce && tinymce.activeEditor ) { + editor = tinymce.activeEditor; + wpActiveEditor = editor.id; + } else if ( ! hasQuicktags ) { + return false; + } + } else if ( hasTinymce ) { + editor = tinymce.get( wpActiveEditor ); + } + + if ( editor && ! editor.isHidden() ) { + editor.execCommand( 'mceInsertContent', false, html ); + } else if ( hasQuicktags ) { + QTags.insertContent( html ); + } else { + document.getElementById( wpActiveEditor ).value += html; + } + + // If the old thickbox remove function exists, call it + if ( window.tb_remove ) { + try { window.tb_remove(); } catch( e ) {} + } +}; + +module.exports = send_to_editor; diff --git a/js/src/utils/shortcode-view-constructor.js b/js/src/utils/shortcode-view-constructor.js index 6876d486..2291770e 100644 --- a/js/src/utils/shortcode-view-constructor.js +++ b/js/src/utils/shortcode-view-constructor.js @@ -1,6 +1,8 @@ var sui = require('sui-utils/sui'), wp = require('wp'), - $ = require('jquery'); + $ = require('jquery'), + getEditView = require( 'sui-utils/get-edit-view'); + // send_to_editor = require( 'sui-utils/sendtoeditor'); /** * Generic shortcode mce view constructor. @@ -10,7 +12,7 @@ var shortcodeViewConstructor = { initialize: function( options ) { this.shortcodeModel = this.getShortcodeModel( this.shortcode ); - this.fetch(); + this.renderPreview(); }, /** @@ -57,34 +59,20 @@ var shortcodeViewConstructor = { * * @return undefined */ - fetch : function() { + renderPreview : function() { - var self = this; + var view; - if ( ! this.fetching ) { + var shortcode = this.shortcodeModel; + view = getEditView( shortcode.get('shortcode_tag') ); + view = new view( { model: shortcode } ); - this.fetching = true; + this.content = view.render().$el; + this.render( null, true ); - wp.ajax.post( 'do_shortcode', { - post_id: $( '#post_ID' ).val(), - shortcode: this.shortcodeModel.formatShortcode(), - nonce: shortcodeUIData.nonces.preview, - }).done( function( response ) { - - if ( '' === response ) { - self.content = '' + self.shortcodeModel.formatShortcode() + ''; - } else { - self.content = response; - } - - }).fail( function() { - self.content = '' + shortcodeUIData.strings.mce_view_error + ''; - } ).always( function() { - delete self.fetching; - self.render( null, true ); - } ); - - } + shortcode.on('change', function() { + console.log( shortcode.formatShortcode() ); + } ); }, @@ -199,122 +187,7 @@ var shortcodeViewConstructor = { if ( switchEditors && switchEditors.pre_wpautop ) { content = switchEditors.pre_wpautop( content ); } - return content; - - }, - - // Backwards compatability for Pre WP 4.2. - View: { - - overlay: true, - - initialize: function( options ) { - this.shortcode = this.getShortcode( options ); - this.fetch(); - }, - - getShortcode: function( options ) { - - var shortcodeModel, shortcode; - - shortcodeModel = sui.shortcodes.findWhere( { shortcode_tag: options.shortcode.tag } ); - - if (!shortcodeModel) { - return; - } - - shortcode = shortcodeModel.clone(); - - shortcode.get('attrs').each( - function(attr) { - - if (attr.get('attr') in options.shortcode.attrs.named) { - attr.set('value', - options.shortcode.attrs.named[attr - .get('attr')]); - } - - }); - - if ('content' in options.shortcode) { - var inner_content = shortcode.get('inner_content'); - if ( inner_content ) { - inner_content.set('value', options.shortcode.content) - } - } - - return shortcode; - - }, - - fetch : function() { - - var self = this; - - if ( ! this.parsed ) { - - wp.ajax.post( 'do_shortcode', { - post_id: $( '#post_ID' ).val(), - shortcode: this.shortcode.formatShortcode(), - nonce: shortcodeUIData.nonces.preview, - }).done( function( response ) { - if ( response.indexOf( ''; - self.render( true ); - } ); - - } - - }, - - /** - * Render the shortcode - * - * To ensure consistent rendering - this makes an ajax request to the - * admin and displays. - * - * @return string html - */ - getHtml : function() { - return this.parsed; - }, - - /** - * Returns an array of tags for stylesheets applied to the TinyMCE editor. - * - * @method getEditorStyles - * @returns {Array} - */ - getEditorStyles: function() { - - var styles = ''; - - this.getNodes( function ( editor, node, content ) { - var dom = editor.dom, - bodyClasses = editor.getBody().className || '', - iframe, iframeDoc, i, resize; - - tinymce.each( dom.$( 'link[rel="stylesheet"]', editor.getDoc().head ), function( link ) { - if ( link.href && link.href.indexOf( 'skins/lightgray/content.min.css' ) === -1 && - link.href.indexOf( 'skins/wordpress/wp-content.css' ) === -1 ) { - - styles += dom.getOuterHTML( link ) + '\n'; - } - - }); - - } ); - - return styles; - }, - }, }; diff --git a/js/src/views/edit-shortcode-form-test.js b/js/src/views/edit-shortcode-form-test.js new file mode 100644 index 00000000..b1d578ca --- /dev/null +++ b/js/src/views/edit-shortcode-form-test.js @@ -0,0 +1,66 @@ +var wp = require('wp'), + sui = require('sui-utils/sui'), + backbone = require('backbone'), + EditAttributeField = require( 'sui-views/edit-attribute-field' ), + EditShortcodeForm = require( 'sui-views/edit-shortcode-form' ), + $ = require( 'jquery' ); + +/** + * Single edit shortcode content view. + */ +var EditShortcodeFormTest = EditShortcodeForm.extend({ + + template: wp.template( 'shortcode-ui-test-inline-edit' ), + + events: { + 'keyup input[type="text"]': 'inputChanged', + 'keyup textarea': 'inputChanged', + 'keyup [contenteditable]': 'inputChanged', + 'change select': 'inputChanged', + 'change input[type=checkbox]': 'inputChanged', + 'change input[type=radio]': 'inputChanged', + 'change input[type=email]': 'inputChanged', + 'change input[type=number]': 'inputChanged', + 'change input[type=date]': 'inputChanged', + 'change input[type=url]': 'inputChanged', + }, + + initialize: function() {}, + + render: function() { + console.log( this.model.toJSON() ); + + this.$el.html( this.template( this.model.toJSON() ) ); + return this; + }, + + inputChanged: _.debounce( function(e) { + + var val, attr, targetAttr; + + attr = e.target.getAttribute( 'name' ); + + if ( e.target.hasAttribute( 'contenteditable' ) ) { + val = $(e.target).html(); + } else { + val = e.target.value; + } + + if ( 'content' === attr ) { + targetAttr = this.model.get( 'inner_content' ); + } else { + targetAttr = this.model.get( 'attrs' ).findWhere( { attr: attr } ); + } + + if ( targetAttr ) { + targetAttr.set( 'value', val ); + this.model.trigger('change'); + this.model.trigger('changed'); + } + + + }, 250 ), + +}); + +module.exports = EditShortcodeFormTest; diff --git a/js/src/views/shortcode-ui.js b/js/src/views/shortcode-ui.js index 4f980724..8069695c 100644 --- a/js/src/views/shortcode-ui.js +++ b/js/src/views/shortcode-ui.js @@ -2,7 +2,7 @@ var Backbone = require('backbone'), insertShortcodeList = require('sui-views/insert-shortcode-list'), TabbedView = require('sui-views/tabbed-view'), ShortcodePreview = require('sui-views/shortcode-preview'), - EditShortcodeForm = require('sui-views/edit-shortcode-form'), + getEditView = require( 'sui-utils/get-edit-view'), Toolbar = require('sui-views/media-toolbar'), SearchShortcode = require('sui-views/search-shortcode'), sui = require('sui-utils/sui'), @@ -64,11 +64,13 @@ var Shortcode_UI = Backbone.View.extend({ renderEditShortcodeView: function() { var shortcode = this.controller.props.get( 'currentShortcode' ); + var editView = getEditView( shortcode.get( 'shortcode_tag' ) ); var view = new TabbedView({ tabs: { + edit: { label: shortcodeUIData.strings.edit_tab_label, - content: new EditShortcodeForm({ model: shortcode }) + content: new editView({ model: shortcode }) }, preview: { @@ -78,6 +80,7 @@ var Shortcode_UI = Backbone.View.extend({ this.render(); } } + }, styles: {