diff --git a/README.md b/README.md index 4ea4735c5..4ffdf2eb8 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,6 @@ Stay tuned for updates, tips and tutorials: [Blog](http://cloudinary.com/blog), ## License ####################################################################### -Released under the MIT license. +Released under the GPL license. diff --git a/assets/banner-772x250.jpg b/assets/banner-772x250.jpg deleted file mode 100644 index d997bf257..000000000 Binary files a/assets/banner-772x250.jpg and /dev/null differ diff --git a/assets/banner-772x250.png b/assets/banner-772x250.png new file mode 100644 index 000000000..7f937958f Binary files /dev/null and b/assets/banner-772x250.png differ diff --git a/assets/icon-128x128.png b/assets/icon-128x128.png index 789340aac..b077639f9 100644 Binary files a/assets/icon-128x128.png and b/assets/icon-128x128.png differ diff --git a/assets/icon-256x256.png b/assets/icon-256x256.png index 913a7106a..e92c918e5 100644 Binary files a/assets/icon-256x256.png and b/assets/icon-256x256.png differ diff --git a/assets/screenshot-1.jpg b/assets/screenshot-1.jpg deleted file mode 100644 index d41a275d1..000000000 Binary files a/assets/screenshot-1.jpg and /dev/null differ diff --git a/assets/screenshot-1.png b/assets/screenshot-1.png new file mode 100644 index 000000000..f0626f437 Binary files /dev/null and b/assets/screenshot-1.png differ diff --git a/assets/screenshot-2.jpg b/assets/screenshot-2.jpg deleted file mode 100644 index d5da1dc1b..000000000 Binary files a/assets/screenshot-2.jpg and /dev/null differ diff --git a/assets/screenshot-2.png b/assets/screenshot-2.png new file mode 100644 index 000000000..5ae2bba59 Binary files /dev/null and b/assets/screenshot-2.png differ diff --git a/assets/screenshot-3.jpg b/assets/screenshot-3.jpg deleted file mode 100644 index b90f45398..000000000 Binary files a/assets/screenshot-3.jpg and /dev/null differ diff --git a/assets/screenshot-3.png b/assets/screenshot-3.png new file mode 100644 index 000000000..ad3190050 Binary files /dev/null and b/assets/screenshot-3.png differ diff --git a/assets/screenshot-4.jpg b/assets/screenshot-4.jpg deleted file mode 100644 index 877f41cc0..000000000 Binary files a/assets/screenshot-4.jpg and /dev/null differ diff --git a/assets/screenshot-4.png b/assets/screenshot-4.png new file mode 100644 index 000000000..4d66c57a0 Binary files /dev/null and b/assets/screenshot-4.png differ diff --git a/assets/screenshot-5.jpg b/assets/screenshot-5.jpg deleted file mode 100644 index cf0998778..000000000 Binary files a/assets/screenshot-5.jpg and /dev/null differ diff --git a/assets/screenshot-5.png b/assets/screenshot-5.png new file mode 100644 index 000000000..6671fe927 Binary files /dev/null and b/assets/screenshot-5.png differ diff --git a/assets/screenshot-6.jpg b/assets/screenshot-6.jpg deleted file mode 100644 index 06c49dd6d..000000000 Binary files a/assets/screenshot-6.jpg and /dev/null differ diff --git a/assets/screenshot-6.png b/assets/screenshot-6.png new file mode 100644 index 000000000..f5c5205d8 Binary files /dev/null and b/assets/screenshot-6.png differ diff --git a/assets/screenshot-7.png b/assets/screenshot-7.png new file mode 100644 index 000000000..31523862c Binary files /dev/null and b/assets/screenshot-7.png differ diff --git a/assets/screenshot-8.png b/assets/screenshot-8.png new file mode 100644 index 000000000..c59713136 Binary files /dev/null and b/assets/screenshot-8.png differ diff --git a/assets/screenshot-9.png b/assets/screenshot-9.png new file mode 100644 index 000000000..f8ac1c137 Binary files /dev/null and b/assets/screenshot-9.png differ diff --git a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/js/block-editor.js b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/js/block-editor.js index 482503df0..38488de8c 100644 --- a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/js/block-editor.js +++ b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/js/block-editor.js @@ -1 +1 @@ -!function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=6)}([function(e,t){!function(){e.exports=this.wp.element}()},function(e,t){!function(){e.exports=this.wp.i18n}()},function(e,t){!function(){e.exports=this.wp.components}()},function(e,t,r){var n=r(5);e.exports=function(e){for(var t=1;t {\n\tconst {attributes: {overwrite_transformations, transformations}, setAttributes} = props;\n\t\n\tif ( ! transformations ) {\n\t\treturn null;\n }\n \n\treturn (\n\t\t\n\t\t\t {\n\t\t\t\t\tsetAttributes( {overwrite_transformations: value} );\n\t\t\t\t}}\n\t\t\t/>\n\t\t\n\t);\n};\n\nlet ImageInspectorControls = ( props ) => {\n\tconst {setAttributes, media} = props;\n\tconst {InspectorControls} = wp.editor;\n\t\n\tif ( media && media.transformations ) {\n\t\tsetAttributes( {transformations: true} );\n\t}\n\n\treturn (\n\t\t\n\t\t\t\n\t\t\n\t);\n};\n\nImageInspectorControls = withSelect( ( select, ownProps ) => ( {\n\t...ownProps,\n\tmedia: ownProps.attributes.id ? select( 'core' ).getMedia( ownProps.attributes.id ) : null\n} ))( ImageInspectorControls );\n\nconst cldFilterBlocksEdit = ( BlockEdit ) => {\n\treturn ( props ) => {\n\t\tconst {name} = props;\n\t\tconst shouldDisplayInspector = 'core/image' === name || 'core/video' === name;\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t{shouldDisplayInspector ? : null}\n\t\t\t\t\n\t\t\t\n\t\t);\n\t}\n};\n\nwp.hooks.addFilter( 'editor.BlockEdit', 'cloudinary/filterEdit', cldFilterBlocksEdit, 20 );\n\nconst cldfilterBlocksSave = ( element, blockType, attributes ) => {\n\tif ( 'core/image' === blockType.name && attributes.overwrite_transformations ) {\n\t\tlet children = cloneElement( element.props.children );\n\t\tlet classname = children.props.children[ 0 ].props.className ? children.props.children[ 0 ].props.className : '';\n\t\tlet child = cloneElement( children.props.children[ 0 ], {className: classname + ' cld-overwrite'} );\n\t\tlet neChildren = cloneElement( children, {children: [ child, false ]} );\n\t\treturn cloneElement( element, {children: neChildren} );\n\t}\n\n\tif ( 'core/video' === blockType.name && attributes.overwrite_transformations ) {\n\t\tlet children = cloneElement( element.props.children[ 0 ], {className: ' cld-overwrite'} );\n\t\treturn cloneElement( element, {children} );\n\t}\n\n\treturn element;\n};\n\nwp.hooks.addFilter( 'blocks.getSaveElement', 'cloudinary/filterSave', cldfilterBlocksSave );\n","function _defineProperty(obj, key, value) {\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n\n return obj;\n}\n\nmodule.exports = _defineProperty;","var defineProperty = require(\"./defineProperty\");\n\nfunction _objectSpread(target) {\n for (var i = 1; i < arguments.length; i++) {\n var source = arguments[i] != null ? Object(arguments[i]) : {};\n var ownKeys = Object.keys(source);\n\n if (typeof Object.getOwnPropertySymbols === 'function') {\n ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) {\n return Object.getOwnPropertyDescriptor(source, sym).enumerable;\n }));\n }\n\n ownKeys.forEach(function (key) {\n defineProperty(target, key, source[key]);\n });\n }\n\n return target;\n}\n\nmodule.exports = _objectSpread;","(function() { module.exports = this[\"wp\"][\"components\"]; }());","(function() { module.exports = this[\"wp\"][\"data\"]; }());","(function() { module.exports = this[\"wp\"][\"element\"]; }());","(function() { module.exports = this[\"wp\"][\"i18n\"]; }());"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./js/src/blocks.js","webpack:///./js/src/components/video.js","webpack:///./node_modules/@babel/runtime/helpers/defineProperty.js","webpack:///./node_modules/@babel/runtime/helpers/objectSpread.js","webpack:///external {\"this\":[\"wp\",\"components\"]}","webpack:///external {\"this\":[\"wp\",\"data\"]}","webpack:///external {\"this\":[\"wp\",\"element\"]}","webpack:///external {\"this\":[\"wp\",\"i18n\"]}"],"names":["$","window","jQuery","cloudinaryBlocks","Video","_init","CLD_VIDEO_PLAYER","wp","hooks","addFilter","settings","name","video_autoplay_mode","attributes","autoplay","default","video_loop","loop","video_controls","controls","cldAddToggle","overwrite_transformations","type","transformations","TransformationsToggle","props","setAttributes","__","value","ImageInspectorControls","media","InspectorControls","editor","withSelect","select","ownProps","id","getMedia","cldFilterBlocksEdit","BlockEdit","shouldDisplayInspector"],"mappings":";QAAA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;;QAEA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;;;QAGA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;QACA,0CAA0C,gCAAgC;QAC1E;QACA;;QAEA;QACA;QACA;QACA,wDAAwD,kBAAkB;QAC1E;QACA,iDAAiD,cAAc;QAC/D;;QAEA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA,yCAAyC,iCAAiC;QAC1E,gHAAgH,mBAAmB,EAAE;QACrI;QACA;;QAEA;QACA;QACA;QACA,2BAA2B,0BAA0B,EAAE;QACvD,iCAAiC,eAAe;QAChD;QACA;QACA;;QAEA;QACA,sDAAsD,+DAA+D;;QAErH;QACA;;;QAGA;QACA;;;;;;;;;;;;;AClFA;AAAA;AAAA;AAAA;;AACA;;;AAIA;CAIA;;AACA,IAAMA,CAAC,GAAGC,MAAM,CAACD,CAAP,GAAWC,MAAM,CAACC,MAA5B,C,CAEA;;AACO,IAAMC,gBAAgB,GAAG;AAC/BC,OAAK,EAALA,yDAAKA;AAD0B,CAAzB,C;;;;;;;;;;;;;;;;;;;;;;;;;;ACbP;AAEA;AACA;AACA;AACA;AAEA,IAAMA,KAAK,GAAG;AACbC,OAAK,EAAE,iBAAW;AACjB,QAAK,OAAOC,gBAAP,KAA4B,WAAjC,EAA+C;AAC9C;AACA,KAHgB,CAKjB;;;AACAC,MAAE,CAACC,KAAH,CAASC,SAAT,CACC,0BADD,EAEC,wBAFD,EAGC,UAAUC,QAAV,EAAoBC,IAApB,EAA2B;AAC1B,UAAKA,IAAI,KAAK,YAAd,EAA6B;AAC5B,YAAK,UAAUL,gBAAgB,CAACM,mBAAhC,EAAsD;AACrDF,kBAAQ,CAACG,UAAT,CAAoBC,QAApB,CAA6BC,OAA7B,GAAuC,IAAvC;AACA;;AAED,YAAK,SAAST,gBAAgB,CAACU,UAA/B,EAA4C;AAC3CN,kBAAQ,CAACG,UAAT,CAAoBI,IAApB,CAAyBF,OAAzB,GAAmC,IAAnC;AACA;;AAED,YAAK,UAAUT,gBAAgB,CAACY,cAAhC,EAAiD;AAChDR,kBAAQ,CAACG,UAAT,CAAoBM,QAApB,CAA6BJ,OAA7B,GAAuC,KAAvC;AACA;AACD;;AACD,aAAOL,QAAP;AACA,KAlBF;AAoBA;AA3BY,CAAd;AA8BeN,oEAAf,E,CAEA;;AACAA,KAAK,CAACC,KAAN;;AAEA,IAAIe,YAAY,GAAG,SAAfA,YAAe,CAAUV,QAAV,EAAoBC,IAApB,EAA2B;AAE7C,MAAK,iBAAiBA,IAAjB,IAAyB,iBAAiBA,IAA/C,EAAsD;AACrD,QAAK,CAACD,QAAQ,CAACG,UAAf,EAA4B;AAC3BH,cAAQ,CAACG,UAAT,GAAsB,EAAtB;AACA;;AAEDH,YAAQ,CAACG,UAAT,CAAoBQ,yBAApB,GAAgD;AAC/CC,UAAI,EAAE;AADyC,KAAhD;AAIAZ,YAAQ,CAACG,UAAT,CAAoBU,eAApB,GAAsC;AACrCD,UAAI,EAAE;AAD+B,KAAtC;AAIA;;AAED,SAAOZ,QAAP;AACA,CAlBD;;AAoBAH,EAAE,CAACC,KAAH,CAASC,SAAT,CAAoB,0BAApB,EAAgD,0BAAhD,EAA4EW,YAA5E;AAEA;;;;;;;;AAOA,IAAMI,qBAAqB,GAAG,SAAxBA,qBAAwB,CAAEC,KAAF,EAAa;AAAA,0BACwCA,KADxC,CACnCZ,UADmC;AAAA,MACtBQ,yBADsB,qBACtBA,yBADsB;AAAA,MACKE,eADL,qBACKA,eADL;AAAA,MACuBG,aADvB,GACwCD,KADxC,CACuBC,aADvB;AAG1C,SACC,yEAAC,+DAAD;AAAW,SAAK,EAAEC,0DAAE,CAAE,iBAAF,EAAqB,YAArB;AAApB,KACC,yEAAC,mEAAD;AACC,SAAK,EAAEA,0DAAE,CAAE,2BAAF,EAA+B,YAA/B,CADV;AAEC,WAAO,EAAEN,yBAFV;AAGC,YAAQ,EAAE,kBAAEO,KAAF,EAAa;AACtBF,mBAAa,CAAE;AAACL,iCAAyB,EAAEO;AAA5B,OAAF,CAAb;AACA;AALF,IADD,CADD;AAWA,CAdD;;AAgBA,IAAIC,sBAAsB,GAAG,gCAAEJ,KAAF,EAAa;AAAA,MAClCC,aADkC,GACVD,KADU,CAClCC,aADkC;AAAA,MACnBI,KADmB,GACVL,KADU,CACnBK,KADmB;AAAA,MAElCC,iBAFkC,GAEbxB,EAAE,CAACyB,MAFU,CAElCD,iBAFkC;;AAIzC,MAAKD,KAAK,IAAIA,KAAK,CAACP,eAApB,EAAsC;AACrCG,iBAAa,CAAE;AAACH,qBAAe,EAAE;AAAlB,KAAF,CAAb;AACA;;AAED,SACC,yEAAC,iBAAD,QACC,yEAAC,qBAAD,EAA2BE,KAA3B,CADD,CADD;AAKA,CAbD;;AAeAI,sBAAsB,GAAGI,kEAAU,CAAE,UAAEC,MAAF,EAAUC,QAAV;AAAA,wFACjCA,QADiC;AAEpCL,SAAK,EAAEK,QAAQ,CAACtB,UAAT,CAAoBuB,EAApB,GAAyBF,MAAM,CAAE,MAAF,CAAN,CAAiBG,QAAjB,CAA2BF,QAAQ,CAACtB,UAAT,CAAoBuB,EAA/C,CAAzB,GAA+E;AAFlD;AAAA,CAAF,CAAV,CAGnBP,sBAHmB,CAAzB;;AAKA,IAAMS,mBAAmB,GAAG,SAAtBA,mBAAsB,CAAEC,SAAF,EAAiB;AAC5C,SAAO,UAAEd,KAAF,EAAa;AAAA,QACZd,IADY,GACJc,KADI,CACZd,IADY;AAEnB,QAAM6B,sBAAsB,GAAG,iBAAiB7B,IAAjB,IAAyB,iBAAiBA,IAAzE;AAEA,WACC,4IACE6B,sBAAsB,GAAG,yEAAC,sBAAD,EAA4Bf,KAA5B,CAAH,GAA2C,IADnE,EAEC,yEAAC,SAAD,EAAeA,KAAf,CAFD,CADD;AAMA,GAVD;AAWA,CAZD;;AAcAlB,EAAE,CAACC,KAAH,CAASC,SAAT,CAAoB,kBAApB,EAAwC,uBAAxC,EAAiE6B,mBAAjE,EAAsF,EAAtF,E;;;;;;;;;;;ACzHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,GAAG;AACH;AACA;;AAEA;AACA;;AAEA,iC;;;;;;;;;;;ACfA,qBAAqB,mBAAO,CAAC,iFAAkB;;AAE/C;AACA,iBAAiB,sBAAsB;AACvC;AACA;;AAEA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA,KAAK;AACL;;AAEA;AACA;;AAEA,+B;;;;;;;;;;;ACrBA,aAAa,2CAA2C,EAAE,I;;;;;;;;;;;ACA1D,aAAa,qCAAqC,EAAE,I;;;;;;;;;;;ACApD,aAAa,wCAAwC,EAAE,I;;;;;;;;;;;ACAvD,aAAa,qCAAqC,EAAE,I","file":"block-editor.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = \"./js/src/blocks.js\");\n","/* global window */\n/**\n * Main JS.\n */\n\n// Components\nimport Video from './components/video';\n\n\n// jQuery, because reasons.\nconst $ = window.$ = window.jQuery;\n\n// Global Constants\nexport const cloudinaryBlocks = {\n\tVideo\n};\n\n","/* global window wp */\n\nimport { __ } from '@wordpress/i18n';\nimport { withSelect } from '@wordpress/data';\nimport { cloneElement } from '@wordpress/element';\nimport { ToggleControl, PanelBody } from '@wordpress/components';\n\nconst Video = {\n\t_init: function() {\n\t\tif ( typeof CLD_VIDEO_PLAYER === 'undefined' ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Gutenberg Video Settings\n\t\twp.hooks.addFilter(\n\t\t\t'blocks.registerBlockType',\n\t\t\t'Cloudinary/Media/Video',\n\t\t\tfunction( settings, name ) {\n\t\t\t\tif ( name === 'core/video' ) {\n\t\t\t\t\tif ( 'off' !== CLD_VIDEO_PLAYER.video_autoplay_mode ) {\n\t\t\t\t\t\tsettings.attributes.autoplay.default = true;\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( 'on' === CLD_VIDEO_PLAYER.video_loop ) {\n\t\t\t\t\t\tsettings.attributes.loop.default = true;\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( 'off' === CLD_VIDEO_PLAYER.video_controls ) {\n\t\t\t\t\t\tsettings.attributes.controls.default = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn settings;\n\t\t\t}\n\t\t);\n\t},\n};\n\nexport default Video;\n\n// Init.\nVideo._init();\n\nlet cldAddToggle = function( settings, name ) {\n\n\tif ( 'core/image' === name || 'core/video' === name ) {\n\t\tif ( !settings.attributes ) {\n\t\t\tsettings.attributes = {};\n\t\t}\n\n\t\tsettings.attributes.overwrite_transformations = {\n\t\t\ttype: 'boolean',\n\t\t};\n\n\t\tsettings.attributes.transformations = {\n\t\t\ttype: 'boolean',\n\t\t};\n\n\t}\n\n\treturn settings;\n};\n\nwp.hooks.addFilter( 'blocks.registerBlockType', 'cloudinary/addAttributes', cldAddToggle );\n\n/**\n * Get AMP Lightbox toggle control.\n *\n * @param {Object} props Props.\n *\n * @return {Component} Element.\n */\nconst TransformationsToggle = ( props ) => {\n\tconst {attributes: {overwrite_transformations, transformations}, setAttributes} = props;\n\n\treturn (\n\t\t\n\t\t\t {\n\t\t\t\t\tsetAttributes( {overwrite_transformations: value} );\n\t\t\t\t}}\n\t\t\t/>\n\t\t\n\t);\n};\n\nlet ImageInspectorControls = ( props ) => {\n\tconst {setAttributes, media} = props;\n\tconst {InspectorControls} = wp.editor;\n\n\tif ( media && media.transformations ) {\n\t\tsetAttributes( {transformations: true} );\n\t}\n\n\treturn (\n\t\t\n\t\t\t\n\t\t\n\t);\n};\n\nImageInspectorControls = withSelect( ( select, ownProps ) => ( {\n\t...ownProps,\n\tmedia: ownProps.attributes.id ? select( 'core' ).getMedia( ownProps.attributes.id ) : null\n} ))( ImageInspectorControls );\n\nconst cldFilterBlocksEdit = ( BlockEdit ) => {\n\treturn ( props ) => {\n\t\tconst {name} = props;\n\t\tconst shouldDisplayInspector = 'core/image' === name || 'core/video' === name;\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t{shouldDisplayInspector ? : null}\n\t\t\t\t\n\t\t\t\n\t\t);\n\t}\n};\n\nwp.hooks.addFilter( 'editor.BlockEdit', 'cloudinary/filterEdit', cldFilterBlocksEdit, 20 );\n","function _defineProperty(obj, key, value) {\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n\n return obj;\n}\n\nmodule.exports = _defineProperty;","var defineProperty = require(\"./defineProperty\");\n\nfunction _objectSpread(target) {\n for (var i = 1; i < arguments.length; i++) {\n var source = arguments[i] != null ? Object(arguments[i]) : {};\n var ownKeys = Object.keys(source);\n\n if (typeof Object.getOwnPropertySymbols === 'function') {\n ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) {\n return Object.getOwnPropertyDescriptor(source, sym).enumerable;\n }));\n }\n\n ownKeys.forEach(function (key) {\n defineProperty(target, key, source[key]);\n });\n }\n\n return target;\n}\n\nmodule.exports = _objectSpread;","(function() { module.exports = this[\"wp\"][\"components\"]; }());","(function() { module.exports = this[\"wp\"][\"data\"]; }());","(function() { module.exports = this[\"wp\"][\"element\"]; }());","(function() { module.exports = this[\"wp\"][\"i18n\"]; }());"],"sourceRoot":""} \ No newline at end of file diff --git a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/js/cloudinary.js b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/js/cloudinary.js index b23ec088c..e12099400 100644 --- a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/js/cloudinary.js +++ b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/js/cloudinary.js @@ -1 +1 @@ -!function(e){var t={};function i(n){if(t[n])return t[n].exports;var s=t[n]={i:n,l:!1,exports:{}};return e[n].call(s.exports,s,s.exports,i),s.l=!0,s.exports}i.m=e,i.c=t,i.d=function(e,t,n){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(i.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var s in e)i.d(n,s,function(t){return e[t]}.bind(null,s));return n},i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="",i(i.s=3)}([function(e,t){window,jQuery,jQuery(document).ready((function(e){e(document).on("tabs.init",(function(){var t=e(".settings-tab-trigger"),i=e(".settings-tab-section");e(this).on("click",".settings-tab-trigger",(function(n){var s=e(this),a=e(s.attr("href"));n.preventDefault(),t.removeClass("active"),i.removeClass("active"),s.addClass("active"),a.addClass("active"),e(document).trigger("settings.tabbed",s)})),e(".cld-field").not('[data-condition="false"]').each((function(){const t=e(this),i=t.data("condition");for(let n in i){const s=i[n],a=e("#field-"+n),o=t.closest("tr");a.on("change init",(function(){this.value===s||this.checked?o.show():o.hide()})),a.trigger("init")}})),e("#field-cloudinary_url").on("input change",(function(){let t=e(this),i=t.val();new RegExp(/^(cloudinary:\/\/){1}(\d)*[:]{1}[^:@]*[@]{1}[^@]*$/g).test(i)?(t.addClass("settings-valid-field"),t.removeClass("settings-invalid-field")):(t.removeClass("settings-valid-field"),t.addClass("settings-invalid-field"))})).trigger("change")})),e(".render-trigger[data-event]").each((function(){var t=e(this),i=t.data("event");t.trigger(i,this)}))}))},function(e,t){if(wp.media&&window.CLDN){wp.media.events.on("editor:image-edit",(function(e){e.metadata.cldoverwrite=null,e.image.className.split(" ").indexOf("cld-overwrite")>=0&&(e.metadata.cldoverwrite="true")})),wp.media.events.on("editor:image-update",(function(e){let t=e.image.className.split(" ");e.metadata.cldoverwrite&&-1===t.indexOf("cld-overwrite")?t.push("cld-overwrite"):!e.metadata.cldoverwrite&&t.indexOf("cld-overwrite")>=0&&delete t[t.indexOf("cld-overwrite")],e.image.className=t.join(" ")}));let e=null,t=wp.media.string.props;wp.media.string.props=function(i,n){return i.cldoverwrite&&(i.classes=["cld-overwrite"],e=!0),t(i,n)},wp.media.post=function(t,i){if("send-attachment-to-editor"===t){let t=wp.media.editor.get().state().get("selection").get(i.attachment);t.attributes.transformations&&(i.attachment.transformations=t.attributes.transformations),(i.html.indexOf("cld-overwrite")>-1||!0===e)&&(i.attachment.cldoverwrite=!0,e=null)}return wp.ajax.post(t,i)};wp.media.controller.Library;let i=wp.media.view.MediaFrame.Select,n=wp.media.view.MediaFrame.Post,s=wp.media.view.MediaFrame.ImageDetails,a=wp.media.view.MediaFrame.VideoDetails,o=wp.media.View.extend({tagName:"div",className:"cloudinary-widget",template:wp.template("cloudinary-dam"),active:!1,toolbar:null,frame:null,ready:function(){let e=this.controller,t=this.model.get("selection"),i=this.model.get("library"),n=wp.media.model.Attachment;if(CLDN.mloptions.multiple=e.options.multiple,this.cid!==this.active){if(CLDN.mloptions.inline_container="#cloudinary-dam-"+e.cid,1===t.length){var s=n.get(t.models[0].id);void 0!==s.attributes.public_id&&(CLDN.mloptions.asset={resource_id:s.attributes.public_id})}else CLDN.mloptions.asset=null;window.ml=cloudinary.openMediaLibrary(CLDN.mloptions,{insertHandler:function(s){for(let a=0;a=100&&void 0!==e.started?(this.submitButton.style.display=this.hide,this.stopButton.style.display=this.show):e.pending>0?(this.submitButton.style.display=this.show,this.stopButton.style.display=this.hide):e.processing>0?this.stopButton.style.display=this.show:this.stopButton.style.display=this.hide,e.percent<100?(this.barSyncCount.innerText=e.total,this.progressCount.innerText=e.done,this.progress.style.display=this.show):(this.completed.style.display=this.show,this.progress.style.display=this.hide)},_start:function(e){e.preventDefault(),a.stopButton.style.display=a.show,a.submitButton.style.display=a.hide,a.pushAttachments()},_reset:function(e){a.submitButton.style.display=a.hide,a.getStatus()},_init:function(e){"undefined"!=typeof cloudinaryApi&&((document.attachEvent?"complete"===document.readyState:"loading"!==document.readyState)?e():document.addEventListener("DOMContentLoaded",e))}};var o=a;a._init((function(){a._reset(),a.submitButton.addEventListener("click",a._start),a.stopButton.addEventListener("click",a.stopSync)}));var r=i(1),l=i.n(r);const d={sample:{image:document.getElementById("transformation-sample-image"),video:document.getElementById("transformation-sample-video")},preview:{image:document.getElementById("sample-image"),video:document.getElementById("sample-video")},fields:document.getElementsByClassName("cld-field"),button:{image:document.getElementById("refresh-image-preview"),video:document.getElementById("refresh-video-preview")},spinner:{image:document.getElementById("image-loader"),video:document.getElementById("video-loader")},activeItem:null,elements:{image:[],video:[]},_placeItem:function(e){null!==e&&(e.style.display="block",e.style.visibility="visible",e.style.position="absolute",e.style.top=e.parentElement.clientHeight/2-e.clientHeight/2+"px",e.style.left=e.parentElement.clientWidth/2-e.clientWidth/2+"px")},_setLoading:function(e){this.button[e].style.display="block",this._placeItem(this.button[e]),this.preview[e].style.opacity="0.1"},_build:function(e){this.sample[e].innerHTML="",this.elements[e]=[];for(let t of this.fields){if(e!==t.dataset.context)continue;let i=t.value.trim();if(i.length){if("select-one"===t.type){if("none"===i)continue;i=t.dataset.meta+"_"+i}else{let e=t.dataset.context;i=this._transformations(i,e,!0)}i&&this.elements[e].push(i)}}let t="";this.elements[e].length&&(t="/"+this.elements[e].join(",").replace(/ /g,"%20")),this.sample[e].textContent=t,this.sample[e].parentElement.href="https://res.cloudinary.com/demo/"+this.sample[e].parentElement.innerText.trim().replace("../","").replace(/ /g,"%20")},_clearLoading:function(e){this.spinner[e].style.visibility="hidden",this.activeItem=null,this.preview[e].style.opacity=1},_refresh:function(e,t){e&&e.preventDefault();let i=this,n=CLD_GLOBAL_TRANSFORMATIONS[t].preview_url+i.elements[t].join(",")+CLD_GLOBAL_TRANSFORMATIONS[t].file;if(this.button[t].style.display="none",this._placeItem(this.spinner[t]),"image"===t){let e=new Image;e.onload=function(){i.preview[t].src=this.src,i._clearLoading(t),e.remove()},e.onerror=function(){alert(CLD_GLOBAL_TRANSFORMATIONS[t].error),i._clearLoading(t)},e.src=n}else{let e=i._transformations(i.elements[t].join(","),t);samplePlayer.source({publicId:"dog",transformation:e}),i._clearLoading(t)}},_transformations:function(e,t,i=!1){let n=CLD_GLOBAL_TRANSFORMATIONS[t].valid_types,s=null,a=e.split("/"),o=[];for(let e=0;e{const i=t.length?t[0].id+1:1;e.startId=null===e.startId?i:++e.startId;const n=a+":"+e.startId;jQuery('[data-item="'+n+'"]').length||e._pushItem(n,s[s.length-1])})}return this.processflushTags(t,i,n)},window.tagBox.processTags=window.tagBox.parseTags,window.tagBox.parseTags=function(t){const i=t.id,n=i.split("-check-num-")[1],s=i.split("-check-num-")[0],a=jQuery(t).closest(".tagsdiv").find(".the-tags"),o=window.tagBox.clean(a.val()).split(e.tagDelimiter)[n];(new wp.api.collections.Tags).fetch({data:{slug:o}}).done(i=>{const n=!!i.length&&jQuery('[data-item="'+s+":"+i[0].id+'"]');n.length?n.remove():(jQuery(`.cld-tax-order-list-item:contains(${o})`).remove(),--e.startId),this.processTags(t)})}),jQuery("body").on("change",".selectit input",(function(){const t=jQuery(this),i=t.val(),n=t.is(":checked"),s=t.parent().text().trim();!0===n?e._pushItem(`category:${i}`,s):e.tags.find(`[data-item="category:${i}"]`).remove()}))},_createItem:function(e,t){const i=jQuery("
  • "),n=jQuery(""),s=jQuery("");return i.addClass("cld-tax-order-list-item").attr("data-item",e),s.addClass("cld-tax-order-list-item-input").attr("type","hidden").attr("name","cld_tax_order[]").val(e),n.addClass("dashicons dashicons-menu cld-tax-order-list-item-handle"),i.append(n).append(t).append(s),i},_pushItem:function(e,t){let i=this._createItem(e,t);this.tags.append(i)},_sortable:function(){jQuery(".cld-tax-order-list").sortable({connectWith:".cld-tax-order",axis:"y",handle:".cld-tax-order-list-item-handle",placeholder:"cld-tax-order-list-item-placeholder",forcePlaceholderSize:!0,helper:"clone"})}};if(void 0!==window.CLDN&&u._init(),wp.data&&wp.data.select("core/editor")){const e={};wp.data.subscribe((function(){let t=wp.data.select("core").getTaxonomies();if(t)for(let i in t){const n=wp.data.select("core/editor").getEditedPostAttribute(t[i].rest_base);e[t[i].slug]=n}}));const t=wp.element.createElement,i=i=>{class n extends i{constructor(e){super(e),this.currentItems=jQuery(".cld-tax-order-list-item").map((e,t)=>jQuery(t).data("item")).get()}makeItem(e){if(this.currentItems.includes(this.getId(e)))return;const t=this.makeElement(e);jQuery("#cld-tax-items").append(t)}removeItem(e){const t=jQuery(`[data-item="${this.getId(e)}"]`);t.length&&(t.remove(),this.currentItems=this.currentItems.filter(t=>t!==this.getId(e)))}findOrCreateTerm(e){return(e=super.findOrCreateTerm(e)).then(e=>this.makeItem(e)),e}onChange(t){super.onChange(t);const i=this.pickItem(t);i&&(e[this.props.slug].includes(i.id)?this.makeItem(i):this.removeItem(i))}pickItem(e){if("object"==typeof e){if(e.target){for(let t in this.state.availableTerms)if(this.state.availableTerms[t].id===parseInt(e.target.value))return this.state.availableTerms[t]}else if(Array.isArray(e)){let t=this.state.selectedTerms.filter(t=>!e.includes(t))[0];return void 0===t&&(t=e.filter(e=>!this.state.selectedTerms.includes(e))[0]),this.state.availableTerms.find(e=>e.name===t)}}else if("number"==typeof e){for(let t in this.state.availableTerms)if(this.state.availableTerms[t].id===e)return this.state.availableTerms[t]}else{let t;if(e.length>this.state.selectedTerms.length)for(let i in e)-1===this.state.selectedTerms.indexOf(e[i])&&(t=e[i]);else for(let i in this.state.selectedTerms)-1===e.indexOf(this.state.selectedTerms[i])&&(t=this.state.selectedTerms[i]);for(let e in this.state.availableTerms)if(this.state.availableTerms[e].name===t)return this.state.availableTerms[e]}}getId(e){return`${this.props.slug}:${e.id}`}makeElement(e){const t=jQuery("
  • "),i=jQuery(""),n=jQuery("");return t.addClass("cld-tax-order-list-item").attr("data-item",this.getId(e)),n.addClass("cld-tax-order-list-item-input").attr("type","hidden").attr("name","cld_tax_order[]").val(this.getId(e)),i.addClass("dashicons dashicons-menu cld-tax-order-list-item-handle"),t.append(i).append(e.name).append(n),t}}return e=>t(n,e)};wp.hooks.addFilter("editor.PostTaxonomyType","cld",i)}const p={wpWrap:document.getElementById("wpwrap"),wpContent:document.getElementById("wpbody-content"),libraryWrap:document.getElementById("cloudinary-embed"),_init:function(){let e=this;"undefined"!=typeof CLD_ML&&(cloudinary.openMediaLibrary(CLD_ML.mloptions,{insertHandler:function(e){alert("Import is not yet implemented.")}}),window.addEventListener("resize",(function(t){e._resize()})),e._resize())},_resize:function(){let e=getComputedStyle(this.wpContent);this.libraryWrap.style.height=this.wpWrap.offsetHeight-parseInt(e.getPropertyValue("padding-bottom"))+"px"}};var m=p;p._init();i(2);i.d(t,"cloudinary",(function(){return h}));window.$=window.jQuery;const h={settings:s.a,sync:o,widget:l.a,Global_Transformations:c,Terms_Order:void 0,Media_Library:m}}]); \ No newline at end of file +!function(e){var t={};function i(n){if(t[n])return t[n].exports;var s=t[n]={i:n,l:!1,exports:{}};return e[n].call(s.exports,s,s.exports,i),s.l=!0,s.exports}i.m=e,i.c=t,i.d=function(e,t,n){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(i.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var s in e)i.d(n,s,function(t){return e[t]}.bind(null,s));return n},i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="",i(i.s=3)}([function(e,t){window,jQuery,jQuery(document).ready((function(e){e(document).on("tabs.init",(function(){var t=e(".settings-tab-trigger"),i=e(".settings-tab-section");e(this).on("click",".settings-tab-trigger",(function(n){var s=e(this),a=e(s.attr("href"));n.preventDefault(),t.removeClass("active"),i.removeClass("active"),s.addClass("active"),a.addClass("active"),e(document).trigger("settings.tabbed",s)})),e(".cld-field").not('[data-condition="false"]').each((function(){const t=e(this),i=t.data("condition");for(let n in i){const s=i[n],a=e("#field-"+n),r=t.closest("tr");a.on("change init",(function(){this.value===s||this.checked?r.show():r.hide()})),a.trigger("init")}})),e("#field-cloudinary_url").on("input change",(function(){let t=e(this),i=t.val();new RegExp(/^(cloudinary:\/\/){1}(\d)*[:]{1}[^:@]*[@]{1}[^@]*$/g).test(i)?(t.addClass("settings-valid-field"),t.removeClass("settings-invalid-field")):(t.removeClass("settings-valid-field"),t.addClass("settings-invalid-field"))})).trigger("change")})),e(".render-trigger[data-event]").each((function(){var t=e(this),i=t.data("event");t.trigger(i,this)}))}))},function(e,t){if(wp.media&&window.CLDN){wp.media.events.on("editor:image-edit",(function(e){e.metadata.cldoverwrite=null,e.image.className.split(" ").indexOf("cld-overwrite")>=0&&(e.metadata.cldoverwrite="true")})),wp.media.events.on("editor:image-update",(function(e){let t=e.image.className.split(" ");e.metadata.cldoverwrite&&-1===t.indexOf("cld-overwrite")?t.push("cld-overwrite"):!e.metadata.cldoverwrite&&t.indexOf("cld-overwrite")>=0&&delete t[t.indexOf("cld-overwrite")],e.image.className=t.join(" ")}));let e=null,t=wp.media.string.props;wp.media.string.props=function(i,n){return i.cldoverwrite&&(i.classes=["cld-overwrite"],e=!0),t(i,n)},wp.media.post=function(t,i){if("send-attachment-to-editor"===t){let t=wp.media.editor.get().state().get("selection").get(i.attachment);t.attributes.transformations&&(i.attachment.transformations=t.attributes.transformations),(i.html.indexOf("cld-overwrite")>-1||!0===e)&&(i.attachment.cldoverwrite=!0,e=null)}return wp.ajax.post(t,i)};wp.media.controller.Library;let i=wp.media.view.MediaFrame.Select,n=wp.media.view.MediaFrame.Post,s=wp.media.view.MediaFrame.ImageDetails,a=wp.media.view.MediaFrame.VideoDetails,r=wp.media.View.extend({tagName:"div",className:"cloudinary-widget",template:wp.template("cloudinary-dam"),active:!1,toolbar:null,frame:null,ready:function(){let e=this.controller,t=this.model.get("selection"),i=this.model.get("library"),n=wp.media.model.Attachment;if(CLDN.mloptions.multiple=e.options.multiple,this.cid!==this.active){if(CLDN.mloptions.inline_container="#cloudinary-dam-"+e.cid,1===t.length){var s=n.get(t.models[0].id);void 0!==s.attributes.public_id&&(CLDN.mloptions.asset={resource_id:s.attributes.public_id})}else CLDN.mloptions.asset=null;window.ml=cloudinary.openMediaLibrary(CLDN.mloptions,{insertHandler:function(s){for(let a=0;a=100&&void 0!==e.started?(this.submitButton.style.display=this.hide,this.stopButton.style.display=this.show):e.pending>0?(this.submitButton.style.display=this.show,this.stopButton.style.display=this.hide):e.processing>0?this.stopButton.style.display=this.show:this.stopButton.style.display=this.hide,e.percent<100?(this.barSyncCount.innerText=e.total,this.progressCount.innerText=e.done,this.progress.style.display=this.show):(this.completed.style.display=this.show,this.progress.style.display=this.hide)},_start:function(e){e.preventDefault(),a.stopButton.style.display=a.show,a.submitButton.style.display=a.hide,a.pushAttachments()},_reset:function(e){a.submitButton.style.display=a.hide,a.getStatus()},_init:function(e){"undefined"!=typeof cloudinaryApi&&((document.attachEvent?"complete"===document.readyState:"loading"!==document.readyState)?e():document.addEventListener("DOMContentLoaded",e))}};var r=a;a._init((function(){a._reset(),a.submitButton.addEventListener("click",a._start),a.stopButton.addEventListener("click",a.stopSync)}));var o=i(1),l=i.n(o);const d={sample:{image:document.getElementById("transformation-sample-image"),video:document.getElementById("transformation-sample-video")},preview:{image:document.getElementById("sample-image"),video:document.getElementById("sample-video")},fields:document.getElementsByClassName("cld-field"),button:{image:document.getElementById("refresh-image-preview"),video:document.getElementById("refresh-video-preview")},spinner:{image:document.getElementById("image-loader"),video:document.getElementById("video-loader")},activeItem:null,elements:{image:[],video:[]},_placeItem:function(e){null!==e&&(e.style.display="block",e.style.visibility="visible",e.style.position="absolute",e.style.top=e.parentElement.clientHeight/2-e.clientHeight/2+"px",e.style.left=e.parentElement.clientWidth/2-e.clientWidth/2+"px")},_setLoading:function(e){this.button[e].style.display="block",this._placeItem(this.button[e]),this.preview[e].style.opacity="0.1"},_build:function(e){this.sample[e].innerHTML="",this.elements[e]=[];for(let t of this.fields){if(e!==t.dataset.context)continue;let i=t.value.trim();if(i.length){if("select-one"===t.type){if("none"===i)continue;i=t.dataset.meta+"_"+i}else{let e=t.dataset.context;i=this._transformations(i,e,!0)}i&&this.elements[e].push(i)}}let t="";this.elements[e].length&&(t="/"+this.elements[e].join(",").replace(/ /g,"%20")),this.sample[e].textContent=t,this.sample[e].parentElement.href="https://res.cloudinary.com/demo/"+this.sample[e].parentElement.innerText.trim().replace("../","").replace(/ /g,"%20")},_clearLoading:function(e){this.spinner[e].style.visibility="hidden",this.activeItem=null,this.preview[e].style.opacity=1},_refresh:function(e,t){e&&e.preventDefault();let i=this,n=CLD_GLOBAL_TRANSFORMATIONS[t].preview_url+i.elements[t].join(",")+CLD_GLOBAL_TRANSFORMATIONS[t].file;if(this.button[t].style.display="none",this._placeItem(this.spinner[t]),"image"===t){let e=new Image;e.onload=function(){i.preview[t].src=this.src,i._clearLoading(t),e.remove()},e.onerror=function(){alert(CLD_GLOBAL_TRANSFORMATIONS[t].error),i._clearLoading(t)},e.src=n}else{let e=i._transformations(i.elements[t].join(","),t);samplePlayer.source({publicId:"dog",transformation:e}),i._clearLoading(t)}},_transformations:function(e,t,i=!1){let n=CLD_GLOBAL_TRANSFORMATIONS[t].valid_types,s=null,a=e.split("/"),r=[];for(let e=0;e{const n=!!i.length&&jQuery('[data-item="'+s+":"+i[0].id+'"]');n.length?n.remove():(jQuery(`.cld-tax-order-list-item:contains(${r})`).remove(),--e.startId),this.processTags(t)})}),jQuery("body").on("change",".selectit input",(function(){const t=jQuery(this),i=t.val(),n=t.is(":checked"),s=t.parent().text().trim();!0===n?e.tags.find(`[data-item="category:${i}"]`).length||e._pushItem(`category:${i}`,s):e.tags.find(`[data-item="category:${i}"]`).remove()}))},_createItem:function(e,t){const i=jQuery("
  • "),n=jQuery(""),s=jQuery("");return i.addClass("cld-tax-order-list-item").attr("data-item",e),s.addClass("cld-tax-order-list-item-input").attr("type","hidden").attr("name","cld_tax_order[]").val(e),n.addClass("dashicons dashicons-menu cld-tax-order-list-item-handle"),i.append(n).append(t).append(s),i},_pushItem:function(e,t){let i=this._createItem(e,t);this.tags.append(i)},_sortable:function(){jQuery(".cld-tax-order-list").sortable({connectWith:".cld-tax-order",axis:"y",handle:".cld-tax-order-list-item-handle",placeholder:"cld-tax-order-list-item-placeholder",forcePlaceholderSize:!0,helper:"clone"})}};if(void 0!==window.CLDN&&(u._init(),jQuery("[data-wp-lists] .selectit input[checked]").map((e,t)=>{jQuery(t).trigger("change")})),wp.data&&wp.data.select("core/editor")){const e={};wp.data.subscribe((function(){let t=wp.data.select("core").getTaxonomies();if(t)for(let i in t){const n=wp.data.select("core/editor").getEditedPostAttribute(t[i].rest_base);e[t[i].slug]=n}}));const t=wp.element.createElement,i=i=>{class n extends i{constructor(e){super(e),this.currentItems=jQuery(".cld-tax-order-list-item").map((e,t)=>jQuery(t).data("item")).get()}makeItem(e){if(this.currentItems.includes(this.getId(e)))return;const t=this.makeElement(e);jQuery("#cld-tax-items").append(t)}removeItem(e){const t=jQuery(`[data-item="${this.getId(e)}"]`);t.length&&(t.remove(),this.currentItems=this.currentItems.filter(t=>t!==this.getId(e)))}findOrCreateTerm(e){return(e=super.findOrCreateTerm(e)).then(e=>this.makeItem(e)),e}onChange(t){super.onChange(t);const i=this.pickItem(t);i&&(e[this.props.slug].includes(i.id)?this.makeItem(i):this.removeItem(i))}pickItem(e){if("object"==typeof e){if(e.target){for(let t in this.state.availableTerms)if(this.state.availableTerms[t].id===parseInt(e.target.value))return this.state.availableTerms[t]}else if(Array.isArray(e)){let t=this.state.selectedTerms.filter(t=>!e.includes(t))[0];return void 0===t&&(t=e.filter(e=>!this.state.selectedTerms.includes(e))[0]),this.state.availableTerms.find(e=>e.name===t)}}else if("number"==typeof e){for(let t in this.state.availableTerms)if(this.state.availableTerms[t].id===e)return this.state.availableTerms[t]}else{let t;if(e.length>this.state.selectedTerms.length)for(let i in e)-1===this.state.selectedTerms.indexOf(e[i])&&(t=e[i]);else for(let i in this.state.selectedTerms)-1===e.indexOf(this.state.selectedTerms[i])&&(t=this.state.selectedTerms[i]);for(let e in this.state.availableTerms)if(this.state.availableTerms[e].name===t)return this.state.availableTerms[e]}}getId(e){return`${this.props.slug}:${e.id}`}makeElement(e){const t=jQuery("
  • "),i=jQuery(""),n=jQuery("");return t.addClass("cld-tax-order-list-item").attr("data-item",this.getId(e)),n.addClass("cld-tax-order-list-item-input").attr("type","hidden").attr("name","cld_tax_order[]").val(this.getId(e)),i.addClass("dashicons dashicons-menu cld-tax-order-list-item-handle"),t.append(i).append(e.name).append(n),t}}return e=>t(n,e)};wp.hooks.addFilter("editor.PostTaxonomyType","cld",i)}var p=u;const m={wpWrap:document.getElementById("wpwrap"),wpContent:document.getElementById("wpbody-content"),libraryWrap:document.getElementById("cloudinary-embed"),_init:function(){let e=this;"undefined"!=typeof CLD_ML&&(cloudinary.openMediaLibrary(CLD_ML.mloptions,{insertHandler:function(e){alert("Import is not yet implemented.")}}),window.addEventListener("resize",(function(t){e._resize()})),e._resize())},_resize:function(){let e=getComputedStyle(this.wpContent);this.libraryWrap.style.height=this.wpWrap.offsetHeight-parseInt(e.getPropertyValue("padding-bottom"))+"px"}};var h=m;m._init();i(2);i.d(t,"cloudinary",(function(){return f}));window.$=window.jQuery;const f={settings:s.a,sync:r,widget:l.a,Global_Transformations:c,Terms_Order:p,Media_Library:h}}]); \ No newline at end of file diff --git a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/js/src/components/global-transformations.js b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/js/src/components/global-transformations.js index ba9a6fd8c..f5daab657 100644 --- a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/js/src/components/global-transformations.js +++ b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/js/src/components/global-transformations.js @@ -219,7 +219,7 @@ const Global_Transformations = { }, }; -export default Global_Transformations; - // Init. Global_Transformations._init(); + +export default Global_Transformations; diff --git a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/js/src/components/terms_order.js b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/js/src/components/terms_order.js index cef9ea6a8..7c543bab0 100644 --- a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/js/src/components/terms_order.js +++ b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/js/src/components/terms_order.js @@ -1,295 +1,310 @@ /* global window wp wpAjax */ -export const Terms_Order = { - template: '', - tags: jQuery( '#cld-tax-items' ), - tagDelimiter: (window.tagsSuggestL10n && window.tagsSuggestL10n.tagDelimiter) || ',', - startId: null, - _init: function() { - // Check that we found the tax-items. - if ( ! this.tags.length ) { - return; - } - - const self = this; - this._sortable(); - - // Setup ajax overrides. - if ( typeof wpAjax !== 'undefined' ) { - wpAjax.procesParseAjaxResponse = wpAjax.parseAjaxResponse; - wpAjax.parseAjaxResponse = function( response, settingsResponse, element ) { - let newResponse = wpAjax.procesParseAjaxResponse( response, settingsResponse, element ); - if ( !newResponse.errors && newResponse.responses[ 0 ] ) { - if ( jQuery( '[data-taxonomy="' + newResponse.responses[ 0 ].what + '"]' ).length ) { - const data = jQuery( newResponse.responses[ 0 ].data ); - const text = data.find( 'label' ).last().text().trim(); - - self._pushItem( newResponse.responses[ 0 ].what, text ); - } - } - - return newResponse; - }; - } - - if ( typeof window.tagBox !== 'undefined' ) { - window.tagBox.processflushTags = window.tagBox.flushTags; - window.tagBox.flushTags = function( el, a, f ) { - if ( typeof f === 'undefined' ) { - let text, list; - const taxonomy = el.prop( 'id' ); - const newTag = jQuery( 'input.newtag', el ); - - a = a || false; - - text = a ? jQuery( a ).text() : newTag.val(); - list = window.tagBox.clean( text ).split( self.tagDelimiter ); - - new wp.api.collections.Tags() - .fetch( { data: { orderby: 'id', order: 'desc', per_page: 1 } } ) - .done( tags => { - const nextTagId = tags.length ? tags[0].id + 1 : 1 - self.startId = self.startId === null ? nextTagId : ++self.startId; - const tag = taxonomy + ':' + self.startId; - - if ( ! jQuery( '[data-item="' + tag + '"]' ).length ) { - self._pushItem( tag, list[ list.length - 1 ] ); - } - } ); - } - - return this.processflushTags( el, a, f ); - }; - - window.tagBox.processTags = window.tagBox.parseTags; - - window.tagBox.parseTags = function( el ) { - const id = el.id; - const num = id.split( '-check-num-' )[ 1 ]; - const taxonomy = id.split( '-check-num-' )[ 0 ]; - const taxBox = jQuery( el ).closest( '.tagsdiv' ); - const tagsTextarea = taxBox.find( '.the-tags' ); - const tagToRemove = window.tagBox.clean( tagsTextarea.val() ).split( self.tagDelimiter )[ num ]; - - new wp.api.collections.Tags() - .fetch( { data: { slug: tagToRemove } } ) - .done( ( tag ) => { - const tagFromDatabase = tag.length ? jQuery( '[data-item="' + taxonomy + ':' + tag[0].id + '"]' ) : false; - - if ( tagFromDatabase.length ) { - tagFromDatabase.remove(); - } else { - jQuery( `.cld-tax-order-list-item:contains(${tagToRemove})` ).remove(); - --self.startId; - } - - this.processTags( el ); - } ); - }; - } - - jQuery( 'body' ).on( 'change', '.selectit input', function() { - const clickedItem = jQuery( this ); - const id = clickedItem.val(); - const checked = clickedItem.is( ':checked' ); - const text = clickedItem.parent().text().trim(); - - if ( true === checked ) { - self._pushItem( `category:${id}`, text ); - } else { - self.tags.find( `[data-item="category:${id}"]` ).remove(); - } - } ); - }, - _createItem: function( id, name ) { - const li = jQuery( '
  • ' ); - const icon = jQuery( '' ); - const input = jQuery( '' ); - - li.addClass( 'cld-tax-order-list-item' ).attr( 'data-item', id ); - input.addClass( 'cld-tax-order-list-item-input' ).attr( 'type', 'hidden' ).attr( 'name', 'cld_tax_order[]' ).val( id ); - icon.addClass( 'dashicons dashicons-menu cld-tax-order-list-item-handle' ); - - li.append( icon ).append( name ).append( input ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append - - return li; - }, - _pushItem: function( id, text ) { - let item = this._createItem( id, text ); - this.tags.append( item ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append - }, - _sortable: function() { - const items = jQuery( '.cld-tax-order-list' ); - - items.sortable( { - connectWith: '.cld-tax-order', - axis: 'y', - handle: '.cld-tax-order-list-item-handle', - placeholder: 'cld-tax-order-list-item-placeholder', - forcePlaceholderSize: true, - helper: 'clone', - } ); - } +const Terms_Order = { + template: '', + tags: jQuery( '#cld-tax-items' ), + tagDelimiter: ( window.tagsSuggestL10n && window.tagsSuggestL10n.tagDelimiter ) || ',', + startId: null, + _init: function() { + // Check that we found the tax-items. + if ( !this.tags.length ) { + return; + } + + const self = this; + this._sortable(); + + // Setup ajax overrides. + if ( typeof wpAjax !== 'undefined' ) { + wpAjax.procesParseAjaxResponse = wpAjax.parseAjaxResponse; + wpAjax.parseAjaxResponse = function( response, settingsResponse, element ) { + let newResponse = wpAjax.procesParseAjaxResponse( response, settingsResponse, element ); + if ( !newResponse.errors && newResponse.responses[ 0 ] ) { + if ( jQuery( '[data-taxonomy="' + newResponse.responses[ 0 ].what + '"]' ).length ) { + const data = jQuery( newResponse.responses[ 0 ].data ); + const text = data.find( 'label' ).last().text().trim(); + self._pushItem( newResponse.responses[ 0 ].what, text ); + } + } + + return newResponse; + }; + } + + if ( typeof window.tagBox !== 'undefined' ) { + window.tagBox.processflushTags = window.tagBox.flushTags; + window.tagBox.flushTags = function( el, a, f ) { + if ( typeof f === 'undefined' ) { + let text, list; + const taxonomy = el.prop( 'id' ); + const newTag = jQuery( 'input.newtag', el ); + + a = a || false; + + text = a ? jQuery( a ).text() : newTag.val(); + list = window.tagBox.clean( text ).split( self.tagDelimiter ); + for ( var i in list ) { + var tag = taxonomy + ':' + list[ i ]; + if ( !jQuery( '[data-item="' + tag + '"]' ).length ) { + self._pushItem( tag, list[ i ] ); + } + } + } + + return this.processflushTags( el, a, f ); + }; + + window.tagBox.processTags = window.tagBox.parseTags; + + window.tagBox.parseTags = function( el ) { + const id = el.id; + const num = id.split( '-check-num-' )[ 1 ]; + const taxonomy = id.split( '-check-num-' )[ 0 ]; + const taxBox = jQuery( el ).closest( '.tagsdiv' ); + const tagsTextarea = taxBox.find( '.the-tags' ); + const tagToRemove = window.tagBox.clean( tagsTextarea.val() ).split( self.tagDelimiter )[ num ]; + + new wp.api.collections.Tags() + .fetch( { data: { slug: tagToRemove } } ) + .done( ( tag ) => { + const tagFromDatabase = tag.length ? jQuery( '[data-item="' + taxonomy + ':' + tag[ 0 ].id + '"]' ) : false; + + if ( tagFromDatabase.length ) { + tagFromDatabase.remove(); + } + else { + jQuery( `.cld-tax-order-list-item:contains(${ tagToRemove })` ).remove(); + --self.startId; + } + this.processTags( el ); + } ); + }; + } + + jQuery( 'body' ).on( 'change', '.selectit input', function() { + const clickedItem = jQuery( this ); + const id = clickedItem.val(); + const checked = clickedItem.is( ':checked' ); + const text = clickedItem.parent().text().trim(); + + if ( true === checked ) { + if( ! self.tags.find(`[data-item="category:${ id }"]`).length ) { + self._pushItem( `category:${ id }`, text ); + } + } + else { + self.tags.find( `[data-item="category:${ id }"]` ).remove(); + } + } ); + }, + _createItem: function( id, name ) { + const li = jQuery( '
  • ' ); + const icon = jQuery( '' ); + const input = jQuery( '' ); + + li.addClass( 'cld-tax-order-list-item' ).attr( 'data-item', id ); + input.addClass( 'cld-tax-order-list-item-input' ).attr( 'type', 'hidden' ).attr( 'name', 'cld_tax_order[]' ).val( id ); + icon.addClass( 'dashicons dashicons-menu cld-tax-order-list-item-handle' ); + + li.append( icon ).append( name ).append( input ); // phpcs:ignore + // WordPressVIPMinimum.JS.HTMLExecutingFunctions.append + + return li; + }, + _pushItem: function( id, text ) { + let item = this._createItem( id, text ); + this.tags.append( item ); // phpcs:ignore + // WordPressVIPMinimum.JS.HTMLExecutingFunctions.append + }, + _sortable: function() { + const items = jQuery( '.cld-tax-order-list' ); + + items.sortable( { + connectWith: '.cld-tax-order', + axis: 'y', + handle: '.cld-tax-order-list-item-handle', + placeholder: 'cld-tax-order-list-item-placeholder', + forcePlaceholderSize: true, + helper: 'clone', + } ); + } }; if ( typeof window.CLDN !== 'undefined' ) { - Terms_Order._init(); + Terms_Order._init(); + // Init checked categories. + jQuery( '[data-wp-lists] .selectit input[checked]' ).map( ( ord, check ) => { + jQuery( check ).trigger( 'change' ); + } ); } // Gutenberg. if ( wp.data && wp.data.select( 'core/editor' ) ) { - const orderSet = {}; - wp.data.subscribe( function() { - let taxonomies = wp.data.select( 'core' ).getTaxonomies(); - - if ( taxonomies ) { - for ( let t in taxonomies ) { - const set = wp.data.select( 'core/editor' ).getEditedPostAttribute( taxonomies[ t ].rest_base ); - orderSet[ taxonomies[ t ].slug ] = set; - } - } - } ); - - const el = wp.element.createElement; - const CustomizeTaxonomySelector = ( OriginalComponent ) => { - class CustomHandler extends OriginalComponent { - constructor( props ) { - super(props) - - this.currentItems = jQuery( '.cld-tax-order-list-item' ) - .map( ( _, taxonomy ) => jQuery( taxonomy ).data( 'item' ) ).get(); - } - - makeItem( item ) { - // Prevent duplicates in the tax order box - if (this.currentItems.includes( this.getId( item ) ) ) { - return; - } - - const row = this.makeElement( item ); - const box = jQuery( '#cld-tax-items' ); - box.append( row ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append - } - - removeItem( item ) { - const elementWithId = jQuery( `[data-item="${this.getId( item )}"]` ); - - if ( elementWithId.length ) { - elementWithId.remove(); - - this.currentItems = this.currentItems.filter( ( taxIdentifier ) => { - return taxIdentifier !== this.getId( item ); - } ); - } - } - - findOrCreateTerm( termName ) { - termName = super.findOrCreateTerm( termName ); - termName.then( ( item ) => this.makeItem( item ) ); - - return termName; - } - - onChange( event ) { - super.onChange( event ); - const item = this.pickItem( event ); - - if ( item ) { - if ( orderSet[ this.props.slug ].includes( item.id ) ) { - this.makeItem( item ); - } else { - this.removeItem( item ); - } - } - } - - pickItem( event ) { - if ( typeof event === 'object' ) { - if ( event.target ) { - for (let p in this.state.availableTerms) { - if ( this.state.availableTerms[ p ].id === parseInt( event.target.value ) ) { - return this.state.availableTerms[ p ]; - } - } - // Tags that are already registered need to be selected separately - // as its expected that they return back with an "id" property. - } else if ( Array.isArray( event ) ) { - // Figure out the diff between the current state and the event and determine which tag is getting removed - let enteredTag = this.state.selectedTerms.filter( flatItem => !event.includes( flatItem ) )[0]; - - if ( typeof enteredTag === 'undefined' ) { - // If the above returns undefined, then we presume the user is adding, so reverse the logic to figure out the new item - enteredTag = event.filter( flatItem => !this.state.selectedTerms.includes( flatItem ) )[0]; - } - - return this.state.availableTerms.find( ( item ) => item.name === enteredTag ); - } - } else if ( typeof event === 'number' ) { - for (let p in this.state.availableTerms) { - if ( this.state.availableTerms[ p ].id === event ) { - return this.state.availableTerms[ p ]; - } - } - } else { - let text; - - // add or remove. - if ( event.length > this.state.selectedTerms.length ) { - // Added. - for (let o in event) { - if ( this.state.selectedTerms.indexOf( event[ o ] ) === -1 ) { - text = event[ o ]; - } - } - } else { - // removed. - for (let o in this.state.selectedTerms) { - if ( event.indexOf( this.state.selectedTerms[ o ] ) === -1 ) { - text = this.state.selectedTerms[ o ]; - } - } - } - - for (let p in this.state.availableTerms) { - if ( this.state.availableTerms[ p ].name === text ) { - return this.state.availableTerms[ p ]; - } - } - } - } - - getId( item ) { - return `${this.props.slug}:${item.id}` - } - - makeElement( item ) { - const li = jQuery( '
  • ' ); - const icon = jQuery( '' ); - const input = jQuery( '' ); - - li - .addClass( 'cld-tax-order-list-item' ) - .attr( 'data-item', this.getId( item ) ); - - input - .addClass( 'cld-tax-order-list-item-input' ) - .attr( 'type', 'hidden' ) - .attr( 'name', 'cld_tax_order[]' ).val( this.getId( item ) ); - - icon.addClass( 'dashicons dashicons-menu cld-tax-order-list-item-handle' ); - - li.append( icon ).append( item.name ).append( input ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append - - return li; - } - } - - return ( props ) => el( CustomHandler, props ); - }; - - wp.hooks.addFilter( - 'editor.PostTaxonomyType', - 'cld', - CustomizeTaxonomySelector - ); + const orderSet = {}; + wp.data.subscribe( function() { + let taxonomies = wp.data.select( 'core' ).getTaxonomies(); + + if ( taxonomies ) { + for ( let t in taxonomies ) { + const set = wp.data.select( 'core/editor' ).getEditedPostAttribute( taxonomies[ t ].rest_base ); + orderSet[ taxonomies[ t ].slug ] = set; + } + } + } ); + + const el = wp.element.createElement; + const CustomizeTaxonomySelector = ( OriginalComponent ) => { + class CustomHandler extends OriginalComponent { + constructor( props ) { + super( props ); + + this.currentItems = jQuery( '.cld-tax-order-list-item' ) + .map( ( _, taxonomy ) => jQuery( taxonomy ).data( 'item' ) ).get(); + } + + makeItem( item ) { + // Prevent duplicates in the tax order box + if ( this.currentItems.includes( this.getId( item ) ) ) { + return; + } + + const row = this.makeElement( item ); + const box = jQuery( '#cld-tax-items' ); + box.append( row ); // phpcs:ignore + // WordPressVIPMinimum.JS.HTMLExecutingFunctions.append + } + + removeItem( item ) { + const elementWithId = jQuery( `[data-item="${ this.getId( item ) }"]` ); + + if ( elementWithId.length ) { + elementWithId.remove(); + + this.currentItems = this.currentItems.filter( ( taxIdentifier ) => { + return taxIdentifier !== this.getId( item ); + } ); + } + } + + findOrCreateTerm( termName ) { + termName = super.findOrCreateTerm( termName ); + termName.then( ( item ) => this.makeItem( item ) ); + + return termName; + } + + onChange( event ) { + super.onChange( event ); + const item = this.pickItem( event ); + + if ( item ) { + if ( orderSet[ this.props.slug ].includes( item.id ) ) { + this.makeItem( item ); + } + else { + this.removeItem( item ); + } + } + } + + pickItem( event ) { + if ( typeof event === 'object' ) { + if ( event.target ) { + for ( let p in this.state.availableTerms ) { + if ( this.state.availableTerms[ p ].id === parseInt( event.target.value ) ) { + return this.state.availableTerms[ p ]; + } + } + // Tags that are already registered need to be selected + // separately as its expected that they return back + // with an "id" property. + } + else if ( Array.isArray( event ) ) { + // Figure out the diff between the current state and + // the event and determine which tag is getting removed + let enteredTag = this.state.selectedTerms.filter( flatItem => !event.includes( flatItem ) )[ 0 ]; + + if ( typeof enteredTag === 'undefined' ) { + // If the above returns undefined, then we presume + // the user is adding, so reverse the logic to + // figure out the new item + enteredTag = event.filter( flatItem => !this.state.selectedTerms.includes( flatItem ) )[ 0 ]; + } + + return this.state.availableTerms.find( ( item ) => item.name === enteredTag ); + } + } + else if ( typeof event === 'number' ) { + for ( let p in this.state.availableTerms ) { + if ( this.state.availableTerms[ p ].id === event ) { + return this.state.availableTerms[ p ]; + } + } + } + else { + let text; + + // add or remove. + if ( event.length > this.state.selectedTerms.length ) { + // Added. + for ( let o in event ) { + if ( this.state.selectedTerms.indexOf( event[ o ] ) === -1 ) { + text = event[ o ]; + } + } + } + else { + // removed. + for ( let o in this.state.selectedTerms ) { + if ( event.indexOf( this.state.selectedTerms[ o ] ) === -1 ) { + text = this.state.selectedTerms[ o ]; + } + } + } + + for ( let p in this.state.availableTerms ) { + if ( this.state.availableTerms[ p ].name === text ) { + return this.state.availableTerms[ p ]; + } + } + } + } + + getId( item ) { + return `${ this.props.slug }:${ item.id }`; + } + + makeElement( item ) { + const li = jQuery( '
  • ' ); + const icon = jQuery( '' ); + const input = jQuery( '' ); + + li + .addClass( 'cld-tax-order-list-item' ) + .attr( 'data-item', this.getId( item ) ); + + input + .addClass( 'cld-tax-order-list-item-input' ) + .attr( 'type', 'hidden' ) + .attr( 'name', 'cld_tax_order[]' ).val( this.getId( item ) ); + + icon.addClass( 'dashicons dashicons-menu cld-tax-order-list-item-handle' ); + + li.append( icon ).append( item.name ).append( input ); // phpcs:ignore + // WordPressVIPMinimum.JS.HTMLExecutingFunctions.append + + return li; + } + } + + return ( props ) => el( CustomHandler, props ); + }; + + wp.hooks.addFilter( + 'editor.PostTaxonomyType', + 'cld', + CustomizeTaxonomySelector + ); } + +export default Terms_Order; diff --git a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/js/src/components/video.js b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/js/src/components/video.js index 8690e1db2..5496bb742 100644 --- a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/js/src/components/video.js +++ b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/js/src/components/video.js @@ -71,11 +71,7 @@ wp.hooks.addFilter( 'blocks.registerBlockType', 'cloudinary/addAttributes', cldA */ const TransformationsToggle = ( props ) => { const {attributes: {overwrite_transformations, transformations}, setAttributes} = props; - - if ( ! transformations ) { - return null; - } - + return ( { let ImageInspectorControls = ( props ) => { const {setAttributes, media} = props; const {InspectorControls} = wp.editor; - + if ( media && media.transformations ) { setAttributes( {transformations: true} ); } @@ -124,22 +120,3 @@ const cldFilterBlocksEdit = ( BlockEdit ) => { }; wp.hooks.addFilter( 'editor.BlockEdit', 'cloudinary/filterEdit', cldFilterBlocksEdit, 20 ); - -const cldfilterBlocksSave = ( element, blockType, attributes ) => { - if ( 'core/image' === blockType.name && attributes.overwrite_transformations ) { - let children = cloneElement( element.props.children ); - let classname = children.props.children[ 0 ].props.className ? children.props.children[ 0 ].props.className : ''; - let child = cloneElement( children.props.children[ 0 ], {className: classname + ' cld-overwrite'} ); - let neChildren = cloneElement( children, {children: [ child, false ]} ); - return cloneElement( element, {children: neChildren} ); - } - - if ( 'core/video' === blockType.name && attributes.overwrite_transformations ) { - let children = cloneElement( element.props.children[ 0 ], {className: ' cld-overwrite'} ); - return cloneElement( element, {children} ); - } - - return element; -}; - -wp.hooks.addFilter( 'blocks.getSaveElement', 'cloudinary/filterSave', cldfilterBlocksSave ); diff --git a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/class-media.php b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/class-media.php index 0a9b0497d..3c654d76c 100644 --- a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/class-media.php +++ b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/class-media.php @@ -216,7 +216,7 @@ public function get_id_from_sync_key( $sync_key ) { $meta_query = array( array( - 'key' => md5( $sync_key ), + 'key' => '_' . md5( $sync_key ), 'compare' => 'EXISTS', ), ); @@ -498,7 +498,7 @@ public function apply_default_transformations( array $transformations, $type = ' $default = array(); if ( 'video' === $type ) { $default['quality'] = 'auto'; - if ( isset( $global['video_limit_bitrate'] ) ) { + if ( isset( $global['video_limit_bitrate'] ) && 'on' === $global['video_limit_bitrate'] ) { $default['bit_rate'] = $global['video_bitrate'] . 'k'; } } else { @@ -509,7 +509,7 @@ public function apply_default_transformations( array $transformations, $type = ' $default['quality'] = 'auto'; } } - $default = array_filter( $default ); // Clear out empty settings. + $default = array_filter( $default ); // Clear out empty settings. $new_transformations['qf'] = \Cloudinary\Connect\Api::generate_transformation_string( array( $default ), $type ); // Add freeform global transformations. $freeform_type = $type . '_freeform'; @@ -892,7 +892,6 @@ public function editor_assets() { 'api_key' => $this->credentials['api_key'], 'cms_type' => 'wordpress', 'remove_header' => true, - 'folder' => array( 'path' => $this->cloudinary_folder ), 'integration' => array( 'type' => 'wordpress_plugin', 'platform' => 'WordPress ' . get_bloginfo( 'version' ), @@ -901,6 +900,11 @@ public function editor_assets() { ), ); + // Set folder if needed. + if ( ! empty( $this->cloudinary_folder ) ) { + $params['mloptions']['folder'] = array( 'path' => $this->cloudinary_folder ); + } + $params['mloptions']['insert_transformation'] = true; $params['mloptions']['inline_container'] = '#cloudinary-dam'; @@ -942,7 +946,7 @@ private function create_attachment( $asset, $public_id ) { update_post_meta( $attachment_id, Sync::META_KEYS['transformation'], $asset['transformations'] ); } // create a trackable key in post meta. - update_post_meta( $attachment_id, md5( $sync_key ), true ); + update_post_meta( $attachment_id, '_' . md5( $sync_key ), true ); // record a base to ensure primary isn't deleted. update_post_meta( $attachment_id, '_' . md5( $public_id ), true ); // Capture the ALT Text. @@ -1003,7 +1007,7 @@ public function down_sync_asset() { } $transformations = $this->get_transformations_from_string( $url ); if ( ! empty( $transformations ) ) { - $sync_key .= wp_json_encode( $transformations ); + $sync_key .= wp_json_encode( $transformations ); $asset['transformations'] = $transformations; } // Check Format and url extension. @@ -1270,7 +1274,7 @@ public function setup() { $this->base_url = $this->plugin->components['connect']->api->cloudinary_url( '/' ); $this->credentials = $this->plugin->components['connect']->get_credentials(); - $this->cloudinary_folder = $this->plugin->config['settings']['sync_media']['cloudinary_folder']; + $this->cloudinary_folder = $this->plugin->config['settings']['sync_media']['cloudinary_folder'] ? $this->plugin->config['settings']['sync_media']['cloudinary_folder'] : ''; $this->filter = new Filter( $this ); $this->upgrade = new Upgrade( $this ); $this->global_transformations = new Global_Transformations( $this ); diff --git a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/class-sync.php b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/class-sync.php index a2bcd3745..6d740dcd7 100644 --- a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/class-sync.php +++ b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/class-sync.php @@ -48,6 +48,7 @@ class Sync implements Setup, Assets { 'transformation' => '_transformations', 'sync_error' => '_sync_error', 'cloudinary' => '_cloudinary_v2', + 'attempts' => '_sync_attempts', ); /** diff --git a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/media/class-filter.php b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/media/class-filter.php index 306137dc2..5c2b0890a 100644 --- a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/media/class-filter.php +++ b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/media/class-filter.php @@ -290,14 +290,19 @@ public function filter_out_local( $content ) { $assets = $this->get_media_tags( $content, 'img' ); foreach ( $assets as $asset ) { - $url = $this->get_url_from_tag( $asset ); + $url = $this->get_url_from_tag( $asset ); + $attachment_id = $this->get_id_from_tag( $asset ); // Check if this is not already a cloudinary url. if ( $this->media->is_cloudinary_url( $url ) ) { - continue; // Already a cloudinary URL. Possibly from a previous version. Will correct on post update. - } + // Is a content based ID. If has a cloudinary ID, it's from an older plugin version. + // Check if has an ID, and push update to reset. + if ( ! empty( $attachment_id ) && ! $this->media->plugin->components['sync']->is_synced( $attachment_id ) ) { + $this->media->cloudinary_id( $attachment_id ); // Start an on-demand sync. + } - $attachment_id = $this->get_id_from_tag( $asset ); + continue; // Already a cloudinary URL. Possibly from a previous version. Will correct on post update after synced. + } if ( false === $attachment_id ) { $attachment_id = $this->media->get_id_from_url( $url ); @@ -645,6 +650,27 @@ public function catch_media_templates_maybe() { } } + /** + * Filter an image block to add the class for cld-overriding. + * + * @param array $block The current block structure. + * @param array $source_block The source, unfiltered block structure. + * + * @return array + */ + public function filter_image_block_pre_render( $block, $source_block ) { + + if ( 'core/image' === $source_block['blockName'] ) { + if ( ! empty( $source_block['attrs']['overwrite_transformations'] ) ) { + foreach ( $block['innerContent'] as &$content ) { + $content = str_replace( 'wp-image-' . $block['attrs']['id'], 'wp-image-' . $block['attrs']['id'] . ' cld-overwrite', $content ); + } + } + } + + return $block; + } + /** * Setup hooks for the filters. */ @@ -680,5 +706,8 @@ function ( $type ) use ( $filter ) { // Add checkbox to media modal template. add_action( 'admin_footer', array( $this, 'catch_media_templates_maybe' ), 9 ); + // Filter for block rendering. + add_filter( 'render_block_data', array( $this, 'filter_image_block_pre_render' ), 10, 2 ); + } } diff --git a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/media/class-global-transformations.php b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/media/class-global-transformations.php index dbf0c5df1..fa07794ce 100644 --- a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/media/class-global-transformations.php +++ b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/media/class-global-transformations.php @@ -315,7 +315,7 @@ function ( $item ) { if ( ! $term ) { $term = get_term_by( 'term_taxonomy_id', $parts[1], $parts[0] ); - } + } } else { // Something went wrong, and value was not an int and didn't contain a tax:slug string. return null; @@ -422,9 +422,30 @@ public function save_taxonomy_ordering( $post_id ) { ); $taxonomy_order = filter_input_array( INPUT_POST, $args ); - + if ( ! empty( $taxonomy_order['cld_tax_order'] ) ) { - update_post_meta( $post_id, self::META_ORDER_KEY . '_terms', $taxonomy_order['cld_tax_order'] ); + // Map to ID's where needed. + $order = array_map( + function ( $line ) { + $parts = explode( ':', $line ); + if ( ! empty( $parts[1] ) && ! is_numeric( $parts[1] ) ) { + // Tag based, find term ID. + $line = null; + $term = get_term_by( 'name', $parts[1], $parts[0] ); + if ( ! empty( $term ) ) { + $line = $term->taxonomy . ':' . $term->term_id; + } + } elseif ( empty( $parts[1] ) ) { + // strange '0' based section, remove to be safe. + $line = null; + } + + return $line; + }, + $taxonomy_order['cld_tax_order'] + ); + $order = array_filter( $order ); + update_post_meta( $post_id, self::META_ORDER_KEY . '_terms', $order ); } else { delete_post_meta( $post_id, self::META_ORDER_KEY . '_terms' ); } diff --git a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/media/class-upgrade.php b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/media/class-upgrade.php index ea97be450..7621769eb 100644 --- a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/media/class-upgrade.php +++ b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/media/class-upgrade.php @@ -55,6 +55,20 @@ public function check_cloudinary_version( $cloudinary_id, $attachment_id ) { */ if ( ! empty( $meta['cloudinary'] ) && empty( $public_id ) ) { $cloudinary_id = $this->convert_cloudinary_version( $attachment_id ); + } elseif ( ! empty( $meta['cloudinary'] ) ) { + // Has public ID, but still has cloudinary, check pending status. + $is_pending = $this->media->get_post_meta( $attachment_id, Sync::META_KEYS['pending'], true ); + $attempts = (int) $this->media->get_post_meta( $attachment_id, Sync::META_KEYS['attempts'], true ); + if ( ( empty( $is_pending ) || $is_pending < time() - 5 * 60 ) && 10 > $attempts ) { + // Timeout. + $this->media->update_post_meta( $attachment_id, Sync::META_KEYS['attempts'], $attempts + 1 ); + + // return proposed ID to allow front render. + return $this->convert_cloudinary_version( $attachment_id ); + } + $cloudinary_id = $public_id; + } else { + $cloudinary_id = $public_id; } } @@ -105,12 +119,15 @@ function ( $val ) use ( $media ) { $public_id = strstr( $public_id, '.' . $path['extension'], true ); // Save public ID. $this->media->update_post_meta( $attachment_id, Sync::META_KEYS['public_id'], $public_id ); + // Set download started data. + $this->media->update_post_meta( $attachment_id, Sync::META_KEYS['pending'], time() ); // Setup a call for a background sync. $params = array( 'attachment_id' => $attachment_id, 'src' => $file, 'transformations' => $media->get_transformations_from_string( $file ), + 'filename' => basename( $file ), ); $media->plugin->components['api']->background_request( 'asset', $params ); @@ -124,7 +141,7 @@ public function setup_hooks() { add_filter( 'cloudinary_id', array( $this, 'check_cloudinary_version' ), 9, 2 ); // Priority 9, to take preference over prep_on_demand_upload. // Add a redirection to the new plugin settings, from the old plugin. - if( is_admin() ) { + if ( is_admin() ) { add_action( 'admin_menu', function () { global $plugin_page; if ( ! empty( $plugin_page ) && false !== strpos( $plugin_page, 'cloudinary-image-management-and-manipulation-in-the-cloud-cdn' ) ) { diff --git a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/media/class-video.php b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/media/class-video.php index d76ec64c3..a461f841f 100644 --- a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/media/class-video.php +++ b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/media/class-video.php @@ -199,14 +199,21 @@ public function filter_video_shortcode( $html, $attr ) { if ( false === $this->player_enabled ) { return $html; }; - - // Queue video. - $video = wp_get_attachment_metadata( $attr['id'] ); + // Check for override flag. $overwrite_transformations = false; if ( ! empty( $attr['cldoverwrite'] ) ) { $overwrite_transformations = true; } - $cloudinary_url = $this->media->cloudinary_url( $attr['id'], false, false, null, $overwrite_transformations ); + // Check for a cloudinary url, or prep sync if not found. + $cloudinary_url = $this->media->cloudinary_url( $attr['id'], false, false, null, $overwrite_transformations ); + if ( ! $this->media->plugin->components['sync']->is_synced( $attr['id'] ) ) { + // If the asset is not synced, then the metadata will not be complete since v1 didn't save any. + // Return html for now since cloudinary_url will queue it up for syncing in the background. + return $html; + } + + // Queue video. + $video = wp_get_attachment_metadata( $attr['id'] ); $transformations = $this->media->get_transformations_from_string( $cloudinary_url, 'video' ); $args = array(); @@ -265,8 +272,14 @@ public function filter_video_tags( $content ) { } } - $url = $this->media->filter->get_url_from_tag( $tag ); + $url = $this->media->filter->get_url_from_tag( $tag ); + if ( false === $url ) { + continue; + } $attachment_id = $this->media->get_id_from_url( $url ); + if ( empty( $attachment_id ) ) { + continue; // Missing or no attachment ID found. + } // Enable Autoplay for this video. if ( false !== strpos( $tag, 'autoplay' ) ) { $args['autoplayMode'] = $this->config['video_autoplay_mode']; // if on, use defined mode. @@ -339,7 +352,7 @@ public function print_video_scripts() { $config = wp_parse_args( $video['args'], $default ); - if ( empty( $config['size'] ) && ! isset( $this->config['video_freeform'] ) ) { + if ( empty( $config['size'] ) && ! empty( $config['transformation'] ) && ! $this->media->get_crop_from_transformation( $config['transformation'] ) ) { $config['fluid'] = true; } @@ -356,31 +369,31 @@ public function print_video_scripts() { var cldVideos = ; for ( var videoInstance in cldVideos ) { - var cldConfig = cldVideos[ videoInstance ]; - var cldId = 'cloudinary-video-' + videoInstance; - cld.videoPlayer( cldId, cldConfig ); + var cldConfig = cldVideos[ videoInstance ]; + var cldId = 'cloudinary-video-' + videoInstance; + cld.videoPlayer( cldId, cldConfig ); } window.addEventListener( 'load', function() { - for ( var videoInstance in cldVideos ) { - var cldId = 'cloudinary-video-' + videoInstance; - var videoContainer = document.getElementById( cldId ); - var videoElement = videoContainer.getElementsByTagName( 'video' ); - - if ( videoElement.length === 1 ) { - videoElement = videoElement[0]; - videoElement.style.width = '100%'; - - config['video_freeform'] ): ?> - videoElement.src = videoElement.src.replace( - 'upload/', - 'upload/config['video_freeform'] ) ?>/' - ); - - } - } + for ( var videoInstance in cldVideos ) { + var cldId = 'cloudinary-video-' + videoInstance; + var videoContainer = document.getElementById( cldId ); + var videoElement = videoContainer.getElementsByTagName( 'video' ); + + if ( videoElement.length === 1 ) { + videoElement = videoElement[0]; + + + config['video_freeform'] ): ?> + videoElement.src = videoElement.src.replace( + 'upload/', + 'upload/config['video_freeform'] ) ?>/' + ); + + } + } } ); - plugin->components['media']->get_post_meta( $attachment_id, Sync::META_KEYS['pending'], true ); + if ( ! empty( $is_pending ) ) { + // Dont delete if it's a downsync. + $this->plugin->components['media']->update_post_meta( $attachment_id, Sync::META_KEYS['sync_error'], $error ); + } else { + // Delete attachment temp. + wp_delete_attachment( $attachment_id, true ); + } // Send error. wp_send_json_error( $error ); } @@ -181,6 +189,10 @@ public function rest_download_asset( \WP_REST_Request $request ) { 'data' => $attachment, ); + // Remove pending. + delete_post_meta( $attachment_id, Sync::META_KEYS['pending'] ); + delete_post_meta( $attachment_id, Sync::META_KEYS['sync_error'] ); + return rest_ensure_response( $response ); } } diff --git a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/sync/class-push-sync.php b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/sync/class-push-sync.php index 9c54f27dc..fe98e4448 100644 --- a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/sync/class-push-sync.php +++ b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/php/sync/class-push-sync.php @@ -578,6 +578,14 @@ public function push_attachments( $attachments ) { $meta = wp_get_attachment_metadata( $attachment->ID, true ); $meta[ Sync::META_KEYS['cloudinary'] ] = $meta_data; wp_update_attachment_metadata( $attachment->ID, $meta ); + // Search and update link references in content. + $content_search = new \WP_Query( array( 's' => 'wp-image-' . $attachment->ID, 'fields' => 'ids', 'posts_per_page' => 1000 ) ); + if ( ! empty( $content_search->found_posts ) ) { + $content_posts = array_unique( $content_search->get_posts() ); // ensure post only gets updated once. + foreach ( $content_posts as $content_id ) { + wp_update_post( array( 'ID' => $content_id ) ); // Trigger an update, internal filters will filter out remote URLS. + } + } } $stats['processed'] += 1; diff --git a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/readme.txt b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/readme.txt index bf2edb87a..dc5e236e9 100644 --- a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/readme.txt +++ b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/readme.txt @@ -1,246 +1,115 @@ -=== Cloudinary - Image management and manipulation in the cloud + CDN === -Contributors: cloudinary -Tags: image, images, media, gallery, photo, photos, picture, pictures, thumbnail, upload, admin, administration, api, cms, dashboard, editor, flickr, integration, manage, mobile, page, pages, post, social-media -Requires at least: 3.0 -Tested up to: 5.1 +=== Cloudinary – Dynamic Image and Video Management === +Contributors: Cloudinary, XWP, Automattic +Tags: images, videos, DAM, optimizations, CDN, media, gallery, photo, photos, picture, pictures, thumbnail, upload, admin, administration, api, cms, dashboard, editor, integration, manage, mobile, social-media +Requires at least: 4.7 +Tested up to: 5.3.2 +Requires PHP: 5.6 Stable tag: trunk License: GPLv2 License URI: http://www.gnu.org/licenses/gpl-2.0.html -Cloudinary supercharges your images! Upload images to the cloud, deliver optimized via a fast CDN. Perform smart resizing and apply effects. +Cloudinary is the leading image, video, and rich media management solution that’s used by the world’s leading brands and innovative startups, now available as an easy plugin for WordPress. == Description == +Cloudinary makes automating your image, video, and rich media workflow easy, offering significant advantages over native WordPress capabilities. From upload to management to manipulation and optimization through delivery, all features are offered from within the plugin. -**Cloudinary is your one stop shop for EVERY image related task.** +Optimize your site performance and user experience with faster page load times, advanced auto-responsive delivery, and better visual experience. Automate quality and encoding settings, scale and crop images using AI to focus on the most important region, apply comprehensive transformations and effects, and deliver on any device in any resolution or pixel density. -With Cloudinary, all your images are automatically uploaded, normalized, optimized and backed-up in the cloud instead of being hosted on your servers. - -With Cloudinary, you can stop messing around with image editors. Cloudinary can manipulate and transform your images online, on-the-fly, directly from your WordPress console. Enhance your images using every possible filter and effect you can think of. All manipulations are done in the cloud using super-powerful hardware, and all resulting images are cached, optimized (smushed and more) and delivered via a lightning fast content delivery network (CDN). - -Install Cloudinary now, get the most powerful image solution available today, and get your WordPress powered site to the next level. +And with an embedded digital asset management platform offering full DAM capabilities, you won’t need to leave your WordPress environment. Take full advantage of advanced search, AI tagging, automation, collections, structured metadata, and an intuitive UI making it much easier to manage all of your media in WordPress. = Requirements = -* While you don't need to install any image software on your server, you will need to register for a (free) [Cloudinary account](https://cloudinary.com/users/register/free) to use the plugin and start uploading images to the cloud. -* Is your site gaining traction? Upgrade to one of our PRO accounts for higher usage limits with practically limitless scale. - - -= Overview = - -* Vast array of image manipulation capabilities. -* Virtually limitless scale. -* Lightning-fast image delivery. -* Highly improved user experience & website performance. -* Useful from small websites and blogs to large enterprise solutions. - -= Image Uploads = - -* Upload any image type: JPG, PNG, GIF, animated GIF, BMP, ICO, TIFF, PSD, WebP and even PDFs. -* Upload directly from your desktop. -* Upload a single image or multiple images with ease. -* Remote fetching from public URLs - -= Image Manipulations = - -You can apply one or more transformations and manipulations on every image: - -* **Image formats** - easily convert image formats and modify image quality. -* **Apply effects & filters** - sharpen, sepia, saturation, grayscale, black & white, hue, brightness, oil paint, pixelate, vignette, add borders. -* **Overlays & Text** - add watermarks, add image overlay and underlay, add text to the image. -* **Face detection** - face detection based cropping, thumbnail, multiple faces detection, pixelate faces. -* **Rotates & flips** - Image rotation (90 degrees), arbitrary rotation, exif-based automatic rotation, vertical & horizontal flips, -* **Shape alteration** - add rounded corners, crop to ellipses and circles. -* **Resize & crop** - scale, fill, fit, pad, crop, limit, custom coordinates. -* **PDF Processing** - extract pages, convert to images. - -= Image Storage = - -* All your images are stored in a cloud-based persistent storage. -* Scales to Terabytes and more. -* Highly available redundant storage. -* All your photos are automatically backed-up, including revision tracking. - -= Image Delivery = +* All you need to get started is to register for a free [Cloudinary account](https://cloudinary.com/users/register/free?utm_source=wp&utm_medium=wpmarketplace&utm_campaign=wpmarketplace) to use the plugin and start uploading your media to the cloud. +* As your site’s media management needs grow, you have the choice to easily upgrade to higher usage plans with practically limitless scale. -* All your images are automatically delivered via a lightning-fast world-wide Content Delivery Network (CDN). -* Images are smartly cached for performance optimization, using every best practice in the book. -* Multiple CDN sub-domains (Domain Sharding). += Highlights = -= Image Optimization = - -* Your images are automatically optimized. Their file size is reduced and they are delivered faster to your visitors. -* Stripping meta data. -* Converting formats. -* Optimizing compression. +* Automatically optimize and apply specified global transformations to pre-existing media upon plugin installation as well as all future uploads. +* Search and browse your media with AI-powered tagging and attributes including file type, size, format, and many other parameters all within the media library. +* Automatic responsive images for delivery on various devices in different resolutions. +* Taxonomy level transformations allow users to set transformations by “category” or “tag” and apply these in real time. +* Transcode, AI crop, apply filters, generate thumbnails, and more with our video transformation capabilities. +* The most comprehensive array of image and video manipulation capabilities, powered by AI. +* Ability to display videos using Cloudinary’s video player giving additional features such as bitrate limit, analytics, monetization, and more. = Simple Integration = -* Upload and manage your images with Cloudinary directly from your WordPress interface. -* Migrate all your locally hosted images to Cloudinary. -* Move your existing posts' images to Cloudinary in a single click. -* Easily restore your posts to use local images instead of Cloudinary. -* Seamlessly use Cloudinary's processed images as WordPress featured images. - -= Insights and Reports = +* Upload and manage your assets with Cloudinary directly from your WordPress interface. +* Migrate all your locally hosted assets to Cloudinary. +* Move your existing posts’ images and videos to Cloudinary with a single click. -* Cloudinary offers a powerful online management console. -* Browse all your images and transformations. -* View comprehensive statistics and usage reports. -* You can even automate your content management using a RESTful API. = About Cloudinary = -Read more about the Cloudinary service: - -* [Our website](http://cloudinary.com) -* [Blog](http://cloudinary.com/blog) -* [Features overview](http://cloudinary.com/features) -* [Detailed documentation](http://cloudinary.com/documentation) -* [Image transformations documentation](http://cloudinary.com/documentation/image_transformations) -* [FAQ](http://cloudinary.com/faq) +* [Our website](http://cloudinary.com?utm_source=wp&utm_medium=wpmarketplace&utm_campaign=wpmarketplace) +* [Blog](http://cloudinary.com/blog?utm_source=wp&utm_medium=wpmarketplace&utm_campaign=wpmarketplace) +* [Features overview](http://cloudinary.com/features?utm_source=wp&utm_medium=wpmarketplace&utm_campaign=wpmarketplace) +* [DAM solution](https://cloudinary.com/solutions/digital_asset_management?utm_source=wp&utm_medium=wpmarketplace&utm_campaign=wpmarketplace) +* [Detailed documentation](http://cloudinary.com/documentation?utm_source=wp&utm_medium=wpmarketplace&utm_campaign=wpmarketplace) +* [Image transformations documentation](http://cloudinary.com/documentation/image_transformations?utm_source=wp&utm_medium=wpmarketplace&utm_campaign=wpmarketplace) +* [Video transformations documentation](https://cloudinary.com/documentation/video_manipulation_and_delivery?utm_source=wp&utm_medium=wpmarketplace&utm_campaign=wpmarketplace) +* [FAQ](http://cloudinary.com/faq?utm_source=wp&utm_medium=wpmarketplace&utm_campaign=wpmarketplace) -= Support = += Contributors & Developers = +“Cloudinary – Dynamic Image and Video Management” is an open source software. The following people have contributed to this plugin: +[Cloudinary](https://profiles.wordpress.org/cloudinary/) +[XWP](https://profiles.wordpress.org/xwp/) +[Automattic](https://profiles.wordpress.org/automattic/) -* [Support site](http://support.cloudinary.com/home) -* [Knowledge Base](http://support.cloudinary.com/forums) -* Support Email: [support@cloudinary.com](support@cloudinary.com) -* [Contact page](http://cloudinary.com/contact) -* Twitter: [@cloudinary](http://twitter.com/cloudinary) -* [Facebook page](https://www.facebook.com/Cloudinary) -**Keywords**: image, images, photo, photos, picture, pictures, thumbnail, thumbnails, upload, batch, cdn, content delivery network, transform, manipulate, effects, scale, high availability, fast, format, sharpen, sepia, saturation, grayscale, b&w, hue, brightness, oil paint, pixelate, vignette, -jpg, jpeg, png, gif, animated gif, pdf, face, faces, crop, resize, scale, fit, fill, pad, rotate, rotation, flip, corners, borders, exif, watermark, caption, overlay, underlay, text, embed, quality, smush. - == Installation == += Install from within wordpress = +* Visit the plugins page within your dashboard and select `Add New`. +* Search for `Cloudinary`. +* Select `Cloudinary – Dynamic Image and Video Management` from the list. +* Activate `Cloudinary` from your Plugins page. +* Go to `Setting up` below. -1. Search and install the plugin through the `Install Plugins` page of your WordPress dashboard. Alternatively, upload the `cloudinary` folder to the `/wp-content/plugins/` directory of your blog. -1. Activate the Cloudinary plugin through the `Plugins` page of your WordPress dashboard. -1. Configure the plugin by selecting `Cloudinary' on the left menu of your WordPress dashboard. - -== Frequently Asked Questions == - -= How can I migrate existing posts to deliver images through Cloudinary? = - -Go to WordPress standard media library (select '**Media**' from the left menu). Click '**Upload to Cloudinary**' for each media item you want to migrate to Cloudinary. - -The images will be uploaded to Cloudinary while the content of all associated posts and pages will be automatically updated to point to Cloudinary's CDN URLs. += Install Cloudinary manually = +* Upload the `Cloudinary` folder to the /wp-content/plugins/ directory. +* Activate the `Cloudinary` plugin through the `Plugins` menu in WordPress. +* Go to `Setting up` below. -You can perform bulk migration of multiple posts by selecting multiple media items, selecting '**Upload to Cloudinary**' from the '**Bulk Actions**' menu and click '**Apply**'. += Setting up = +* Once the plugin is activated, go to the `Cloudinary` settings. +* You’ll be prompted to “Add your Cloudinary URL”. +* Enter your “Cloudinary environment variable URL”, the format should be cloudinary://{API_Key}:{API_Secret}@{Cloud_Name} and can be found in the "Account Details" section of the Cloudinary Console Dashboard, then click save. +* After saving, additional settings tabs will be available. -Automatic post migration is supported since version 1.1.0 of the plugin. +**Note** +If you have two factor authentication configured for your account, you will need to open the Cloudinary Console and login before you can use the Cloudinary plugin. +Your site is now setup to start using Cloudinary. -= How can I update my posts to use local files again? = -In case that you decide to stop using Cloudinary's WordPress plugin, you can migrate your existing posts and pages to embed local image files instead of Cloudinary's cloud-based images. -Go to WordPress standard media library (select '**Media**' from the left menu). Select multiple media items you wish to migrate then select '**Migrate away from Cloudinary**' from the '**Bulk Actions**' menu and click '**Apply**'. - -The selected images are automatically downloaded from Cloudinary to your local server. Associated posts are automatically updated to use local image files of Cloudinary's CDN URLs. +== Frequently Asked Questions == += Upgrade from v1= -Automatic migrate away is supported since version 1.1.0 of the plugin. +Once installing the new version of the plugin, the plugin will automatically upgrade all of your assets to work with the new plugin. +Upgrade is seamless and requires no action from your side. -We would appreciate it if you could let us know why you decided to stop using Cloudinary for your site. += Does the plugin sync all of my media to Cloudinary? = -= Where can I find answers to additional common questions? = +The plugin will automatically sync all of your WordPress media to your Cloudinary account and start delivering assets from Cloudinary. -Check out our dynamic [knowledge base](http://support.cloudinary.com/forums/21855426-WordPress) for additional questions and articles. += Where can I find more info? = +You can read the plugin [documentation](https://cloudinary.com/documentation/wordpress_integration?utm_source=wp&utm_medium=wpmarketplace&utm_campaign=wpmarketplace) == Screenshots == - -1. **Cloud-based image gallery** -2. **Drag & drop upload to the cloud** -3. **Powerful live image manipulation** -4. **Apply effects and face detection** -5. **Insert into post and edit** -6. **Simple setup after free sign-up** - -== Upgrade Notice == - -N/A +1. Streamline Your Creative Workflow +2. Media Editor +3. Media Library +4. Easy Generation of Asset Derivatives +5. Automatically Deliver Responsive Images +6. Global Image Transformation Settings +7. Global Video Transformation Settings +8. Folder and Syncing Settings +9. Easily Configure Your Account == Changelog == += 2.0.0 (31 Mar 2020) = + * Release of a new major version of the plugin -= 1.1.12 (11 Mar 2019) = - * Fix jQuery exception - -= 1.1.11 (3 Mar 2019) = - * Add CLI command for syncing media - * Fix `update_window_dimensions` to fire only when library is visible - * Fix illegal function call in PHP5.3 - -= 1.1.10 (17 May 2018) = - * Fix memory exhaustion in "Upload to Cloudinary" functionality - * Fix "Cloudinary Upload/Insert" button compatibility and style - * Fix `url` and `secure_url` inconsistency - * Add handling of WP_Error - * Add cloudinary_php v1.10.0 to WordPress plugin - -= 1.1.9 (26 Apr 2018) = -* Fix "Cloudinary Upload/Insert" functionality - -= 1.1.8 (22 Apr 2018) = -* Fix PHP errors( notices) in DEBUG mode. -* Fix "tinyMCE is not defined" JS error when TinyMCE is not loaded. -* Fix include path in cloudinary.php. - -= 1.1.7 (11 Dec 2017) = -* Support https for bulk upload. -* Fix for DEPRECATED Old style constructor. - -= 1.1.6 (6 Aug 2017) = -* Confirm WordPress 4.8 support. -* Replace old logos. -* Fix "Edit with Cloudinaty" button for WP posts image edit. - -= 1.1.5 (14 Nov 2016) = -* Fix Upload/Insert button. -* Fix setting page on before set credentials. - -= 1.1.4 (4 Nov 2014) = -* Support newer versions of PHP in file upload. Report user agent to Cloudinary. -* Correctly locate path to ajax-loader. - -= 1.1.3 (18 Sep 2014) = -* Fix display compatibility issue with WordPress 4.0. -* Support earlier versions of PHP 5.2. - -= 1.1.2 (24 Dec 2013) = -* Fix display compatibility issue with WordPress 3.8. - -= 1.1.1 (6 Nov 2013) = -* Support WordPress sites that use relative URLs for images. - -= 1.1.0 (5 Aug 2013) = -* Migrate existing posts: upload images to Cloudinary and automatically update associated posts and pages to point to Cloudinary CDN URLs. -* Migrate away from Cloudinary: bulk image downloading from Cloudinary and automatic post updating to use local image files. -* Better integration with WordPress featured images and image galleries. -* Allow adding Cloudinary's images directly to WP's post gallery for setting as featured image and using for image galleries. - -= 1.0.8 (28 Mar 2013) = -* Register images uploaded to Cloudinary from WordPress media library as media items so they can be used as featured images. - -= 1.0.7 (25 Mar 2013) = -* Fix issue of Cloudinary settings not appearing with some themes activated. -* Better error handling when verifying CLOUDINARY_URL. - -= 1.0.6 (22 Mar 2013) = -* Register images with WordPress media to allow using them as featured images. -* Allow uploading images from WP's media library that aren't recognized properly by local PHP code. -* Add class prefix to elements in the settings page to avoid possible collisions. - -= 1.0.5 (17 Mar 2013) = -* Allow administrator (and not only super admin) to manage Cloudinary settings. -* Validation of CLOUDINARY_URL in Settings page. - -= 1.0.4 (16 Mar 2013) = -* Fixes menu and settings in multisite mode. - -= 1.0.3 (15 Mar 2013) = -* Fixes non saved settings issue. - -= 1.0.2 (7 Mar 2013) = -* Minor fixes related to changing directory name. - -= 1.0.1 (27 Feb 2013) = -* Fully tested version entering the plugin directory. +== Upgrade Notice == +Enjoy a seamless upgrade to experience the completely new look and feel of our plugin. Boasting many new features including our digital asset management platform, video player offering advanced capabilities, auto-responsive images, automatic optimizations and transformations, and much more. diff --git a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/ui-definitions/tabs/settings-sync-media.php b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/ui-definitions/tabs/settings-sync-media.php index 8e77d53eb..997b43b15 100644 --- a/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/ui-definitions/tabs/settings-sync-media.php +++ b/cloudinary-image-management-and-manipulation-in-the-cloud-cdn/ui-definitions/tabs/settings-sync-media.php @@ -15,10 +15,8 @@ 'fields' => array( 'cloudinary_folder' => array( 'label' => __( 'Cloudinary folder path', 'cloudinary' ), - 'description' => __( 'Specify the folder in your Cloudinary account where WordPress assets are uploaded to. All assets uploaded to WordPress from this point on will be synced to the specified folder in Cloudinary.', 'cloudinary' ), - 'default' => '/', + 'description' => __( 'Specify the folder in your Cloudinary account where WordPress assets are uploaded to. All assets uploaded to WordPress from this point on will be synced to the specified folder in Cloudinary. Leave blank to use the root of your Cloudinary library.', 'cloudinary' ), 'sanitize_callback' => array( '\Cloudinary\Media', 'sanitize_cloudinary_folder' ), - 'required' => true, 'suffix' => '', ), ),