__( 'Save as a template', 'elementor' ); __( 'New', 'elementor' ); __( 'Create component', 'elementor' ); __( 'To create new components, update Elementor Pro to the latest version.', 'elementor' ); __( 'Update Now', 'elementor' ); __( 'Add %s', 'elementor' ); __( 'Edit %s', 'elementor' ); __( 'Duplicate %s', 'elementor' ); __( 'Delete %s', 'elementor' );# Members - EDD Integration The Members - EDD Integration add-on more nicely integrates the [Easy Digital Downloads](https://easydigitaldownloads.com/) plugin capabilities into the Members plugin's role manager. The [Members plugin](https://themehybrid.com/plugins/members) and the Easy Digital Downloads plugin are required to be installed and activated for this plugin to work. ## Shop Role Group The plugin creates a new "Shop" role group for Easy Digital Downloads, which is located under the Users > Roles screen in the admin. This role group lists the following roles: - Shop Accountant - Shop Manager - Shop Vendor - Shop Worker - Any other roles that have EDD-related capabilities. This allows you to see any roles that have EDD permissions at a glance. ## Downloads Capability Group When editing or creating a new role in Members, this add-on creates a new "Downloads" tab (cap group). This tab combines all of the Easy Digital Downloads capabilities in one place. That way, you can see all available caps without jumping between different tabs. ## Copyright and License This project is licensed under the [GNU GPL](http://www.gnu.org/licenses/old-licenses/gpl-2.0.html), version 2 or later. 2019 © [Justin Tadlock](http://justintadlock.com). /******/ (function() { // webpackBootstrap /******/ "use strict"; /******/ var __webpack_modules__ = ({ /***/ "./node_modules/@monaco-editor/loader/lib/es/_virtual/_rollupPluginBabelHelpers.js": /*!*****************************************************************************************!*\ !*** ./node_modules/@monaco-editor/loader/lib/es/_virtual/_rollupPluginBabelHelpers.js ***! \*****************************************************************************************/ /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ arrayLikeToArray: function() { return /* binding */ _arrayLikeToArray; }, /* harmony export */ arrayWithHoles: function() { return /* binding */ _arrayWithHoles; }, /* harmony export */ defineProperty: function() { return /* binding */ _defineProperty; }, /* harmony export */ iterableToArrayLimit: function() { return /* binding */ _iterableToArrayLimit; }, /* harmony export */ nonIterableRest: function() { return /* binding */ _nonIterableRest; }, /* harmony export */ objectSpread2: function() { return /* binding */ _objectSpread2; }, /* harmony export */ objectWithoutProperties: function() { return /* binding */ _objectWithoutProperties; }, /* harmony export */ objectWithoutPropertiesLoose: function() { return /* binding */ _objectWithoutPropertiesLoose; }, /* harmony export */ slicedToArray: function() { return /* binding */ _slicedToArray; }, /* harmony export */ toPrimitive: function() { return /* binding */ _toPrimitive; }, /* harmony export */ toPropertyKey: function() { return /* binding */ _toPropertyKey; }, /* harmony export */ unsupportedIterableToArray: function() { return /* binding */ _unsupportedIterableToArray; } /* harmony export */ }); function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } function _arrayWithHoles(r) { if (Array.isArray(r)) return r; } function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: true, configurable: true, writable: true }) : e[r] = t, e; } function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = true, o = false; try { if (i = (t = t.call(r)).next, 0 === l) ; else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = true, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread2(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), true).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; } function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; } function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); } function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; } function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } /***/ }), /***/ "./node_modules/@monaco-editor/loader/lib/es/config/index.js": /*!*******************************************************************!*\ !*** ./node_modules/@monaco-editor/loader/lib/es/config/index.js ***! \*******************************************************************/ /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": function() { return /* binding */ config; } /* harmony export */ }); var config = { paths: { vs: 'https://cdn.jsdelivr.net/npm/monaco-editor@0.55.1/min/vs' } }; /***/ }), /***/ "./node_modules/@monaco-editor/loader/lib/es/index.js": /*!************************************************************!*\ !*** ./node_modules/@monaco-editor/loader/lib/es/index.js ***! \************************************************************/ /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": function() { return /* reexport safe */ _loader_index_js__WEBPACK_IMPORTED_MODULE_0__["default"]; } /* harmony export */ }); /* harmony import */ var _loader_index_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./loader/index.js */ "./node_modules/@monaco-editor/loader/lib/es/loader/index.js"); /***/ }), /***/ "./node_modules/@monaco-editor/loader/lib/es/loader/index.js": /*!*******************************************************************!*\ !*** ./node_modules/@monaco-editor/loader/lib/es/loader/index.js ***! \*******************************************************************/ /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": function() { return /* binding */ loader; } /* harmony export */ }); /* harmony import */ var _virtual_rollupPluginBabelHelpers_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../_virtual/_rollupPluginBabelHelpers.js */ "./node_modules/@monaco-editor/loader/lib/es/_virtual/_rollupPluginBabelHelpers.js"); /* harmony import */ var state_local__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! state-local */ "./node_modules/state-local/lib/es/state-local.js"); /* harmony import */ var _config_index_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../config/index.js */ "./node_modules/@monaco-editor/loader/lib/es/config/index.js"); /* harmony import */ var _validators_index_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../validators/index.js */ "./node_modules/@monaco-editor/loader/lib/es/validators/index.js"); /* harmony import */ var _utils_compose_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/compose.js */ "./node_modules/@monaco-editor/loader/lib/es/utils/compose.js"); /* harmony import */ var _utils_deepMerge_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../utils/deepMerge.js */ "./node_modules/@monaco-editor/loader/lib/es/utils/deepMerge.js"); /* harmony import */ var _utils_makeCancelable_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../utils/makeCancelable.js */ "./node_modules/@monaco-editor/loader/lib/es/utils/makeCancelable.js"); var _excluded = ["monaco"]; /** the local state of the module */ var _state$create = state_local__WEBPACK_IMPORTED_MODULE_1__["default"].create({ config: _config_index_js__WEBPACK_IMPORTED_MODULE_2__["default"], isInitialized: false, resolve: null, reject: null, monaco: null }), _state$create2 = (0,_virtual_rollupPluginBabelHelpers_js__WEBPACK_IMPORTED_MODULE_0__.slicedToArray)(_state$create, 2), getState = _state$create2[0], setState = _state$create2[1]; /** * set the loader configuration * @param {Object} config - the configuration object */ function config(globalConfig) { var _validators$config = _validators_index_js__WEBPACK_IMPORTED_MODULE_3__["default"].config(globalConfig), monaco = _validators$config.monaco, config = (0,_virtual_rollupPluginBabelHelpers_js__WEBPACK_IMPORTED_MODULE_0__.objectWithoutProperties)(_validators$config, _excluded); setState(function (state) { return { config: (0,_utils_deepMerge_js__WEBPACK_IMPORTED_MODULE_5__["default"])(state.config, config), monaco: monaco }; }); } /** * handles the initialization of the monaco-editor * @return {Promise} - returns an instance of monaco (with a cancelable promise) */ function init() { var state = getState(function (_ref) { var monaco = _ref.monaco, isInitialized = _ref.isInitialized, resolve = _ref.resolve; return { monaco: monaco, isInitialized: isInitialized, resolve: resolve }; }); if (!state.isInitialized) { setState({ isInitialized: true }); if (state.monaco) { state.resolve(state.monaco); return (0,_utils_makeCancelable_js__WEBPACK_IMPORTED_MODULE_6__["default"])(wrapperPromise); } if (window.monaco && window.monaco.editor) { storeMonacoInstance(window.monaco); state.resolve(window.monaco); return (0,_utils_makeCancelable_js__WEBPACK_IMPORTED_MODULE_6__["default"])(wrapperPromise); } (0,_utils_compose_js__WEBPACK_IMPORTED_MODULE_4__["default"])(injectScripts, getMonacoLoaderScript)(configureLoader); } return (0,_utils_makeCancelable_js__WEBPACK_IMPORTED_MODULE_6__["default"])(wrapperPromise); } /** * injects provided scripts into the document.body * @param {Object} script - an HTML script element * @return {Object} - the injected HTML script element */ function injectScripts(script) { return document.body.appendChild(script); } /** * creates an HTML script element with/without provided src * @param {string} [src] - the source path of the script * @return {Object} - the created HTML script element */ function createScript(src) { var script = document.createElement('script'); return src && (script.src = src), script; } /** * creates an HTML script element with the monaco loader src * @return {Object} - the created HTML script element */ function getMonacoLoaderScript(configureLoader) { var state = getState(function (_ref2) { var config = _ref2.config, reject = _ref2.reject; return { config: config, reject: reject }; }); var loaderScript = createScript("".concat(state.config.paths.vs, "/loader.js")); loaderScript.onload = function () { return configureLoader(); }; loaderScript.onerror = state.reject; return loaderScript; } /** * configures the monaco loader */ function configureLoader() { var state = getState(function (_ref3) { var config = _ref3.config, resolve = _ref3.resolve, reject = _ref3.reject; return { config: config, resolve: resolve, reject: reject }; }); var require = window.require; require.config(state.config); require(['vs/editor/editor.main'], function (loaded) { var monaco = loaded.m /* for 0.53 & 0.54 */ || loaded /* for other versions */; storeMonacoInstance(monaco); state.resolve(monaco); }, function (error) { state.reject(error); }); } /** * store monaco instance in local state */ function storeMonacoInstance(monaco) { if (!getState().monaco) { setState({ monaco: monaco }); } } /** * internal helper function * extracts stored monaco instance * @return {Object|null} - the monaco instance */ function __getMonacoInstance() { return getState(function (_ref4) { var monaco = _ref4.monaco; return monaco; }); } var wrapperPromise = new Promise(function (resolve, reject) { return setState({ resolve: resolve, reject: reject }); }); var loader = { config: config, init: init, __getMonacoInstance: __getMonacoInstance }; /***/ }), /***/ "./node_modules/@monaco-editor/loader/lib/es/utils/compose.js": /*!********************************************************************!*\ !*** ./node_modules/@monaco-editor/loader/lib/es/utils/compose.js ***! \********************************************************************/ /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": function() { return /* binding */ compose; } /* harmony export */ }); var compose = function compose() { for (var _len = arguments.length, fns = new Array(_len), _key = 0; _key < _len; _key++) { fns[_key] = arguments[_key]; } return function (x) { return fns.reduceRight(function (y, f) { return f(y); }, x); }; }; /***/ }), /***/ "./node_modules/@monaco-editor/loader/lib/es/utils/curry.js": /*!******************************************************************!*\ !*** ./node_modules/@monaco-editor/loader/lib/es/utils/curry.js ***! \******************************************************************/ /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": function() { return /* binding */ curry; } /* harmony export */ }); function curry(fn) { return function curried() { var _this = this; for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } return args.length >= fn.length ? fn.apply(this, args) : function () { for (var _len2 = arguments.length, nextArgs = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { nextArgs[_key2] = arguments[_key2]; } return curried.apply(_this, [].concat(args, nextArgs)); }; }; } /***/ }), /***/ "./node_modules/@monaco-editor/loader/lib/es/utils/deepMerge.js": /*!**********************************************************************!*\ !*** ./node_modules/@monaco-editor/loader/lib/es/utils/deepMerge.js ***! \**********************************************************************/ /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": function() { return /* binding */ merge; } /* harmony export */ }); /* harmony import */ var _virtual_rollupPluginBabelHelpers_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../_virtual/_rollupPluginBabelHelpers.js */ "./node_modules/@monaco-editor/loader/lib/es/_virtual/_rollupPluginBabelHelpers.js"); function merge(target, source) { Object.keys(source).forEach(function (key) { if (source[key] instanceof Object) { if (target[key]) { Object.assign(source[key], merge(target[key], source[key])); } } }); return (0,_virtual_rollupPluginBabelHelpers_js__WEBPACK_IMPORTED_MODULE_0__.objectSpread2)((0,_virtual_rollupPluginBabelHelpers_js__WEBPACK_IMPORTED_MODULE_0__.objectSpread2)({}, target), source); } /***/ }), /***/ "./node_modules/@monaco-editor/loader/lib/es/utils/isObject.js": /*!*********************************************************************!*\ !*** ./node_modules/@monaco-editor/loader/lib/es/utils/isObject.js ***! \*********************************************************************/ /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": function() { return /* binding */ isObject; } /* harmony export */ }); function isObject(value) { return {}.toString.call(value).includes('Object'); } /***/ }), /***/ "./node_modules/@monaco-editor/loader/lib/es/utils/makeCancelable.js": /*!***************************************************************************!*\ !*** ./node_modules/@monaco-editor/loader/lib/es/utils/makeCancelable.js ***! \***************************************************************************/ /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ CANCELATION_MESSAGE: function() { return /* binding */ CANCELATION_MESSAGE; }, /* harmony export */ "default": function() { return /* binding */ makeCancelable; } /* harmony export */ }); // The source (has been changed) is https://github.com/facebook/react/issues/5465#issuecomment-157888325 var CANCELATION_MESSAGE = { type: 'cancelation', msg: 'operation is manually canceled' }; function makeCancelable(promise) { var hasCanceled_ = false; var wrappedPromise = new Promise(function (resolve, reject) { promise.then(function (val) { return hasCanceled_ ? reject(CANCELATION_MESSAGE) : resolve(val); }); promise["catch"](reject); }); return wrappedPromise.cancel = function () { return hasCanceled_ = true; }, wrappedPromise; } /***/ }), /***/ "./node_modules/@monaco-editor/loader/lib/es/validators/index.js": /*!***********************************************************************!*\ !*** ./node_modules/@monaco-editor/loader/lib/es/validators/index.js ***! \***********************************************************************/ /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": function() { return /* binding */ validators; }, /* harmony export */ errorHandler: function() { return /* binding */ errorHandler; }, /* harmony export */ errorMessages: function() { return /* binding */ errorMessages; } /* harmony export */ }); /* harmony import */ var _utils_curry_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/curry.js */ "./node_modules/@monaco-editor/loader/lib/es/utils/curry.js"); /* harmony import */ var _utils_isObject_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/isObject.js */ "./node_modules/@monaco-editor/loader/lib/es/utils/isObject.js"); /** * validates the configuration object and informs about deprecation * @param {Object} config - the configuration object * @return {Object} config - the validated configuration object */ function validateConfig(config) { if (!config) errorHandler('configIsRequired'); if (!(0,_utils_isObject_js__WEBPACK_IMPORTED_MODULE_1__["default"])(config)) errorHandler('configType'); if (config.urls) { informAboutDeprecation(); return { paths: { vs: config.urls.monacoBase } }; } return config; } /** * logs deprecation message */ function informAboutDeprecation() { console.warn(errorMessages.deprecation); } function throwError(errorMessages, type) { throw new Error(errorMessages[type] || errorMessages["default"]); } var errorMessages = { configIsRequired: 'the configuration object is required', configType: 'the configuration object should be an object', "default": 'an unknown error accured in `@monaco-editor/loader` package', deprecation: "Deprecation warning!\n You are using deprecated way of configuration.\n\n Instead of using\n monaco.config({ urls: { monacoBase: '...' } })\n use\n monaco.config({ paths: { vs: '...' } })\n\n For more please check the link https://github.com/suren-atoyan/monaco-loader#config\n " }; var errorHandler = (0,_utils_curry_js__WEBPACK_IMPORTED_MODULE_0__["default"])(throwError)(errorMessages); var validators = { config: validateConfig }; /***/ }), /***/ "./packages/packages/pro/editor-controls-extended/src/components/css-code-editor/css-editor.styles.ts": /*!************************************************************************************************************!*\ !*** ./packages/packages/pro/editor-controls-extended/src/components/css-code-editor/css-editor.styles.ts ***! \************************************************************************************************************/ /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ EditorWrapper: function() { return /* binding */ EditorWrapper; }, /* harmony export */ ResizeHandle: function() { return /* binding */ ResizeHandle; } /* harmony export */ }); /* harmony import */ var _elementor_ui__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @elementor/ui */ "@elementor/ui"); /* harmony import */ var _elementor_ui__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_elementor_ui__WEBPACK_IMPORTED_MODULE_0__); const EditorWrapper = (0,_elementor_ui__WEBPACK_IMPORTED_MODULE_0__.styled)((0,_elementor_ui__WEBPACK_IMPORTED_MODULE_0__.Box))` /* @noflip */ direction: ltr; border: 1px solid var( --e-a-border-color ); border-radius: 8px; padding: 4px; position: relative; height: 200px; .monaco-editor .suggest-widget { width: 220px !important; max-width: 220px !important; z-index: 1001; } .visual-content-dimmed { opacity: 0.6; color: #aaa !important; pointer-events: none; } .monaco-editor { .margin-view-overlays > div:nth-of-type( 1 ) .cldr.codicon.codicon-folding-expanded { visibility: hidden; } .monaco-scrollable-element { > .scrollbar { width: 6px !important; > .slider { width: 6px !important; } } } } `; const ResizeHandle = (0,_elementor_ui__WEBPACK_IMPORTED_MODULE_0__.styled)((0,_elementor_ui__WEBPACK_IMPORTED_MODULE_0__.Button))` position: absolute; bottom: 0; left: 0; right: 0; height: 6px; cursor: ns-resize; background: transparent; border: none; padding: 0; &:hover { background: rgba( 0, 0, 0, 0.05 ); } &:active { background: rgba( 0, 0, 0, 0.1 ); } &::after { content: ''; position: absolute; top: 50%; left: 50%; transform: translate( -50%, -50% ); width: 30px; height: 2px; background: var( --e-a-border-color ); border-radius: 1px; } `; /***/ }), /***/ "./packages/packages/pro/editor-controls-extended/src/components/css-code-editor/css-editor.tsx": /*!******************************************************************************************************!*\ !*** ./packages/packages/pro/editor-controls-extended/src/components/css-code-editor/css-editor.tsx ***! \******************************************************************************************************/ /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ CssEditor: function() { return /* binding */ CssEditor; } /* harmony export */ }); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "react"); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _elementor_editor_controls__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @elementor/editor-controls */ "@elementor/editor-controls"); /* harmony import */ var _elementor_editor_controls__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_elementor_editor_controls__WEBPACK_IMPORTED_MODULE_1__); /* harmony import */ var _elementor_editor_ui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @elementor/editor-ui */ "@elementor/editor-ui"); /* harmony import */ var _elementor_editor_ui__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_elementor_editor_ui__WEBPACK_IMPORTED_MODULE_2__); /* harmony import */ var _elementor_ui__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @elementor/ui */ "@elementor/ui"); /* harmony import */ var _elementor_ui__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_elementor_ui__WEBPACK_IMPORTED_MODULE_3__); /* harmony import */ var _monaco_editor_react__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @monaco-editor/react */ "./node_modules/@monaco-editor/react/dist/index.mjs"); /* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n"); /* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_5__); /* harmony import */ var _css_editor_styles__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./css-editor.styles */ "./packages/packages/pro/editor-controls-extended/src/components/css-code-editor/css-editor.styles.ts"); /* harmony import */ var _css_validation__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./css-validation */ "./packages/packages/pro/editor-controls-extended/src/components/css-code-editor/css-validation.ts"); /* harmony import */ var _resize_handle__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./resize-handle */ "./packages/packages/pro/editor-controls-extended/src/components/css-code-editor/resize-handle.tsx"); /* harmony import */ var _visual_content_change_protection__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./visual-content-change-protection */ "./packages/packages/pro/editor-controls-extended/src/components/css-code-editor/visual-content-change-protection.ts"); const createEditorDidMountHandler = (editorRef, monacoRef, onUserContentChange, setIsValid, syntaxRuleOptions) => { return (editor, monaco) => { editorRef.current = editor; monacoRef.current = monaco; (0,_visual_content_change_protection__WEBPACK_IMPORTED_MODULE_9__.preventChangeOnVisualContent)(editor); (0,_css_validation__WEBPACK_IMPORTED_MODULE_7__.setCustomSyntaxRules)(editor, monaco, syntaxRuleOptions); const initialCode = editor.getModel()?.getValue() ?? ''; const initialUserContent = (0,_visual_content_change_protection__WEBPACK_IMPORTED_MODULE_9__.getActual)(initialCode); onUserContentChange(initialUserContent); monaco.editor.onDidChangeMarkers(() => { (0,_css_validation__WEBPACK_IMPORTED_MODULE_7__.clearMarkersFromVisualContent)(editor, monaco); setIsValid((0,_css_validation__WEBPACK_IMPORTED_MODULE_7__.validate)(editor, monaco)); }); editor.setPosition({ lineNumber: 2, column: (editor.getModel()?.getLineContent(2).length ?? 0) + 1 }); disableFoldingFirstRow(editor); // eslint-disable-next-line no-bitwise editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyA, () => { const editorModel = editor.getModel(); if (!editorModel) { return; } const fullRange = editorModel.getFullModelRange(); const contentEndLine = fullRange.endLineNumber - 1; let endColumn = editorModel.getLineLastNonWhitespaceColumn(contentEndLine); if (endColumn === 0) { endColumn = editorModel.getLineMaxColumn(contentEndLine); } editor.setSelection(new monaco.Selection(fullRange.startLineNumber + 1, fullRange.startColumn, contentEndLine, endColumn)); }); }; }; function disableFoldingFirstRow(editor) { if (!(typeof editor.getDomNode === 'function')) { return; } const marginViewOverlays = editor.getDomNode()?.querySelector('.margin-view-overlays'); const handler = event => { const ev = event; if (ev.button !== 0) { return; } const target = ev.target; const firstElem = marginViewOverlays?.children[0]; const isFirstRow = target === firstElem || target.parentElement === firstElem; if (isFirstRow) { event.preventDefault(); event.stopPropagation(); } }; marginViewOverlays?.addEventListener('mousedown', handler); editor.onDidDispose(() => { marginViewOverlays?.removeEventListener('mousedown', handler); }); } const CssEditor = ({ value, onChange, syntaxRuleOptions, readOnly = false }) => { const theme = (0,_elementor_ui__WEBPACK_IMPORTED_MODULE_3__.useTheme)(); const containerRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null); const editorRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null); const monacoRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null); const debounceTimer = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null); const [hasContent, setHasContent] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(value.trim() !== ''); const [isValid, setIsValid] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(true); const [contentVersion, setContentVersion] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(0); useOnUpdate(() => { const code = editorRef.current?.getModel()?.getValue() ?? ''; const userContent = (0,_visual_content_change_protection__WEBPACK_IMPORTED_MODULE_9__.getActual)(code); setHasContent(!userContent.trim()); onChange(userContent, isValid); }, [contentVersion, isValid]); const handleUserContentChange = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(newValue => { setHasContent(newValue.trim() !== ''); }, []); const handleResize = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => { editorRef.current?.layout(); }, []); const handleHeightChange = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(height => { if (containerRef.current) { containerRef.current.style.height = `${height}px`; } }, []); const handleEditorChange = () => { if (!editorRef.current || !monacoRef.current) { return; } (0,_css_validation__WEBPACK_IMPORTED_MODULE_7__.setCustomSyntaxRules)(editorRef?.current, monacoRef.current, syntaxRuleOptions); if (debounceTimer.current) { clearTimeout(debounceTimer.current); } debounceTimer.current = setTimeout(() => { setContentVersion(prev => prev + 1); }, 500); }; const handleEditorDidMount = createEditorDidMountHandler(editorRef, monacoRef, handleUserContentChange, setIsValid, syntaxRuleOptions); const handleReset = () => editorRef.current?.getModel()?.setValue((0,_visual_content_change_protection__WEBPACK_IMPORTED_MODULE_9__.setVisualContent)('')); (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => { const timerRef = debounceTimer; return () => { const timer = timerRef.current; if (timer) { clearTimeout(timer); } }; }, []); return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(_elementor_editor_ui__WEBPACK_IMPORTED_MODULE_2__.FloatingActionsBar, { actions: hasContent ? [/*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(_elementor_editor_controls__WEBPACK_IMPORTED_MODULE_1__.ClearIconButton, { key: "clear", tooltipText: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_5__.__)('Clear', 'elementor-pro'), onClick: handleReset })] : [] }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(_elementor_ui__WEBPACK_IMPORTED_MODULE_3__.Box, null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(_css_editor_styles__WEBPACK_IMPORTED_MODULE_6__.EditorWrapper, { ref: containerRef, dir: "ltr" }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(_monaco_editor_react__WEBPACK_IMPORTED_MODULE_4__.Editor, { height: "100%", language: "css", theme: theme.palette.mode === 'dark' ? 'vs-dark' : 'vs', value: (0,_visual_content_change_protection__WEBPACK_IMPORTED_MODULE_9__.setVisualContent)(value), onMount: handleEditorDidMount, onChange: handleEditorChange, options: { lineNumbers: 'on', lineNumbersMinChars: 3, folding: true, minimap: { enabled: false }, fontFamily: 'Roboto, Arial, Helvetica, Verdana, sans-serif', fontSize: 12, renderLineHighlight: 'none', hideCursorInOverviewRuler: true, overviewRulerBorder: false, fixedOverflowWidgets: true, suggestFontSize: 10, suggestLineHeight: 14, stickyScroll: { enabled: false }, lineDecorationsWidth: 2, wordWrap: 'on', scrollBeyondLastLine: false, readOnly, editContext: false } }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(_resize_handle__WEBPACK_IMPORTED_MODULE_8__.ResizeHandleComponent, { onResize: handleResize, containerRef: containerRef, onHeightChange: handleHeightChange })))); }; function useOnUpdate(callback, dependencies) { const hasMounted = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(false); (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => { if (hasMounted.current) { callback(); } else { hasMounted.current = true; } // eslint-disable-next-line react-hooks/exhaustive-deps }, dependencies); } /***/ }), /***/ "./packages/packages/pro/editor-controls-extended/src/components/css-code-editor/css-validation.ts": /*!*********************************************************************************************************!*\ !*** ./packages/packages/pro/editor-controls-extended/src/components/css-code-editor/css-validation.ts ***! \*********************************************************************************************************/ /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ clearMarkersFromVisualContent: function() { return /* binding */ clearMarkersFromVisualContent; }, /* harmony export */ setCustomSyntaxRules: function() { return /* binding */ setCustomSyntaxRules; }, /* harmony export */ validate: function() { return /* binding */ validate; } /* harmony export */ }); /* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n"); /* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_0__); const syntaxRules = { pseudoState: { pattern: '^\\s*[&]{0,1}\\s*(?::hover|:active|:focus)', regex: true, message: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_0__.__)('The use of pseudo-states is not permitted. Instead, switch to the desired pseudo state and add your custom code there.', 'elementor-pro') }, mediaQuery: { pattern: '@media\\s+[^{]*\\b(?:min-width|max-width|width)\\b', regex: true, message: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_0__.__)('The use of @media width queries is not permitted. Instead, switch to the desired breakpoint and add your custom code there.', 'elementor-pro') } }; function setCustomSyntaxRules(editor, monaco, options) { const model = editor.getModel(); if (!model) { return true; } const customMarkers = []; Object.entries(syntaxRules).forEach(([id, rule]) => { if (options?.rules?.[id] === false) { return; } const matches = model.findMatches(rule.pattern, true, rule.regex ?? false, true, null, true); matches.forEach(match => { customMarkers.push({ severity: monaco.MarkerSeverity.Error, message: rule.message, startLineNumber: match.range.startLineNumber, startColumn: match.range.startColumn, endLineNumber: match.range.endLineNumber, endColumn: match.range.endColumn, source: 'custom-css-rules' }); }); }); monaco.editor.setModelMarkers(model, 'custom-css-rules', customMarkers); return customMarkers.length === 0; } function validate(editor, monaco) { const model = editor.getModel(); if (!model) { return true; } const allMarkers = monaco.editor.getModelMarkers({ resource: model.uri }); return allMarkers.filter(marker => marker.severity === monaco.MarkerSeverity.Error).length === 0; } function clearMarkersFromVisualContent(editor, monaco) { const model = editor.getModel(); if (!model) { return; } const allMarkers = monaco.editor.getModelMarkers({ resource: model.uri }); const filteredMarkers = allMarkers.filter(marker => marker.startLineNumber !== 1); const nonCustomMarkers = filteredMarkers.filter(m => m.source !== 'custom-css-rules'); if (nonCustomMarkers.length === allMarkers.length) { return; } monaco.editor.setModelMarkers(model, 'css', nonCustomMarkers); } /***/ }), /***/ "./packages/packages/pro/editor-controls-extended/src/components/css-code-editor/resize-handle.tsx": /*!*********************************************************************************************************!*\ !*** ./packages/packages/pro/editor-controls-extended/src/components/css-code-editor/resize-handle.tsx ***! \*********************************************************************************************************/ /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ ResizeHandleComponent: function() { return /* binding */ ResizeHandleComponent; } /* harmony export */ }); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "react"); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _css_editor_styles__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./css-editor.styles */ "./packages/packages/pro/editor-controls-extended/src/components/css-code-editor/css-editor.styles.ts"); const ResizeHandleComponent = ({ onResize, containerRef, onHeightChange }) => { const handleResizeMove = react__WEBPACK_IMPORTED_MODULE_0__.useCallback(e => { const container = containerRef.current; if (!container) { return; } const containerRect = container.getBoundingClientRect(); const newHeight = Math.max(100, e.clientY - containerRect.top); onHeightChange?.(newHeight); onResize(newHeight); }, [containerRef, onResize, onHeightChange]); const handleResizeEnd = react__WEBPACK_IMPORTED_MODULE_0__.useCallback(() => { document.removeEventListener('mousemove', handleResizeMove); document.removeEventListener('mouseup', handleResizeEnd); }, [handleResizeMove]); const handleResizeStart = react__WEBPACK_IMPORTED_MODULE_0__.useCallback(e => { e.preventDefault(); e.stopPropagation(); document.addEventListener('mousemove', handleResizeMove); document.addEventListener('mouseup', handleResizeEnd); }, [handleResizeMove, handleResizeEnd]); react__WEBPACK_IMPORTED_MODULE_0__.useEffect(() => { return () => { document.removeEventListener('mousemove', handleResizeMove); document.removeEventListener('mouseup', handleResizeEnd); }; }, [handleResizeMove, handleResizeEnd]); return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(_css_editor_styles__WEBPACK_IMPORTED_MODULE_1__.ResizeHandle, { onMouseDown: handleResizeStart, "aria-label": "Resize editor height", title: "Drag to resize editor height" }); }; /***/ }), /***/ "./packages/packages/pro/editor-controls-extended/src/components/css-code-editor/visual-content-change-protection.ts": /*!***************************************************************************************************************************!*\ !*** ./packages/packages/pro/editor-controls-extended/src/components/css-code-editor/visual-content-change-protection.ts ***! \***************************************************************************************************************************/ /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ getActual: function() { return /* binding */ getActual; }, /* harmony export */ preventChangeOnVisualContent: function() { return /* binding */ preventChangeOnVisualContent; }, /* harmony export */ setVisualContent: function() { return /* binding */ setVisualContent; } /* harmony export */ }); const preventChangeOnVisualContent = editor => { const model = editor.getModel(); if (!model) { return; } // On first load applyVisualContentStyling(editor, model); // On every change model.onDidChangeContent(() => { applyVisualContentStyling(editor, model); }); disableCursorOnVisualContent(editor); overridePushEditOperations(model); }; const applyVisualContentStyling = (editor, model) => { const decorationsCollection = editor.createDecorationsCollection(); const lineCount = model.getLineCount(); const decorations = []; decorations.push({ range: { startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: model.getLineContent(1).length + 1 }, options: { inlineClassName: 'visual-content-dimmed', isWholeLine: false } }); if (lineCount > 1) { decorations.push({ range: { startLineNumber: lineCount, startColumn: 1, endLineNumber: lineCount, endColumn: model.getLineContent(lineCount).length + 1 }, options: { inlineClassName: 'visual-content-dimmed', isWholeLine: false } }); } decorationsCollection.set(decorations); }; const disableCursorOnVisualContent = editor => { const model = editor.getModel(); if (!model) { return; } editor.onDidChangeCursorPosition(e => { const totalLines = model.getLineCount(); const position = e.position; if (position.lineNumber === 1) { editor.setPosition({ lineNumber: 2, column: 1 }); } else if (position.lineNumber === totalLines) { editor.setPosition({ lineNumber: totalLines - 1, column: model.getLineContent(totalLines - 1).length + 1 }); } }); }; const overridePushEditOperations = model => { const originalPushEditOperations = model.pushEditOperations; model.pushEditOperations = (beforeCursorState, editOperations, cursorStateComputer) => { const totalLines = model.getLineCount(); const modelRange = model.getFullModelRange(); const filteredOperations = editOperations.filter(operation => { const range = operation.range; const affectsProtectedLine = range.startLineNumber === 1 || range.endLineNumber === 1 || range.startLineNumber === totalLines || range.endLineNumber === totalLines; if (affectsProtectedLine && isFullContentReplacement(range, modelRange) && hasVisualContent(operation.text)) { return true; } return !affectsProtectedLine; }); return originalPushEditOperations.call(model, beforeCursorState, filteredOperations, cursorStateComputer); }; }; const isFullContentReplacement = (range, modelRange) => { return range.startLineNumber === modelRange.startLineNumber && range.endLineNumber === modelRange.endLineNumber && range.startColumn === modelRange.startColumn && range.endColumn === modelRange.endColumn; }; const hasVisualContent = text => { if (!text) { return false; } return text.startsWith('element.style {') && text.endsWith('}'); }; const setVisualContent = value => { const trimmed = value.trim(); return `element.style {\n${trimmed ? ' ' + trimmed.replace(/\n/g, '\n ') + '\n' : ' \n'}}`; }; const getActual = value => { const lines = value.split('\n'); if (lines.length < 2) { return ''; } return lines.slice(1, -1).map(line => line.replace(/^ {2}/, '')).join('\n'); }; /***/ }), /***/ "./packages/packages/pro/editor-controls-extended/src/controls/attributes-control.tsx": /*!********************************************************************************************!*\ !*** ./packages/packages/pro/editor-controls-extended/src/controls/attributes-control.tsx ***! \********************************************************************************************/ /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ AttributesControl: function() { return /* binding */ AttributesControl; } /* harmony export */ }); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "react"); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _elementor_editor_controls__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @elementor/editor-controls */ "@elementor/editor-controls"); /* harmony import */ var _elementor_editor_controls__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_elementor_editor_controls__WEBPACK_IMPORTED_MODULE_1__); /* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n"); /* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_2__); const AttributesControl = (0,_elementor_editor_controls__WEBPACK_IMPORTED_MODULE_1__.createControl)(() => { const getHelperText = (key, value) => { if (value && !key) { return { keyHelper: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_2__.__)("Empty attribute names aren't valid and won't render on the page.", 'elementor-pro') }; } return {}; }; return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(_elementor_editor_controls__WEBPACK_IMPORTED_MODULE_1__.KeyValueControl, { keyName: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_2__.__)('Name', 'elementor-pro'), valueName: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_2__.__)('Value', 'elementor-pro'), regexKey: "^[a-zA-Z0-9_-]*$", validationErrorMessage: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_2__.__)('Names can only use letters, numbers, dashes (-) and underscores (_).', 'elementor-pro'), getHelperText: getHelperText }); }); /***/ }), /***/ "./packages/packages/pro/editor-controls-extended/src/controls/display-conditions-control.tsx": /*!****************************************************************************************************!*\ !*** ./packages/packages/pro/editor-controls-extended/src/controls/display-conditions-control.tsx ***! \****************************************************************************************************/ /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ DisplayConditionsControl: function() { return /* binding */ DisplayConditionsControl; } /* harmony export */ }); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "react"); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _elementor_editor_controls__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @elementor/editor-controls */ "@elementor/editor-controls"); /* harmony import */ var _elementor_editor_controls__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_elementor_editor_controls__WEBPACK_IMPORTED_MODULE_1__); /* harmony import */ var _elementor_icons__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @elementor/icons */ "@elementor/icons"); /* harmony import */ var _elementor_icons__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_elementor_icons__WEBPACK_IMPORTED_MODULE_2__); /* harmony import */ var _elementor_ui__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @elementor/ui */ "@elementor/ui"); /* harmony import */ var _elementor_ui__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_elementor_ui__WEBPACK_IMPORTED_MODULE_3__); /* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n"); /* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_4__); /* harmony import */ var _prop_types_display_conditions__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../prop-types/display-conditions */ "./packages/packages/pro/editor-controls-extended/src/prop-types/display-conditions.ts"); /* harmony import */ var _utils_display_conditions_utils__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../utils/display-conditions-utils */ "./packages/packages/pro/editor-controls-extended/src/utils/display-conditions-utils.ts"); const OPEN_MODAL_EVENT = 'elementor/display-conditions/open'; const CLOSE_MODAL_EVENT = 'elementor/display-conditions/close'; const SET_CACHE_NOTICE_STATUS_EVENT = 'elementor/display-conditions/set-cache-notice-status'; const ariaLabel = (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_4__.__)('Display Conditions', 'elementor-pro'); async function setCacheNoticeStatus() { return new Promise((resolve, reject) => { window.dispatchEvent(new CustomEvent(SET_CACHE_NOTICE_STATUS_EVENT, { detail: { resolve, reject } })); }); } const DisplayConditionsControl = (0,_elementor_editor_controls__WEBPACK_IMPORTED_MODULE_1__.createControl)(({ disabled = false }) => { const { setValue, value: displayConditionsValue } = (0,_elementor_editor_controls__WEBPACK_IMPORTED_MODULE_1__.useBoundProp)(_prop_types_display_conditions__WEBPACK_IMPORTED_MODULE_5__.displayConditionsPropTypeUtil); const [isModalOpen, setIsModalOpen] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false); const hasValue = !!displayConditionsValue?.length; const setControlValue = value => setValue((0,_utils_display_conditions_utils__WEBPACK_IMPORTED_MODULE_6__.transformV3ToV4)(JSON.parse(value ?? '[]'))); const getControlValue = () => (0,_utils_display_conditions_utils__WEBPACK_IMPORTED_MODULE_6__.transformV4ToV3)(displayConditionsValue) ?? []; const onClose = () => { setIsModalOpen(false); window.dispatchEvent(new CustomEvent(CLOSE_MODAL_EVENT)); }; const conditions = getControlValue(); const openConditionsModal = () => { setIsModalOpen(true); window.dispatchEvent(new CustomEvent(OPEN_MODAL_EVENT, { detail: { props: { getControlValue, setControlValue, onClose, setCacheNoticeStatus } } })); }; return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(_elementor_ui__WEBPACK_IMPORTED_MODULE_3__.Stack, { direction: "row", spacing: 2, sx: { justifyContent: 'flex-end', alignItems: 'center' } }, disabled && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(_elementor_ui__WEBPACK_IMPORTED_MODULE_3__.Chip, { icon: /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(_elementor_icons__WEBPACK_IMPORTED_MODULE_2__.CrownFilledIcon, { fontSize: "tiny" }), size: "tiny", color: "promotion", variant: "standard", sx: { width: '20px', '& .MuiChip-label': { display: 'none' } } }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(_elementor_ui__WEBPACK_IMPORTED_MODULE_3__.Tooltip, { title: ariaLabel, placement: "top" }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(_elementor_ui__WEBPACK_IMPORTED_MODULE_3__.Box, { sx: { cursor: disabled ? 'not-allowed' : 'pointer', display: 'inline-flex' } }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(_elementor_ui__WEBPACK_IMPORTED_MODULE_3__.ToggleButton, { value: JSON.stringify(conditions), size: "tiny", variant: "outline", "aria-pressed": hasValue, "aria-expanded": isModalOpen, selected: hasValue, "aria-haspopup": "dialog", "aria-label": ariaLabel, onClick: openConditionsModal, disabled: disabled, sx: { pointerEvents: disabled ? 'none' : 'auto' }, "data-behavior": "display-conditions" }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(_elementor_icons__WEBPACK_IMPORTED_MODULE_2__.SitemapIcon, { fontSize: "tiny" })))))); }); /***/ }), /***/ "./packages/packages/pro/editor-controls-extended/src/controls/options-control.tsx": /*!*****************************************************************************************!*\ !*** ./packages/packages/pro/editor-controls-extended/src/controls/options-control.tsx ***! \*****************************************************************************************/ /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ OptionsControl: function() { return /* binding */ OptionsControl; } /* harmony export */ }); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "react"); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _elementor_editor_controls__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @elementor/editor-controls */ "@elementor/editor-controls"); /* harmony import */ var _elementor_editor_controls__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_elementor_editor_controls__WEBPACK_IMPORTED_MODULE_1__); /* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n"); /* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_2__); const OptionsControl = (0,_elementor_editor_controls__WEBPACK_IMPORTED_MODULE_1__.createControl)(() => { return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(_elementor_editor_controls__WEBPACK_IMPORTED_MODULE_1__.KeyValueControl, { keyName: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_2__.__)('Name', 'elementor-pro'), valueName: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_2__.__)('Value', 'elementor-pro') }); }); /***/ }), /***/ "./packages/packages/pro/editor-controls-extended/src/extend-transition-properties.ts": /*!********************************************************************************************!*\ !*** ./packages/packages/pro/editor-controls-extended/src/extend-transition-properties.ts ***! \********************************************************************************************/ /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ extendTransitionProperties: function() { return /* binding */ extendTransitionProperties; }, /* harmony export */ transitionProperties: function() { return /* reexport safe */ _elementor_editor_controls__WEBPACK_IMPORTED_MODULE_0__.transitionProperties; }, /* harmony export */ transitionsItemsList: function() { return /* reexport safe */ _elementor_editor_controls__WEBPACK_IMPORTED_MODULE_0__.transitionsItemsList; } /* harmony export */ }); /* harmony import */ var _elementor_editor_controls__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @elementor/editor-controls */ "@elementor/editor-controls"); /* harmony import */ var _elementor_editor_controls__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_elementor_editor_controls__WEBPACK_IMPORTED_MODULE_0__); function extendTransitionProperties(isDisabled = false) { if (!_elementor_editor_controls__WEBPACK_IMPORTED_MODULE_0__.transitionProperties || _elementor_editor_controls__WEBPACK_IMPORTED_MODULE_0__.transitionProperties.length === 0) { return; } _elementor_editor_controls__WEBPACK_IMPORTED_MODULE_0__.transitionProperties.forEach(category => { category.properties.forEach(property => { if (property.value !== 'all') { property.isDisabled = isDisabled; } }); }); _elementor_editor_controls__WEBPACK_IMPORTED_MODULE_0__.transitionsItemsList.splice(0, _elementor_editor_controls__WEBPACK_IMPORTED_MODULE_0__.transitionsItemsList.length, ..._elementor_editor_controls__WEBPACK_IMPORTED_MODULE_0__.transitionProperties.map(category => ({ label: category.label, items: category.properties.map(property => property.label) }))); } /***/ }), /***/ "./packages/packages/pro/editor-controls-extended/src/init.ts": /*!********************************************************************!*\ !*** ./packages/packages/pro/editor-controls-extended/src/init.ts ***! \********************************************************************/ /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ init: function() { return /* binding */ init; } /* harmony export */ }); /* harmony import */ var _elementor_license_api__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @elementor/license-api */ "@elementor/license-api"); /* harmony import */ var _elementor_license_api__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_elementor_license_api__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _extend_transition_properties__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./extend-transition-properties */ "./packages/packages/pro/editor-controls-extended/src/extend-transition-properties.ts"); async function init() { const [isExpired, features] = await Promise.all([(0,_elementor_license_api__WEBPACK_IMPORTED_MODULE_0__.fetchLicenseStatus)().catch(() => false), (0,_elementor_license_api__WEBPACK_IMPORTED_MODULE_0__.fetchTierFeatures)().catch(() => [])]); if (features.includes('transitions')) { (0,_extend_transition_properties__WEBPACK_IMPORTED_MODULE_1__.extendTransitionProperties)(isExpired); } } /***/ }), /***/ "./packages/packages/pro/editor-controls-extended/src/prop-types/condition-group.ts": /*!******************************************************************************************!*\ !*** ./packages/packages/pro/editor-controls-extended/src/prop-types/condition-group.ts ***! \******************************************************************************************/ /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ conditionGroupPropTypeUtil: function() { return /* binding */ conditionGroupPropTypeUtil; } /* harmony export */ }); /* harmony import */ var _elementor_editor_props__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @elementor/editor-props */ "@elementor/editor-props"); /* harmony import */ var _elementor_editor_props__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_elementor_editor_props__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _elementor_schema__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @elementor/schema */ "@elementor/schema"); /* harmony import */ var _elementor_schema__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_elementor_schema__WEBPACK_IMPORTED_MODULE_1__); const unknownChildrenSchema = _elementor_schema__WEBPACK_IMPORTED_MODULE_1__.z.any().nullable(); const conditionGroupPropTypeUtil = (0,_elementor_editor_props__WEBPACK_IMPORTED_MODULE_0__.createPropUtils)('condition-group', _elementor_schema__WEBPACK_IMPORTED_MODULE_1__.z.array(unknownChildrenSchema)); /***/ }), /***/ "./packages/packages/pro/editor-controls-extended/src/prop-types/display-conditions.ts": /*!*********************************************************************************************!*\ !*** ./packages/packages/pro/editor-controls-extended/src/prop-types/display-conditions.ts ***! \*********************************************************************************************/ /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ displayConditionsPropTypeUtil: function() { return /* binding */ displayConditionsPropTypeUtil; } /* harmony export */ }); /* harmony import */ var _elementor_editor_props__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @elementor/editor-props */ "@elementor/editor-props"); /* harmony import */ var _elementor_editor_props__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_elementor_editor_props__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _elementor_schema__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @elementor/schema */ "@elementor/schema"); /* harmony import */ var _elementor_schema__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_elementor_schema__WEBPACK_IMPORTED_MODULE_1__); const unknownChildrenSchema = _elementor_schema__WEBPACK_IMPORTED_MODULE_1__.z.any().nullable(); const displayConditionsPropTypeUtil = (0,_elementor_editor_props__WEBPACK_IMPORTED_MODULE_0__.createPropUtils)('display-conditions', _elementor_schema__WEBPACK_IMPORTED_MODULE_1__.z.array(unknownChildrenSchema)); /***/ }), /***/ "./packages/packages/pro/editor-controls-extended/src/utils/display-conditions-utils.ts": /*!**********************************************************************************************!*\ !*** ./packages/packages/pro/editor-controls-extended/src/utils/display-conditions-utils.ts ***! \**********************************************************************************************/ /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ transformV3ToV4: function() { return /* binding */ transformV3ToV4; }, /* harmony export */ transformV4ToV3: function() { return /* binding */ transformV4ToV3; } /* harmony export */ }); /* harmony import */ var _elementor_editor_props__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @elementor/editor-props */ "@elementor/editor-props"); /* harmony import */ var _elementor_editor_props__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_elementor_editor_props__WEBPACK_IMPORTED_MODULE_0__); // Value must be falsy for navigator indication to work properly function transformV3ToV4(displayConditions) { if (!Array.isArray(displayConditions) || !displayConditions?.length) { return null; } const transformed = displayConditions.filter(conditionGroup => !!conditionGroup?.length).map(conditionGroup => ({ $$type: 'condition-group', value: conditionGroup.map(condition => _elementor_editor_props__WEBPACK_IMPORTED_MODULE_0__.stringPropTypeUtil.create(JSON.stringify(condition))) })); return transformed.length ? transformed : null; } function transformV4ToV3(value) { const conditionGroups = value; const transformed = conditionGroups?.map(group => group.value.map(conditions => { return JSON.parse(_elementor_editor_props__WEBPACK_IMPORTED_MODULE_0__.stringPropTypeUtil.extract(conditions) ?? '[]'); })) ?? null; return getStructuredConditions(transformed); } function shouldConvertConditionsStructure(conditions) { return !!conditions?.length && !Array.isArray(conditions?.[0]); } function getStructuredConditions(conditions) { return shouldConvertConditionsStructure(conditions) ? [conditions] : conditions; } /***/ }), /***/ "./node_modules/state-local/lib/es/state-local.js": /*!********************************************************!*\ !*** ./node_modules/state-local/lib/es/state-local.js ***! \********************************************************/ /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread2(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } function compose() { for (var _len = arguments.length, fns = new Array(_len), _key = 0; _key < _len; _key++) { fns[_key] = arguments[_key]; } return function (x) { return fns.reduceRight(function (y, f) { return f(y); }, x); }; } function curry(fn) { return function curried() { var _this = this; for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { args[_key2] = arguments[_key2]; } return args.length >= fn.length ? fn.apply(this, args) : function () { for (var _len3 = arguments.length, nextArgs = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { nextArgs[_key3] = arguments[_key3]; } return curried.apply(_this, [].concat(args, nextArgs)); }; }; } function isObject(value) { return {}.toString.call(value).includes('Object'); } function isEmpty(obj) { return !Object.keys(obj).length; } function isFunction(value) { return typeof value === 'function'; } function hasOwnProperty(object, property) { return Object.prototype.hasOwnProperty.call(object, property); } function validateChanges(initial, changes) { if (!isObject(changes)) errorHandler('changeType'); if (Object.keys(changes).some(function (field) { return !hasOwnProperty(initial, field); })) errorHandler('changeField'); return changes; } function validateSelector(selector) { if (!isFunction(selector)) errorHandler('selectorType'); } function validateHandler(handler) { if (!(isFunction(handler) || isObject(handler))) errorHandler('handlerType'); if (isObject(handler) && Object.values(handler).some(function (_handler) { return !isFunction(_handler); })) errorHandler('handlersType'); } function validateInitial(initial) { if (!initial) errorHandler('initialIsRequired'); if (!isObject(initial)) errorHandler('initialType'); if (isEmpty(initial)) errorHandler('initialContent'); } function throwError(errorMessages, type) { throw new Error(errorMessages[type] || errorMessages["default"]); } var errorMessages = { initialIsRequired: 'initial state is required', initialType: 'initial state should be an object', initialContent: 'initial state shouldn\'t be an empty object', handlerType: 'handler should be an object or a function', handlersType: 'all handlers should be a functions', selectorType: 'selector should be a function', changeType: 'provided value of changes should be an object', changeField: 'it seams you want to change a field in the state which is not specified in the "initial" state', "default": 'an unknown error accured in `state-local` package' }; var errorHandler = curry(throwError)(errorMessages); var validators = { changes: validateChanges, selector: validateSelector, handler: validateHandler, initial: validateInitial }; function create(initial) { var handler = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; validators.initial(initial); validators.handler(handler); var state = { current: initial }; var didUpdate = curry(didStateUpdate)(state, handler); var update = curry(updateState)(state); var validate = curry(validators.changes)(initial); var getChanges = curry(extractChanges)(state); function getState() { var selector = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : function (state) { return state; }; validators.selector(selector); return selector(state.current); } function setState(causedChanges) { compose(didUpdate, update, validate, getChanges)(causedChanges); } return [getState, setState]; } function extractChanges(state, causedChanges) { return isFunction(causedChanges) ? causedChanges(state.current) : causedChanges; } function updateState(state, changes) { state.current = _objectSpread2(_objectSpread2({}, state.current), changes); return changes; } function didStateUpdate(state, handler, changes) { isFunction(handler) ? handler(state.current) : Object.keys(changes).forEach(function (field) { var _handler$field; return (_handler$field = handler[field]) === null || _handler$field === void 0 ? void 0 : _handler$field.call(handler, state.current[field]); }); return changes; } var index = { create: create }; /* harmony default export */ __webpack_exports__["default"] = (index); /***/ }), /***/ "react": /*!**************************!*\ !*** external ["React"] ***! \**************************/ /***/ (function(module) { module.exports = window["React"]; /***/ }), /***/ "@elementor/editor-controls": /*!*************************************************!*\ !*** external ["elementorV2","editorControls"] ***! \*************************************************/ /***/ (function(module) { module.exports = window["elementorV2"]["editorControls"]; /***/ }), /***/ "@elementor/editor-props": /*!**********************************************!*\ !*** external ["elementorV2","editorProps"] ***! \**********************************************/ /***/ (function(module) { module.exports = window["elementorV2"]["editorProps"]; /***/ }), /***/ "@elementor/editor-ui": /*!*******************************************!*\ !*** external ["elementorV2","editorUi"] ***! \*******************************************/ /***/ (function(module) { module.exports = window["elementorV2"]["editorUi"]; /***/ }), /***/ "@elementor/icons": /*!****************************************!*\ !*** external ["elementorV2","icons"] ***! \****************************************/ /***/ (function(module) { module.exports = window["elementorV2"]["icons"]; /***/ }), /***/ "@elementor/license-api": /*!*********************************************!*\ !*** external ["elementorV2","licenseApi"] ***! \*********************************************/ /***/ (function(module) { module.exports = window["elementorV2"]["licenseApi"]; /***/ }), /***/ "@elementor/schema": /*!*****************************************!*\ !*** external ["elementorV2","schema"] ***! \*****************************************/ /***/ (function(module) { module.exports = window["elementorV2"]["schema"]; /***/ }), /***/ "@elementor/ui": /*!*************************************!*\ !*** external ["elementorV2","ui"] ***! \*************************************/ /***/ (function(module) { module.exports = window["elementorV2"]["ui"]; /***/ }), /***/ "@wordpress/i18n": /*!******************************!*\ !*** external ["wp","i18n"] ***! \******************************/ /***/ (function(module) { module.exports = window["wp"]["i18n"]; /***/ }), /***/ "./node_modules/@monaco-editor/react/dist/index.mjs": /*!**********************************************************!*\ !*** ./node_modules/@monaco-editor/react/dist/index.mjs ***! \**********************************************************/ /***/ (function(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ DiffEditor: function() { return /* binding */ we; }, /* harmony export */ Editor: function() { return /* binding */ de; }, /* harmony export */ "default": function() { return /* binding */ Ft; }, /* harmony export */ loader: function() { return /* reexport safe */ _monaco_editor_loader__WEBPACK_IMPORTED_MODULE_0__["default"]; }, /* harmony export */ useMonaco: function() { return /* binding */ Le; } /* harmony export */ }); /* harmony import */ var _monaco_editor_loader__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @monaco-editor/loader */ "./node_modules/@monaco-editor/loader/lib/es/index.js"); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react */ "react"); var le={wrapper:{display:"flex",position:"relative",textAlign:"initial"},fullWidth:{width:"100%"},hide:{display:"none"}},v=le;var ae={container:{display:"flex",height:"100%",width:"100%",justifyContent:"center",alignItems:"center"}},Y=ae;function Me({children:e}){return react__WEBPACK_IMPORTED_MODULE_1__.createElement("div",{style:Y.container},e)}var Z=Me;var $=Z;function Ee({width:e,height:r,isEditorReady:n,loading:t,_ref:a,className:m,wrapperProps:E}){return react__WEBPACK_IMPORTED_MODULE_1__.createElement("section",{style:{...v.wrapper,width:e,height:r},...E},!n&&react__WEBPACK_IMPORTED_MODULE_1__.createElement($,null,t),react__WEBPACK_IMPORTED_MODULE_1__.createElement("div",{ref:a,style:{...v.fullWidth,...!n&&v.hide},className:m}))}var ee=Ee;var H=(0,react__WEBPACK_IMPORTED_MODULE_1__.memo)(ee);function Ce(e){(0,react__WEBPACK_IMPORTED_MODULE_1__.useEffect)(e,[])}var k=Ce;function he(e,r,n=!0){let t=(0,react__WEBPACK_IMPORTED_MODULE_1__.useRef)(!0);(0,react__WEBPACK_IMPORTED_MODULE_1__.useEffect)(t.current||!n?()=>{t.current=!1}:e,r)}var l=he;function D(){}function h(e,r,n,t){return De(e,t)||be(e,r,n,t)}function De(e,r){return e.editor.getModel(te(e,r))}function be(e,r,n,t){return e.editor.createModel(r,n,t?te(e,t):void 0)}function te(e,r){return e.Uri.parse(r)}function Oe({original:e,modified:r,language:n,originalLanguage:t,modifiedLanguage:a,originalModelPath:m,modifiedModelPath:E,keepCurrentOriginalModel:g=!1,keepCurrentModifiedModel:N=!1,theme:x="light",loading:P="Loading...",options:y={},height:V="100%",width:z="100%",className:F,wrapperProps:j={},beforeMount:A=D,onMount:q=D}){let[M,O]=(0,react__WEBPACK_IMPORTED_MODULE_1__.useState)(!1),[T,s]=(0,react__WEBPACK_IMPORTED_MODULE_1__.useState)(!0),u=(0,react__WEBPACK_IMPORTED_MODULE_1__.useRef)(null),c=(0,react__WEBPACK_IMPORTED_MODULE_1__.useRef)(null),w=(0,react__WEBPACK_IMPORTED_MODULE_1__.useRef)(null),d=(0,react__WEBPACK_IMPORTED_MODULE_1__.useRef)(q),o=(0,react__WEBPACK_IMPORTED_MODULE_1__.useRef)(A),b=(0,react__WEBPACK_IMPORTED_MODULE_1__.useRef)(!1);k(()=>{let i=_monaco_editor_loader__WEBPACK_IMPORTED_MODULE_0__["default"].init();return i.then(f=>(c.current=f)&&s(!1)).catch(f=>f?.type!=="cancelation"&&console.error("Monaco initialization: error:",f)),()=>u.current?I():i.cancel()}),l(()=>{if(u.current&&c.current){let i=u.current.getOriginalEditor(),f=h(c.current,e||"",t||n||"text",m||"");f!==i.getModel()&&i.setModel(f)}},[m],M),l(()=>{if(u.current&&c.current){let i=u.current.getModifiedEditor(),f=h(c.current,r||"",a||n||"text",E||"");f!==i.getModel()&&i.setModel(f)}},[E],M),l(()=>{let i=u.current.getModifiedEditor();i.getOption(c.current.editor.EditorOption.readOnly)?i.setValue(r||""):r!==i.getValue()&&(i.executeEdits("",[{range:i.getModel().getFullModelRange(),text:r||"",forceMoveMarkers:!0}]),i.pushUndoStop())},[r],M),l(()=>{u.current?.getModel()?.original.setValue(e||"")},[e],M),l(()=>{let{original:i,modified:f}=u.current.getModel();c.current.editor.setModelLanguage(i,t||n||"text"),c.current.editor.setModelLanguage(f,a||n||"text")},[n,t,a],M),l(()=>{c.current?.editor.setTheme(x)},[x],M),l(()=>{u.current?.updateOptions(y)},[y],M);let L=(0,react__WEBPACK_IMPORTED_MODULE_1__.useCallback)(()=>{if(!c.current)return;o.current(c.current);let i=h(c.current,e||"",t||n||"text",m||""),f=h(c.current,r||"",a||n||"text",E||"");u.current?.setModel({original:i,modified:f})},[n,r,a,e,t,m,E]),U=(0,react__WEBPACK_IMPORTED_MODULE_1__.useCallback)(()=>{!b.current&&w.current&&(u.current=c.current.editor.createDiffEditor(w.current,{automaticLayout:!0,...y}),L(),c.current?.editor.setTheme(x),O(!0),b.current=!0)},[y,x,L]);(0,react__WEBPACK_IMPORTED_MODULE_1__.useEffect)(()=>{M&&d.current(u.current,c.current)},[M]),(0,react__WEBPACK_IMPORTED_MODULE_1__.useEffect)(()=>{!T&&!M&&U()},[T,M,U]);function I(){let i=u.current?.getModel();g||i?.original?.dispose(),N||i?.modified?.dispose(),u.current?.dispose()}return react__WEBPACK_IMPORTED_MODULE_1__.createElement(H,{width:z,height:V,isEditorReady:M,loading:P,_ref:w,className:F,wrapperProps:j})}var ie=Oe;var we=(0,react__WEBPACK_IMPORTED_MODULE_1__.memo)(ie);function Pe(){let[e,r]=(0,react__WEBPACK_IMPORTED_MODULE_1__.useState)(_monaco_editor_loader__WEBPACK_IMPORTED_MODULE_0__["default"].__getMonacoInstance());return k(()=>{let n;return e||(n=_monaco_editor_loader__WEBPACK_IMPORTED_MODULE_0__["default"].init(),n.then(t=>{r(t)})),()=>n?.cancel()}),e}var Le=Pe;function He(e){let r=(0,react__WEBPACK_IMPORTED_MODULE_1__.useRef)();return (0,react__WEBPACK_IMPORTED_MODULE_1__.useEffect)(()=>{r.current=e},[e]),r.current}var se=He;var _=new Map;function Ve({defaultValue:e,defaultLanguage:r,defaultPath:n,value:t,language:a,path:m,theme:E="light",line:g,loading:N="Loading...",options:x={},overrideServices:P={},saveViewState:y=!0,keepCurrentModel:V=!1,width:z="100%",height:F="100%",className:j,wrapperProps:A={},beforeMount:q=D,onMount:M=D,onChange:O,onValidate:T=D}){let[s,u]=(0,react__WEBPACK_IMPORTED_MODULE_1__.useState)(!1),[c,w]=(0,react__WEBPACK_IMPORTED_MODULE_1__.useState)(!0),d=(0,react__WEBPACK_IMPORTED_MODULE_1__.useRef)(null),o=(0,react__WEBPACK_IMPORTED_MODULE_1__.useRef)(null),b=(0,react__WEBPACK_IMPORTED_MODULE_1__.useRef)(null),L=(0,react__WEBPACK_IMPORTED_MODULE_1__.useRef)(M),U=(0,react__WEBPACK_IMPORTED_MODULE_1__.useRef)(q),I=(0,react__WEBPACK_IMPORTED_MODULE_1__.useRef)(),i=(0,react__WEBPACK_IMPORTED_MODULE_1__.useRef)(t),f=se(m),Q=(0,react__WEBPACK_IMPORTED_MODULE_1__.useRef)(!1),B=(0,react__WEBPACK_IMPORTED_MODULE_1__.useRef)(!1);k(()=>{let p=_monaco_editor_loader__WEBPACK_IMPORTED_MODULE_0__["default"].init();return p.then(R=>(d.current=R)&&w(!1)).catch(R=>R?.type!=="cancelation"&&console.error("Monaco initialization: error:",R)),()=>o.current?pe():p.cancel()}),l(()=>{let p=h(d.current,e||t||"",r||a||"",m||n||"");p!==o.current?.getModel()&&(y&&_.set(f,o.current?.saveViewState()),o.current?.setModel(p),y&&o.current?.restoreViewState(_.get(m)))},[m],s),l(()=>{o.current?.updateOptions(x)},[x],s),l(()=>{!o.current||t===void 0||(o.current.getOption(d.current.editor.EditorOption.readOnly)?o.current.setValue(t):t!==o.current.getValue()&&(B.current=!0,o.current.executeEdits("",[{range:o.current.getModel().getFullModelRange(),text:t,forceMoveMarkers:!0}]),o.current.pushUndoStop(),B.current=!1))},[t],s),l(()=>{let p=o.current?.getModel();p&&a&&d.current?.editor.setModelLanguage(p,a)},[a],s),l(()=>{g!==void 0&&o.current?.revealLine(g)},[g],s),l(()=>{d.current?.editor.setTheme(E)},[E],s);let X=(0,react__WEBPACK_IMPORTED_MODULE_1__.useCallback)(()=>{if(!(!b.current||!d.current)&&!Q.current){U.current(d.current);let p=m||n,R=h(d.current,t||e||"",r||a||"",p||"");o.current=d.current?.editor.create(b.current,{model:R,automaticLayout:!0,...x},P),y&&o.current.restoreViewState(_.get(p)),d.current.editor.setTheme(E),g!==void 0&&o.current.revealLine(g),u(!0),Q.current=!0}},[e,r,n,t,a,m,x,P,y,E,g]);(0,react__WEBPACK_IMPORTED_MODULE_1__.useEffect)(()=>{s&&L.current(o.current,d.current)},[s]),(0,react__WEBPACK_IMPORTED_MODULE_1__.useEffect)(()=>{!c&&!s&&X()},[c,s,X]),i.current=t,(0,react__WEBPACK_IMPORTED_MODULE_1__.useEffect)(()=>{s&&O&&(I.current?.dispose(),I.current=o.current?.onDidChangeModelContent(p=>{B.current||O(o.current.getValue(),p)}))},[s,O]),(0,react__WEBPACK_IMPORTED_MODULE_1__.useEffect)(()=>{if(s){let p=d.current.editor.onDidChangeMarkers(R=>{let G=o.current.getModel()?.uri;if(G&&R.find(J=>J.path===G.path)){let J=d.current.editor.getModelMarkers({resource:G});T?.(J)}});return()=>{p?.dispose()}}return()=>{}},[s,T]);function pe(){I.current?.dispose(),V?y&&_.set(m,o.current.saveViewState()):o.current.getModel()?.dispose(),o.current.dispose()}return react__WEBPACK_IMPORTED_MODULE_1__.createElement(H,{width:z,height:F,isEditorReady:s,loading:N,_ref:b,className:j,wrapperProps:A})}var fe=Ve;var de=(0,react__WEBPACK_IMPORTED_MODULE_1__.memo)(fe);var Ft=de; //# sourceMappingURL=index.mjs.map /***/ }) /******/ }); /************************************************************************/ /******/ // The module cache /******/ var __webpack_module_cache__ = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache /******/ var cachedModule = __webpack_module_cache__[moduleId]; /******/ if (cachedModule !== undefined) { /******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { /******/ // no module.id needed /******/ // no module.loaded needed /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ if (!(moduleId in __webpack_modules__)) { /******/ delete __webpack_module_cache__[moduleId]; /******/ var e = new Error("Cannot find module '" + moduleId + "'"); /******/ e.code = 'MODULE_NOT_FOUND'; /******/ throw e; /******/ } /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /************************************************************************/ /******/ /* webpack/runtime/compat get default export */ /******/ !function() { /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function() { return module['default']; } : /******/ function() { return module; }; /******/ __webpack_require__.d(getter, { a: getter }); /******/ return getter; /******/ }; /******/ }(); /******/ /******/ /* webpack/runtime/define property getters */ /******/ !function() { /******/ // define getter functions for harmony exports /******/ __webpack_require__.d = function(exports, definition) { /******/ for(var key in definition) { /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); /******/ } /******/ } /******/ }; /******/ }(); /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ !function() { /******/ __webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); } /******/ }(); /******/ /******/ /* webpack/runtime/make namespace object */ /******/ !function() { /******/ // define __esModule on exports /******/ __webpack_require__.r = function(exports) { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ }(); /******/ /************************************************************************/ var __webpack_exports__ = {}; // This entry needs to be wrapped in an IIFE because it needs to be isolated against other modules in the chunk. !function() { /*!*********************************************************************!*\ !*** ./packages/packages/pro/editor-controls-extended/src/index.ts ***! \*********************************************************************/ __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ AttributesControl: function() { return /* reexport safe */ _controls_attributes_control__WEBPACK_IMPORTED_MODULE_1__.AttributesControl; }, /* harmony export */ CssEditor: function() { return /* reexport safe */ _components_css_code_editor_css_editor__WEBPACK_IMPORTED_MODULE_6__.CssEditor; }, /* harmony export */ DisplayConditionsControl: function() { return /* reexport safe */ _controls_display_conditions_control__WEBPACK_IMPORTED_MODULE_3__.DisplayConditionsControl; }, /* harmony export */ OptionsControl: function() { return /* reexport safe */ _controls_options_control__WEBPACK_IMPORTED_MODULE_2__.OptionsControl; }, /* harmony export */ conditionGroupPropTypeUtil: function() { return /* reexport safe */ _prop_types_condition_group__WEBPACK_IMPORTED_MODULE_5__.conditionGroupPropTypeUtil; }, /* harmony export */ displayConditionsPropTypeUtil: function() { return /* reexport safe */ _prop_types_display_conditions__WEBPACK_IMPORTED_MODULE_4__.displayConditionsPropTypeUtil; } /* harmony export */ }); /* harmony import */ var _init__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./init */ "./packages/packages/pro/editor-controls-extended/src/init.ts"); /* harmony import */ var _controls_attributes_control__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./controls/attributes-control */ "./packages/packages/pro/editor-controls-extended/src/controls/attributes-control.tsx"); /* harmony import */ var _controls_options_control__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./controls/options-control */ "./packages/packages/pro/editor-controls-extended/src/controls/options-control.tsx"); /* harmony import */ var _controls_display_conditions_control__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./controls/display-conditions-control */ "./packages/packages/pro/editor-controls-extended/src/controls/display-conditions-control.tsx"); /* harmony import */ var _prop_types_display_conditions__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./prop-types/display-conditions */ "./packages/packages/pro/editor-controls-extended/src/prop-types/display-conditions.ts"); /* harmony import */ var _prop_types_condition_group__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./prop-types/condition-group */ "./packages/packages/pro/editor-controls-extended/src/prop-types/condition-group.ts"); /* harmony import */ var _components_css_code_editor_css_editor__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./components/css-code-editor/css-editor */ "./packages/packages/pro/editor-controls-extended/src/components/css-code-editor/css-editor.tsx"); (0,_init__WEBPACK_IMPORTED_MODULE_0__.init)(); }(); (window.elementorV2 = window.elementorV2 || {}).editorControlsExtended = __webpack_exports__; /******/ })() ; window.elementorV2.editorControlsExtended?.init?.(); Everything You Need to Know About Sri Lanka | Char's Footsteps https://www.charsfootsteps.com/travel/asia/sri-lanka/ Best Female Travel Blogs 2024 Mon, 11 Aug 2025 18:41:25 +0000 en-US hourly 1 Ella, Sri Lanka: A Guide https://www.charsfootsteps.com/travel/asia/sri-lanka/ella-sri-lanka/?utm_source=rss&utm_medium=rss&utm_campaign=ella-sri-lanka https://www.charsfootsteps.com/travel/asia/sri-lanka/ella-sri-lanka/#respond Thu, 05 Sep 2024 03:51:36 +0000 https://www.charsfootsteps.com/?p=2879 Ella is a gem tucked away in the lush greenery of Sri Lanka‘s hill country. I got to spend 5 amazing nights in Ella and have written up the best things I did during my time. With its beautiful landscapes, rich history and lively atmosphere, Ella offers a plethora of experiences for everyone. Getting the […]

The post Ella, Sri Lanka: A Guide appeared first on Char's Footsteps.

]]>
Ella is a gem tucked away in the lush greenery of Sri Lanka‘s hill country. I got to spend 5 amazing nights in Ella and have written up the best things I did during my time. With its beautiful landscapes, rich history and lively atmosphere, Ella offers a plethora of experiences for everyone.

Getting the Train to Ella

Reaching Ella is an experience in itself, with the scenic train journey from Kandy often regarded as one of the most beautiful in the world. Winding through lush tea plantations, misty mountains and quaint villages, the journey offers breathtaking views at every turn. This iconic train ride is not just a mode of transport, but also a highlight of any trip to Sri Lanka. It does take a while (7 hours on average!!) but it’s absolutely worth it!

Hike to Ella Rock

Ella Rock is an iconic landmark that offers panoramic views of the surrounding valleys and tea plantations. Without doubt, hiking Ella Rock was my favourite thing to do in Ella. So much so, that I did it twice! The hike begins near the Ella Railway Station and takes approximately 2-3 hours to reach the summit. It’s not the most obvious trail route, so if like me you have no sense of direction, I’d go with people. I became close with some girls from my hostel, and even as a group, we got a bit lost at times.

hiking in ella sri lanka

During the hike, you’ll encounter lush forests, cascading waterfalls, and friendly locals who are always ready to offer a helping hand. Trust me, the breathtaking view from the top is well worth the effort. Both times I went, there were a group of people at the top selling cold drinks and snacks. We bought some refreshments and enjoyed the view at the top for a while.

Visit the Nine Arch Bridge

No trip to Ella is complete without marvelling at the Nine Arch Bridge. To note, it can get very crowded with tourists, so go early! We met organised people who had worked out exactly what time the train would be coming through. However, we just bought some snacks and chatted whilst waiting for the trains.

nine arch bridge sri lanka

We walked over the bridge to get pictures from both sides and get a better view into the valley below. The photos honestly don’t do it justice and it was such a nice place to just hang out regardless of the trains.

There were some ladies selling mangos and coconuts on one side too which were so fresh!

Try Ceylon Tea

Sri Lanka is renowned for its tea, and Ella is no exception. I went on a Tea Tasting Experience in Ella at one of the local plantations and got to learn about the art of tea cultivation and production. We got to try a variety of flavours, ranging from strong black teas to light green teas. The green surroundings here were stunning too! I booked my tea tour through my hostel, but through researching, I believe it’s the Halpewatte Tea Factory Tour.

Sri Lanka tea plantation

If you’re getting the Kandy to Ella train, you’ll spend hours travelling through the tea plantations and be treated to incredible smells!!

Explore the Ravana Falls

There are hundreds of waterfalls in Ella and its surrounding area. I went with some new friends to visit the Ravana Falls, one of Ella’s most iconic waterfalls. Located just a short tuk-tuk ride away from the town centre, you will be treated to breathtaking 25m waterfalls. Some people were swimming in the base of the falls, but we just sat on the nearby rocks and enjoyed the atmosphere. As with many places in Ella, it was quite crowded here. I expect if you go early in the morning, you could have a quieter experience.

Little Adam’s Peak

Another brilliant hike to do in Ella is Little Adam’s Peak. This is much less strenuous than Ella Rock but still provides rewarding views. A relatively easy trek from the town centre, this miniature peak offers sweeping vistas of Ella’s lush landscapes and distant mountain ranges. We took some food with us and enjoyed a small lunch at the end of the route. Alternatively, you can here for a while and wait for the epic sunsets over the valley below.

All The Food!!

No visit to Ella would be complete without indulging in the all the mouthwatering flavours of Sri Lankan cuisine. From fragrant curries to spicy sambols, Ella has some great places to try particularly all the roti!

For an even better taste of the Sri Lankan food, visit the Ella Spice Garden! Here you can take cooking classes and learn how to make authentic, tasty Sri Lankan dishes. They also provide guided tours of their gardens where you can learn about how they use a variety of spices for cooking and medicinal properties. The big ones being cinnamon, cardamom and cloves! We also got to sample a few freshly brewed spice tea. The whole experience definitely exceeded my expectations and i’d highly recommend visiting if you’re a foodie.

Watch the Sunset at Ella Gap

Spend one of your evenings watching the sunset over Ella Gap. This gap in the mountain range offers incredible views of the valley below. In the evenings, At sunset, you’ll find groups of people gathered together to marvel over the colourful skies. You’ll be able to get here from Little Adam’s Peak, so if you’re short on time, do the hike in the afternoon and wait for sunset.

Bicycle Around Ella Village

One of my biggest regrets was not renting a bike or doing a cycling tour around Ella. On my last day, I met people who raved about cycling tours that went past emerald green fields, quaint cottages, local markets and eateries. I wasn’t aware this was something on offer, but I’d do it if I go back to Ella.

After my incredible trip in Ella, I caught a shuttle bus down to Mirissa for the next part of my trip in Sri Lanka. Read more on my favourite beaches in Sri Lanka, visiting Galle and why Sigiriya is a must-do!

Sri Lanka Blog Posts

hiking ella rock

Ella, Sri Lanka: A Guide

Ella is a gem tucked away in the lush greenery of Sri Lanka’s hill country. I got to spend 5 …
nine arch bridge sri lanka

Ultimate Guide for Travel in Sri Lanka

Sri Lanka is an incredible island country located in the Indian Ocean, just south of India. I spent three glorious …
best beaches in sri lanka

Best Beaches in Sri Lanka

When it comes to beaches, Sri Lanka has it all. From scuba diving to whale watching, surfing to sunbathing, there’s …
Galle

The 8 Best Things to Do in Galle, Sri Lanka

When people think about Galle, they usually imagine the infamous Lighthouse and nothing else. I nearly avoided the add journey …
sigiriya lions rock

Everything You Need To Know About Climbing Sigiriya

Sigiriya, or Lion Rock, is an ancient rock fortress located in the central plains of Sri Lanka. As one of …
kandy to ella train

The Kandy to Ella Train: The Ultimate Sri Lanka Experience

The Kandy to Ella train is one of the most scenic train rides in Sri Lanka and provides for a …

The post Ella, Sri Lanka: A Guide appeared first on Char's Footsteps.

]]>
https://www.charsfootsteps.com/travel/asia/sri-lanka/ella-sri-lanka/feed/ 0
Ultimate Guide for Travel in Sri Lanka https://www.charsfootsteps.com/travel/asia/sri-lanka/sri-lanka-itinerary/?utm_source=rss&utm_medium=rss&utm_campaign=sri-lanka-itinerary https://www.charsfootsteps.com/travel/asia/sri-lanka/sri-lanka-itinerary/#respond Tue, 03 Sep 2024 03:23:53 +0000 https://www.charsfootsteps.com/?p=65 Sri Lanka is an incredible island country located in the Indian Ocean, just south of India. I spent three glorious weeks travelling around this beautiful country as a solo backpacker and loved every minute. Here is a guide to some of the best places to visit in Sri Lanka, whilst reassuring how easy it was […]

The post Ultimate Guide for Travel in Sri Lanka appeared first on Char's Footsteps.

]]>
Sri Lanka is an incredible island country located in the Indian Ocean, just south of India. I spent three glorious weeks travelling around this beautiful country as a solo backpacker and loved every minute. Here is a guide to some of the best places to visit in Sri Lanka, whilst reassuring how easy it was travelling solo. So, from the ancient ruins in the north, to sandy beaches in the south, here are the best places to go in Sri Lanka!

Sri Lanka Itinerary

There is so much to do in Sri Lanka and I loved how varied each place is! This is a suggested itinerary based on my 3-week trip. I wanted a mix of historical sites, hikes, beaches, nights-out, cities and chill time:

  • Dambulla – 4 nights (I arrived very late on night one)
  • Kandy – 1 night
  • Ella – 5 nights
  • Mirissa – 4 nights
  • Weligama – 1 night
  • Unawatuna – 4 nights
  • Galle (day trip from Unawatuna)
  • Colombo – 1 night

Best Places to Go in Sri Lanka

For a small country, there are so many incredible places to visit whilst spending time in Sri Lanka. I wanted a mix of cultural sites, nature, beaches and cities so picked my route accordingly. Landing in the international airport, Colombo Bandaranaike, I started my three weeks in Sri Lanka by heading straight to Dambulla.

Dambulla

Dambulla, a small town tucked away in the Central Province of Sri Lanka, provided an excellent base to explore the cultural north. The main attraction within Dambulla itself is the World Heritage Site The Golden Temple of Dambulla. These are the largest and best preserved cave temples in Sri Lanka and definitely worth a visit.

By staying in Dambulla, I was able to easily do day excursions to Sigiriya, Polonnaruwa and Anuradhapura. The main bus station in Dambulla has a number of options to get to each place cheaply. However, for these journeys I shared a private taxi with two guys I met in my hotel. This worked out to be approximately £110 in total for 3 days worth of taxis.

This option worked out well for us! We saved time getting between each place and our lovely driver made for an excellent guide, providing us with lots of interesting information for each area.

Polonnaruwa, located in Sri Lanka’s North Central Province, is an ancient city that served as the island’s capital during the 11th and 12th centuries. It is renowned for its well-preserved ruins, including royal palaces, temples, and massive statues of Buddha, such as the Gal Vihara. Polonnaruwa archaeological park, a UNESCO World Heritage Site, offers an interesting glimpse into Sri Lanka’s rich history. We rented bicycles to make exploring Polonnaruwa easier!

Anuradhapura is one of the island’s ancient capitals, also renowned for its well-preserved ruins and religious significance. This UNESCO World Heritage Site features impressive stupas, monasteries, and the sacred Bodhi tree, believed to be the world’s oldest living tree planted by humans. As a major centre of Buddhism, Anuradhapura offers insight into Sri Lanka’s early civilisation and spiritual heritage, with its vast archaeological complex spread over several square kilometres. Like Polonnaruwa, you can rent bikes to explore the area. Or even tuktuks!

Sigiriya / Lion Rock

Sigiriya, also known as Lion Rock, is an ancient rock fortress known for its well-preserved gardens and incredible views from the summit. I’ve written a detailed post regarding Sigiriya and my experience climbing Lion Rock here. If you’re limited for time in the North of Sri Lanka, I would personally recommend Sigiriya and Polonnaruwa as must-dos!

sigiriya lions rock

I am extremely scared of heights so getting to the top of Sigiriya was quite a feat! But the whole experience going up and seeing the views from the summit were absolutely worth it. Just don’t make the same mistake as me and go on a Sri Lankan public holiday – as you’ll see from the queues going up, it was packed!

Sigiriya Lion Staircase

After 4 nights in Dambulla, it was time to head down the country. Dambulla has numerous bus routes, which made it easy to travel to my next stop, Kandy. The journey took roughly 2.5 hours in a public bus and was very cheap! For a look into bus routes from Dambulla, check out this post. I relied on this site a lot for bus information. However my hotel were really helpful and flagged the bus for me to jump on, saving me walking a mile to the bus station.

Kandy

Kandy is one of the largest cities in the country and a great place to marvel in some of Sri Lanka’s rich heritage. Some of the best things to do in Kandy include watching a traditional dance show and visiting the UNESCO world heritage site The Temple of the Tooth Relic. Both of these are possible to do late afternoon and in the evening. I spent the day exploring Kandy, sitting by the Lake during the day and enjoying some sites in the evening. I found one night in Kandy to be enough time to everything I wanted.

One of my favourite things to do in Sri Lanka was catch the infamous Kandy to Ella Train. Although it was a long journey – 7 hours – the views were incredible and it was such a unique experience to travel through the country sitting in an open train doorway. I would definitely recommend catching an early train so you’re not spending the bulk of your day travelling.

kandy to ella train

Ella

Ella is nestled in Sri Lanka’s Hill Country and is famous for its lush tea plantations, scenic hikes and waterfalls. I LOVED Ella and extended my original stay to 5 nights. I found there was so much to do in Ella and it was easy to meet other backpackers, making excursions and evenings very fun.

ella sri lanka

The best things to do in Ella were trekking to Ella Rock, climbing Little Adam rock, admiring the waterfalls, visiting Nine Arch Bridge and trying the famous Ceylon Tea. Ella had lots of cute bars, cafes and shops. I also enjoyed a few self-care pamper sessions like massages.

After an incredible stay in Ella, I made my way down to the beaches, with my first stop at Mirissa.

Mirissa

Mirissa, a coastal town in southern Sri Lanka, is renowned for its stunning beaches and vibrant marine life. One of the main things to do here are the whale watching tours, where you see blue whales, dolphins, and other marine species.

best beaches in sri lanka

I had heard negative reviews on how the whales were treated on the tours, so I decided to skip this. Instead I enjoyed Mirissa Beach for its swimming and snorkelling. For those interested in surfing, this is a good beach for it, but there are other more noteworthy surfing beaches – like Weligama. I also went to the famous Coconut Tree Hill to enjoy the scenic viewpoint and to take pictures.

Additionally, Mirissa has a lively nightlife with beachside bars and restaurants serving fresh seafood. As a solobackpacker, I found Mirissa was a great place to meet other people. We were out most nights at beach parties and I found it to be a very lively area, with lots going on.

Mirissa is about 150km South of Colombo and easily accessible by train, bus or car. I took a shuttle from Ella to Mirissa, which was long but a very cheap option.

Weligama

Weligama is primarily known for its surfing – being a great place for beginners and seasoned surfers alike. Although I did enjoy my surf lesson here, I found the beach here to not be very nice compared to Mirissa and Unawatuna. The beach had a few sun bed areas in one section but these were expensive to rent. There were a few small vans selling juices and snacks by the beach, which were enjoyed after tiring work trying to learn to surf. I stayed for one night in Weligama, but in hindsight, would have preferred to just do a day trip to Weligama for the surf lesson.

However, in recent years, Weligama has become quite a hub for digital nomads. Therefore the beach might be quite different now compared to when I went in 2019. This area could be a great place to base yourself if you’re looking for a more long-term option, in terms of accommodation and meeting other long-term stayers.

Related: Best Beaches in Sri Lanka Guide

Unawatuna

30km west of Mirissa is another coastal town worth checking out, Unawatuna. Unawatuna is home to a huge beach; famous for its clear waters, diving, swimming and snorkelling. The main street here is lined with many cafes, restaurants and shops, making it a great place to base yourself for a few days. I stayed here for 4 nights, choosing to chill in Unawatuna and spend some time exploring surrounding areas. I had a day trip to the nearby Hikkaduwa Beach to see turtles and had another day trip to Galle.

The area is also home to the Japanese Peace Pagoda, offering panoramic views of the coastline. Another beach worth checking out in the area is Jungle Beach. It’s much quieter and perfect for a relaxed day by the sea.

Like Mirissa, Unawatuna had great nightlife, with beachfront restaurants and beach bars. As a solo backpacker, I was able to meet people easily in both beaches and had really fun nights out each evening!

Galle

I had no expectations for Galle, but it turned out to be one of my favourite places in Sri Lanka. Galle can easily be done as a day trip from Unawatuna or you could choose to stay there for a night. As I was based in Unawatuna for 4 nights, I chose to visit Galle for the day. It was really easy, and cheap, to get the local bus from Unawatuna straight to Galle, but you could get a train, tuktuk or taxi.

Galle

The best thing to do in Galle is head to the Old Town, walk around the Historic Fort and see the famous Lighthouse. You can easily spend several hours walking around this UNESCO World Heritage Site, and learn more about the old fortified harbour town’s mix of colonial and local traditions.

I also loved walking through the streets of the Old Town, browsing through the boutiques, shops, art galleries and stopping for food in one of the many cafes. I would recommend staying into the evening so you can watch the sunset from the Lighthouse Beach! I’ve written a more detailed post on my time in Galle.

Colombo

Colombo, the capital (and largest city) of Sri Lanka, offers a mix of cultural, historical, and modern attractions. After an incredible three weeks in Sri Lanka, it was time to head home. I took the train from Unawatuna to Colombo for 24 hours in the city before my flight to London.

unawatuna train station

The main things I did during my time in Colombo were; visiting the National Museum – home to artefacts from Sri Lanka’s history. I walked along the Galle Face Green which is a popular seaside promenade – it was bustling with people! In the morning I visited the Jami Ul-Alfar Mosque, one of the oldest mosques in Colombo. Although it was interesting to see, there were MANY scammers in the area trying to make me get into tuk-tuks to another mosque. Nearby is the famous Pettah Market which I’d be recommended by other travellers for some shopping. I would say it was fairly overwhelming given how busy it was and all the shouting to look into stalls/shops. But it was interesting to see.

I only stayed for one night but it seemed like there was good nightlife, with numerous restaurants and bars scattered across the city. Cinnamon Gardens and Fort were the areas recommended to me for nightlife.

Other things I had on my list, but didn’t have time to see were the Gangaramaya Temple (for insight into the country’s Buddhist heritage) and the Old Dutch Hospital – a shopping/dining area that shows the colonial history. Although I enjoyed exploring Colombo, I would say you don’t need very long here. I used it as a base before flying home, so spent a night and two days there.

Weather in Sri Lanka

Like many Asian countries, Sri Lanka’s peak season is between December and mid-April. However different parts of the island are hit by monsoons at times of the year. It’s important to keep this in mind if you’re going for the beaches or hikes.

  • South-West – Monsoon Season: May – Sept, Dry Season: Dec – March
  • North, East Coast – Monsoon Season: Oct-Jan, Dry Season: May-Sept
  • Whole Island – Inter-monsoonal: October – November

For a detailed look into weather in Sri Lanka, check out this site.

Getting to Sri Lanka

Bandaranaike International Airport (BIA) is the main international airport serving Sri Lanka, so it’s likely you’ll be starting your journey here. Many people choose to stay in Colombo (the capital) or Negombo when they first arrive. Both are easy to get to from the airport and are a good place to relax in after long flights.

BIA has a number of bus routes if you’re wanting to save money and immerse yourself into public transport immediately. However, I was travelling solo and landed late in the evening, so opted for a private taxi. It was easy to get one from the airport and only cost £34 for a 4 hour drive to my first stop, Dambulla.

Other Places to See in Sri Lanka

There were many places I didn’t have time to see in Sri Lanka. Here are a few I’d visit if I got the chance to go back:

Jaffna

Jaffna is the capital city of the Northern Province of Sri Lanka and is home to the countries’ vibrant Tamil culture. Visit ancient temples, stroll along pristine beaches and immerse yourself in a side of Sri Lanka that is largely untouched by backpackers.

National Parks of Sri Lanka

There are a number of national parks throughout the country to choose from;

  • Udawalawe National Park – huge nature reserve most famous for its elephants. Although you’ll also see wild buffalos, sambars, spotted deer and more.
  • Yala National Park – a wildlife sanctuary known for its conservation of elephants, leopards and aquatic birds.
  • Sinharaja Forest Reserve – a reserve protecting the last viable remnants of tropical rainforest in Sri Lanka. Home to 139 endemic plant species, two types of forest, insects, birds, reptiles and amphibians.
  • Bundala National Park – famous for migrating water birds; home to 197 species of birds, lagoons and waterways.
  • Wilpattu National Park – the largest and oldest national park in Sri Lanka and known for its leopard population.

Adam’s Peake

Adam’s Peak (Sri Pada) is a prominent pilgrimage site in Sri Lanka. Located in the central highlands, it stands at 2,243 metres and is revered by multiple religious communities. To reach Adam’s Peak, it’s best to start from Hatton (135km SW of Colombo), which is accessible by train or bus from Colombo. From Hatton, a further journey by bus or taxi will take you to the trailhead at Dalhousie, the most common starting point for the ascent.

Adam’s Peake is a challenging 5,000 step climb that typically takes 3-5 hours. From what I heard from other travellers, it’s a fairly well-maintained path with lots of tea shops along the way for refreshments. The climb is often done at night to reach the summit in time for sunrise, which offers stunning views of the surrounding landscape. I imagine this also makes it easier given how hot Sri Lanka can get during the day. At the peak, there is a footprint-shaped rock formation, which is considered sacred. Pilgrims and visitors alike appreciate both the spiritual significance and the natural beauty of the site.

Nuwara Eliya

Nuwara Eliya is located in the Central Highlands at 1,868m and is known for its cool climate and colonial charm. It’s about 170km east of Colombo and can be reached by train or bus – I definitely recommend taking the Kandy to Nuwara Eliya train as the route is unbelievably stunning! (it’s the same train route as Kandy to Ella). The area is popular for its tea plantations and nearby Horton Plains National Park, with a highlight being the World’s End Trek. The World’s End Trek is a 9km hike offers views of grasslands, forests, and a dramatic cliff drop. Nuwara Eliya also offers other activities like golfing, boating on Gregory Lake, and exploring local gardens. I met a lot of people heading that way so I imagine there’s a good community of travellers around there.

Sri Lanka Guides

hiking ella rock

Ella, Sri Lanka: A Guide

Ella is a gem tucked away in the lush greenery of Sri Lanka’s hill country. I got to spend 5 …
nine arch bridge sri lanka

Ultimate Guide for Travel in Sri Lanka

Sri Lanka is an incredible island country located in the Indian Ocean, just south of India. I spent three glorious …
best beaches in sri lanka

Best Beaches in Sri Lanka

When it comes to beaches, Sri Lanka has it all. From scuba diving to whale watching, surfing to sunbathing, there’s …
Galle

The 8 Best Things to Do in Galle, Sri Lanka

When people think about Galle, they usually imagine the infamous Lighthouse and nothing else. I nearly avoided the add journey …
sigiriya lions rock

Everything You Need To Know About Climbing Sigiriya

Sigiriya, or Lion Rock, is an ancient rock fortress located in the central plains of Sri Lanka. As one of …
kandy to ella train

The Kandy to Ella Train: The Ultimate Sri Lanka Experience

The Kandy to Ella train is one of the most scenic train rides in Sri Lanka and provides for a …

The post Ultimate Guide for Travel in Sri Lanka appeared first on Char's Footsteps.

]]>
https://www.charsfootsteps.com/travel/asia/sri-lanka/sri-lanka-itinerary/feed/ 0
Best Beaches in Sri Lanka https://www.charsfootsteps.com/travel/asia/sri-lanka/best-beaches-in-sri-lanka/?utm_source=rss&utm_medium=rss&utm_campaign=best-beaches-in-sri-lanka https://www.charsfootsteps.com/travel/asia/sri-lanka/best-beaches-in-sri-lanka/#respond Sat, 20 Apr 2024 09:20:16 +0000 https://www.charsfootsteps.com/?p=88 When it comes to beaches, Sri Lanka has it all. From scuba diving to whale watching, surfing to sunbathing, there’s something for everyone. During my 3 weeks stay in Sri Lanka, I got to spend 8 glorious days exploring various beaches in the south. There are many beaches to choose from, but these are the […]

The post Best Beaches in Sri Lanka appeared first on Char's Footsteps.

]]>
When it comes to beaches, Sri Lanka has it all. From scuba diving to whale watching, surfing to sunbathing, there’s something for everyone. During my 3 weeks stay in Sri Lanka, I got to spend 8 glorious days exploring various beaches in the south. There are many beaches to choose from, but these are the ones I got to visit and enjoyed.

Best Beaches in Sri Lanka by Activity

  • Mirissa Beach – nightlife, dolphin & whale watching
  • Weligama Beach – surfing, remote working and co-work spaces
  • Unawatuna Beach –
  • Hikkaduwa Beach – scuba diving, snorkelling and turtles
  • Bentota Beach – higher-end resorts
  • Tangalle Beach – Secluded and Off-the-beaten-track
  • Negombo Beach – water sports, city break from Colombo

Mirissa Beach

Mirissa is one of Sri Lanka’s most popular beach towns; famous for its long beach, nightlife and whale watching. Located in the Matara district of the Southern Province, Mirissa can be easily accessed by car or bus. I was able to catch a 6-hour bus directly from Ella down to Mirissa. If you’re travelling by train, the nearest train station is Weligama, approximately 2km away.

Mirissa is most famous for its blue whale watching, with the best time of year being between December to April. You’ll find a number of different Whale and Dolphin watching tours available along the beach. However, after hearing how tour operators regularly chase the whales for tourists, I decided against going on a tour.

black sand beach mirissa
One of the black sand beaches near Mirissa Beach

Mirissa Beach is also a great place to stay if you’re looking for nightlife. Out of all the beaches, I found Mirissa’s nightlife to be the best. From cute bars to live music on the beach, this hippie beach town will keep you entertained throughout your stay!

Coconut Tree Hill

Coconut Tree Hill is one of the most famous photo spots in the beaches of Sri Lanka. To access Coconut Tree Hill, you have to walk about 20 minutes down Mirissa beach or along Matara Road. Make sure to wear proper, stable shoes as you will have to climb up a fairly steep hill to reach the top for photos. As you would expect, there was a queue of people taking photos so prepare to wait a while.

After spending a few magical days in Mirissa, I took a tuk-tuk down the road to Weligama.

Weligama Beach

Weligama is a charming coastal town that’s known for it’s surfing for all abilities. There are a number of surfing options you can sign up for, whether it’s your first time (like mine!) or a seasoned surfer. One of my favourite things about Weligama was it’s beautiful bay, that was lined with coconut palm trees and local seafood eateries. Great for evening strolls!

Weligama has also become known in recent years for its co-working spaces. There’s a community here of remote workers, and long-term travellers, who have chosen Weligama as a place to work from. From this, you’ll be able to find a plethora of restaurants, cafes and bars to enjoy after a day on the beach, or a day working!

Unawatuna Beach

Along with Mirissa, Unawatuna is the other key beach town to visit in Sri Lanka. With beautiful beaches, great snorkelling, nightlife, many eateries and good transport links to surrounding areas, this is a great place to visit! You’ll also find a good range of accomodation here, from cheap backpacker hostels to upmarket hotels.

If you’re staying in Unawatuna, I would highly recommend visiting the Dutch-colonial town of Galle. Located just a short train or bus ride away, Galle is the perfect day trip from Unawatuna.

Another beach to look out for in Unawatuna is Jungle Beach. Again, it’s a great place to snorkel, relax and enjoy the tiki-style beach bars! I found Unawatuna also had good nightlife.

From my experience, I recommend using Mirissa or Unawatuna as a base and doing day trips to surrounding areas like Galle, Hikkadua and Weligama.

unawatuna beach sri lanka

Hikkaduwa Beach

I did a day trip to Hikkaduwa Beach and loved the combination of lively atmosphere with natural beauty! This vibrant stretch of coastline is known for its lively restaurants, bars, and shops, catering to a wide range of visitors. I mainly went for the snorkelling and to see the turtles, but I was so impressed with the cute coastal town itself. It was easy to grab the bus from Mirissa and spend the day marvelling at the stunning marine life, colourful fish, intricate coral formations and…the turtles!!

To see the turtles, go near Hikka by Tranz at Cinnanom and see them swim up to the shallow, rocky area and sand. Hikkaduwa Beach is also known for its diving schools and different surf lessons available. I didn’t book anything in advance but was able to go snorkelling after speaking to different shops along the coast.

Bentota Beaches

If you’re looking for a little more luxury, head to Bentota – home to many upmarket resorts and world-class hotels. Bentota is also famous for its spas and wellness centres, so be sure to . After having a traditional Sri Lankan massage, head to the stunning Bentota beach to relax. As I was on a backpacker budget, I never stayed here but it’s on my list if I ever get back to Sri Lanka!

Tangalle Beach

The beaches in Tangalle are truely hidden gems, home to unspoiled stretches of golden beach and crystal clear waters. It’s a great area to come for a quieter snorkelling and swimming experience, away from the more crowded spots in Sri Lanka. I also enjoyed exploring the surrounding fishing villages. You have a few beaches to choose from here, including Medaketiya beach and Silent beach. I found it interesting that despite being a short ride from Mirissa, the vibe of Tangalle was totally different. It felt more authentic and much more relaxed.

I went to Sri Lanka in February 2019, and with the increasing rise of social media, Tangalle Beach might be less untouched than when I went.

Negombo Beach

Negombo Beach is located an hour drive north of the capital, Colombo, making it a great day trip to escape the bustling city. It’s also very close to the international airport, so it’s worth visiting if you have a day to kill before or after a flight. The beach itself is known for it’s long stretch of pristine beach and activities. You can choose to partake in water sports like windsurfing and jet skiing. Or opt for a more chilled day with seaside restaurants or Ayurvedic massage spas. The beachfront is dotted with vibrant fishing boats and lively markets, which are fun to walk through.

Other Beaches to Consider

A few other beaches worth checking out include Nilaveli Beach and Arugam Bay. I didn’t have time to visit either, but these are beaches i’ve consistently heard good things about.

Arugam Bay is located on the eastern coast of Sri Lanka and is known for its world-class waves. If you’re looking for big swells, check out this area. The bay itself is also known for its laid-back vibe and stunning sunrises over the Indian Ocean.

Nilaveli Beach is known for its seclusion an serenity, with white sand and crystal clear waters. If you’re looking for a quiet, tranquil beach away from other tourists, this could be one to check out!

So whether you’re looking for something adventurous and active, or a more laid-back and secluded, Sri Lanka has beaches for everyone! I’ve just added all the beaches I got to experience during my time in Sri Lanka, but there are lots more to choose from. The whole south coast is full of cute beach towns that are easily accessible by bus, train or tuk tuk. Outside of the beaches, be sure to check out the famous Kandy to Ella train, Galle, Ella, Sigiriya and my full 3 week itinerary of Sri Lanka.

Sri Lanka Blogs

hiking ella rock

Ella, Sri Lanka: A Guide

Ella is a gem tucked away in the lush greenery of Sri Lanka’s hill country. I got to spend 5 …
nine arch bridge sri lanka

Ultimate Guide for Travel in Sri Lanka

Sri Lanka is an incredible island country located in the Indian Ocean, just south of India. I spent three glorious …
best beaches in sri lanka

Best Beaches in Sri Lanka

When it comes to beaches, Sri Lanka has it all. From scuba diving to whale watching, surfing to sunbathing, there’s …
Galle

The 8 Best Things to Do in Galle, Sri Lanka

When people think about Galle, they usually imagine the infamous Lighthouse and nothing else. I nearly avoided the add journey …
sigiriya lions rock

Everything You Need To Know About Climbing Sigiriya

Sigiriya, or Lion Rock, is an ancient rock fortress located in the central plains of Sri Lanka. As one of …
kandy to ella train

The Kandy to Ella Train: The Ultimate Sri Lanka Experience

The Kandy to Ella train is one of the most scenic train rides in Sri Lanka and provides for a …

The post Best Beaches in Sri Lanka appeared first on Char's Footsteps.

]]>
https://www.charsfootsteps.com/travel/asia/sri-lanka/best-beaches-in-sri-lanka/feed/ 0
The 8 Best Things to Do in Galle, Sri Lanka https://www.charsfootsteps.com/travel/asia/sri-lanka/galle/?utm_source=rss&utm_medium=rss&utm_campaign=galle https://www.charsfootsteps.com/travel/asia/sri-lanka/galle/#respond Tue, 20 Aug 2019 09:20:00 +0000 https://www.charsfootsteps.com/?p=86 When people think about Galle, they usually imagine the infamous Lighthouse and nothing else. I nearly avoided the add journey there for this very reason. However, Galle has so much more to offer than just the lighthouse and is a definite must-do if you’re in south Sri Lanka. Plus, it’s easy to get to from […]

The post The 8 Best Things to Do in Galle, Sri Lanka appeared first on Char's Footsteps.

]]>
When people think about Galle, they usually imagine the infamous Lighthouse and nothing else. I nearly avoided the add journey there for this very reason. However, Galle has so much more to offer than just the lighthouse and is a definite must-do if you’re in south Sri Lanka. Plus, it’s easy to get to from Colombo and the southern beaches.

Galle is just one of Sri Lanka’s many UNESCO World Heritage Sites. Built by the Dutch in the 17th century, Galle’s defining feature is the Fort (a walled, small city surrounded on three sides by the sea) and onshore Lighthouse. The Fort area has roughly 400 historic homes, churches, temples, mosques and government buildings.

Its Portuguese, Dutch and British roots are reflected throughout the narrow lanes filled with quaint restaurants, boutique hotels, museums, local artwork, shops and cafes. Whether you stay within the fort walls of the old town, or visit for a day trip, here are some of the best things to do in Galle.

Things to do in Galle

  • Walk round the Historic Fort
  • Photograph the famous Lighthouse
  • Relax on Lighthouse Beach
  • Visit the many museums
  • Watch the beautiful sunsets
  • Eat at the many cafes and restaurants
  • Shop in the boutiques and art galleries
  • Compare Galle’s Old Town vs New Town

The first thing I would recommend you do, is a walk around The Historic Fort. Beginning and ending at the Clock Tower, this 2.75km walk will take you around the entire fort, visiting many top sights along the way. I used the Lonely Planet‘s Self-Guided tour advice, which was fantastic. This was a great way to see what Galle has to offer, before venturing deeper in the Old Town.

Inside the Fort

The British-built Lighthouse can be found in the Southeastern Corner of the Fort and is the perfect photo opportunity. As with any popular sight, the best time to go for photos is first thing in the morning. By midday it was fairly busy. From here you can visit the Lighthouse Beach for a quick dip in the sea. The beach is quite small and there are many rocks offshore, but it was nice to have a quick cool down from the 35c heat.

Along from the Lighthouse is the Old Dutch Hospital. After being fully restored in 2006, the Old Dutch Hospital is now filled with shops and restaurants. It’s definitely worth checking this out for the views alone from its upper balcony.

There are also a number of museums you can visit within the Old Town. These include The National Museum, Marine Archeological Museum and the National Maritime Museum.

It’s worth staying in Galle until dusk to enjoy the stunning sunsets, particularly up along the Fort walls overlooking the ocean. Additionally, it will be cooler at this time too, making the walk easier.

Eating in Galle

The number of incredible places to eat here are endless! Galle offers a variety of different cuisines, from French and Italian restaurants to Asian.

Something I loved about Galle, is that most cafes and restaurants display local artwork, which is usually available for purchase. The cafe ‘Calorie Counter’ is an example of this. Despite the name, this cafe offered incredible food and large portions of more Western-style food – a lovely change after 3 weeks of (albeit delicious) rice and curry.

calorie counter galle
Local artwork displayed in cafe calorie counter

Galle’s New Town

Galle’s new town is worth a visit if you have time, with the main attraction here being the Dutch Market. Located on Main Street, under a 300-year-old columned roof, this lively market is filled with a variety of fruit and veg. I really enjoyed walking through here and soaking up the atmosphere. However, beware of prices being heavily inflated for tourists.

Galle International Cricket Stadium is also a great sight to see. You will pass this on your way to the Old Town.

Getting to Galle

Galle can be reached by car or private taxis along the Southern Expressway. However for a more authentic, and significantly cheaper experience, you can use trains and buses.

Trains along the Colombo-Matara line are some of the most scenic in Sri Lanka (along with the Kandy to Ella Train), making this a great way to travel to Galle. There are at least 6 express trains a day on this line and you can check out prices and times here: http://www.seat61.com. If you’re less flexible with time, it might be worth catching a bus. These run more frequently than trains.

There are plenty of local buses that link all the towns along the coast, with services operating roughly every 10 – 20 minutes. Buses are unbelievably cheap in Sri Lanka, with prices between coastal towns ranging from Rs 28-143 (£0.13-0.66, $0.16-0.81). Air Conditioned buses, known as EX001, are available too but are less frequent. These typically cost Rs 400-550 (£1.86-2.56, $2.25-3.10). Buses to Galle arrive and depart from the bus station on Main Street. This is hard to miss given the sheer number of buses going through this station. I found this bus station overwhelming, however, everyone was extremely helpful in showing me which bus to take.

Related Post: Climbing Sigiriya

Galle is a must see if you’re visiting the south! You’ll forget you’re in Sri Lanka, whilst you stroll around the Dutch lanes within the Fort. Let me know if you make a trip to this beautiful little gem.

Happy Travels x

Sri Lanka Blogs

hiking ella rock

Ella, Sri Lanka: A Guide

Ella is a gem tucked away in the lush greenery of Sri Lanka’s hill country. I got to spend 5 …
nine arch bridge sri lanka

Ultimate Guide for Travel in Sri Lanka

Sri Lanka is an incredible island country located in the Indian Ocean, just south of India. I spent three glorious …
best beaches in sri lanka

Best Beaches in Sri Lanka

When it comes to beaches, Sri Lanka has it all. From scuba diving to whale watching, surfing to sunbathing, there’s …
Galle

The 8 Best Things to Do in Galle, Sri Lanka

When people think about Galle, they usually imagine the infamous Lighthouse and nothing else. I nearly avoided the add journey …
sigiriya lions rock

Everything You Need To Know About Climbing Sigiriya

Sigiriya, or Lion Rock, is an ancient rock fortress located in the central plains of Sri Lanka. As one of …
kandy to ella train

The Kandy to Ella Train: The Ultimate Sri Lanka Experience

The Kandy to Ella train is one of the most scenic train rides in Sri Lanka and provides for a …

The post The 8 Best Things to Do in Galle, Sri Lanka appeared first on Char's Footsteps.

]]>
https://www.charsfootsteps.com/travel/asia/sri-lanka/galle/feed/ 0
Everything You Need To Know About Climbing Sigiriya https://www.charsfootsteps.com/travel/asia/sri-lanka/sigiriya/?utm_source=rss&utm_medium=rss&utm_campaign=sigiriya https://www.charsfootsteps.com/travel/asia/sri-lanka/sigiriya/#comments Mon, 19 Aug 2019 09:34:38 +0000 https://www.charsfootsteps.com/?p=94 Sigiriya, or Lion Rock, is an ancient rock fortress located in the central plains of Sri Lanka. As one of many UNESCO World Heritage Sites in the country, it’s a must-do if you’re visiting Sri Lanka. Boasting an extensive network of surrounding gardens and a museum, Sigiriya has a lot to offer. Standing at over […]

The post Everything You Need To Know About Climbing Sigiriya appeared first on Char's Footsteps.

]]>
Sigiriya, or Lion Rock, is an ancient rock fortress located in the central plains of Sri Lanka. As one of many UNESCO World Heritage Sites in the country, it’s a must-do if you’re visiting Sri Lanka. Boasting an extensive network of surrounding gardens and a museum, Sigiriya has a lot to offer.

Standing at over 200 meters, with over 1,200 steps, Sigiriya usually takes 1.5 to 3 hours to climb and descent. Despite being a strenuous hike, and scary for height-phobics like me, it was an incredible experience that I recommend to anyone! The site is open daily from 7am to 5:30pm. Early morning and late afternoon are the best times to visit for avoiding the heat and crowds. It cost me $30 usd (February 2019) as a foreigner, or Rs50 for locals. Update for 2025: entry for Sigiriya now costs $35 USD for adults and $20 USD for children. Prices differ for Sri Lankan locals.

Once I began researching my trip to Sri Lanka, I knew climbing Sigiriya was high on my to-do list. However given my fear of heights, and the fact I’d be alone as a solo backpacker, I wasn’t sure how doable this would be. I hope this guide helps any other height-phobics know what to expect from climbing Lion’s Rock!

Powered by GetYourGuide

My Experience Climbing Sigiriya

My first stop in Sri Lanka was Dambulla – a great base to explore the wider areas, including Sigiriya and Polonnaruwa. I met two guys in my homestay who kindly let me join their Sigiriya trip. We decided to book a private driver, who not only navigated us to our bucket-list destinations brilliantly, but acted as a knowledgeable tour guide! I’d highly recommend considering a driver for this part of Sri Lanka, particularly if you’re short on time. Public transport is more limited here compared to other areas of the country and the sites are spread out.

Climbing Sigiriya

After a 20 minute drive from Dambulla, in the torrential rain, we arrived at Sigiriya. It happened to be Sri Lanka’s Independence Day, so without realising it, I’d chosen the busiest day of the year to visit. Because of this, it took over 2 hours to ascent the rock, with the entire route being congested with queues of people. Take my photos with a pinch of salt, as it’s apparently never normally this busy. The constant queuing worsened my fears, as we had to wait on scary parts of the climb for long periods of time.

Starting the Sigiriya Climb

The start of the climb takes you up several hundred stairs, surrounded by stunning scenery. From a height’s perspective, this part of the climb was fine. I made the rookie mistake of not bringing enough food or water, which I regretted by the time we got to the top. Luckily as it was overcast and raining, I didn’t struggle too much with the heat! The first part of this section was easy and we were moving at a good pace.

The sheer number of people climbing that day meant that within 15 minutes of climbing, we joined a massive queue of people. The route remained this crowded for the rest of the climb. The surrounding views as we climbed were incredible and you can see for miles ahead with each step up you take. However, moving at snail pace meant that the daunting spiral staircase looming ahead made my nerves. I highly recommend going early in the morning to avoid congestion, as this would have been a lot easier mentally had we been able to power walk our way up.

Powered by GetYourGuide

The Famous Spiral Staircase of Sigiriya

The spiral staircase takes you to murals in the cave, known as the Frescoes. There are only 23 left out of the original 500, and are really beautiful to look at. You’re not allowed to take photos of these, and there are people patrolling to make sure you don’t. However, it’s worth noting that this part of the route is optional! If you have bad vertigo and don’t want to climb this staircase, you don’t have to. It won’t take you to the next part of the route. If I had known this ahead of time I definitely would have avoided it as I found this section very unnerving with my fear of heights.

Spiral Staircase Sigiriya
Spiral Staircase

After completing this part of the climb, we arrived at the foot of Lion Staircase. This is a great place to stop and take a break before tackling the summit. At this point, I noticed some people turn round and head back down…I nearly joined them after seeing the Lion staircase in person.

Lion Staircase – The Summit

In all honesty, I found the climb up the lion staircase terrifying. The stairs were slippery from the rain and completely rammed with people. We often had to stand and wait, which prolonged the journey up. My tip is to really focus on looking up and holding on the the railing (or wall depending which side you’re on) for balance. Again, I believe it’s never usually this busy. If it were empty, I would have just powered up and got it over with quickly.

Lion Staircase
Sigiriya Lion Staircase

After a nerve-wracking 15 minutes, I finally made it to the top! The unbelievable views at the top absolutely made the summit worth it. I spent about 30 minutes walking around the stone ruins, gardens and pools! It was fascinating to hear about the history of the palace, so I’d recommend going with a tour guide or spending time in the museum below beforehand. This area is completely exposed to the elements, so consider bringing an umbrella, hat or other sun protection.

After a lovely experience, I wobbled my way down and started the descent down Sigiriya. Going down was much easier and the traffic of people was constantly moving. It was also easier to enjoy all the stunning surroundings as you walked down, so be prepared to stop a lot for photos.

Sigiriya Lion Staircase
Sigiriya Lion Staircase

Tips for Climbing Lion’s Rock

  • Pick a day/time that isn’t extremely busy. This could mean early in the morning (good to avoid the hottest time of day too) or on a weekday.
  • Bring water and snacks with you. Refreshments are available near the main entrance, however you won’t be able to buy anything within the site.
  • Use a bathroom ahead of time near the entrance. There are no toilet facilities within the site.
  • Lather up in high factor sun cream. The route is largely exposed to the sun, especially at the top! I got a bit burnt, even though it was cloudy, rainy weather.
  • Wear comfortable walking shoes. I wore trainers, but I saw lots of people walking in flip flops. Given the time spent on your feet, I’d recommend wearing proper shoes.
  • Consider taking an umbrella – again, there’s no shade during the summit or at the top, so it’ll help protect you from the sun (or rain in my case).
  • If you’re scared of heights it is important to factor in that some areas are steep or require going up nerve-wracking stairs. If you go ahead, take it one step at a time and break up the journey by stopping at rest points along the route. If I can do it, you can.

I hope anyone reading this with a fear of heights feels reassured that climbing Sigiriya is absolutely possible. Just break the route up by resting at each stopping point. The photos of Sigiriya really don’t do it justice, so definitely go see it for yourself.

Sigiriya FAQs

How to Get to Sigiriya

The easiest way to get to Sigiriya is to drive or hire a taxi, particularly if you’re staying somewhere nearby like Dambulla. For public transport, the nearest train station to Sigiriya is Habrana. This is roughly 17km away, so you’ll need to catch a taxi from the station to the rock itself. There are trains going from major transport areas like Colombo Fort and Kandy. Aside from trains, you can get public buses to Sigiriya and this is likely your cheapest option too. Most major transport areas have public buses going to Dambulla, and from there, you can catch a second bus. I was lazy and got a cab!

What time is Sigiriya open?

Sigiriya is open daily from 7:00 AM to 5:30 PM – with the last entrance allowed at 5:00 PM. Be sure to get there early though, as the midday heat can be intense and make climbing it harder. I would also strongly advise checking for any Sri Lankan public holidays and work around them. I went up during Sri Lankan Independence Day and it was busy to say the least!

How High is Sigiriya?

Sigiriya is approximately 180m high! It looks very impressive when you first arrive in the area and the views from the top are equally incredible!

What Type of Rock is Sigiriya Rock Made of?

Sigiriya is primarily granite

How Long Does It Take to Climb Sigiriya?

With over 1,200 steps, Sigiriya usually takes 1.5 – 3 hours for the climb up and descent back down. This will largely depend on how busy the route is, your fitness levels and the time you spend at the top. It’s worth taking it at a gentle pace, and factoring in steep bits, so give yourself plenty of time! The views during the climb and at the top are also breathtaking, so it’d be a shame to rush past this.

What Else Is There To Do Besides Lion Rock?

Outside of climbing Sigiriya, you can take tours around the stunning landscaped gardens and fountain areas located at the base of the rock. There is also a museum that delves into the history of Sigiryia.

After my stay in Dambulla, I made my way down to Kandy for two days. From there, I did the epic Kandy to Ella train to Ella, then onto the beaches before ending my trip in Galle.

Other Sri Lanka Guides

hiking ella rock

Ella, Sri Lanka: A Guide

Ella is a gem tucked away in the lush greenery of Sri Lanka’s hill …
nine arch bridge sri lanka

Ultimate Guide for Travel in Sri Lanka

Sri Lanka is an incredible island country located in the Indian Ocean, just south …
best beaches in sri lanka

Best Beaches in Sri Lanka

When it comes to beaches, Sri Lanka has it all. From scuba diving to …
Galle

The 8 Best Things to Do in Galle, Sri Lanka

When people think about Galle, they usually imagine the infamous Lighthouse and nothing else …
sigiriya lions rock

Everything You Need To Know About Climbing Sigiriya

Sigiriya, or Lion Rock, is an ancient rock fortress located in the central plains …
kandy to ella train

The Kandy to Ella Train: The Ultimate Sri Lanka Experience

The Kandy to Ella train is one of the most scenic train rides in …

The post Everything You Need To Know About Climbing Sigiriya appeared first on Char's Footsteps.

]]>
https://www.charsfootsteps.com/travel/asia/sri-lanka/sigiriya/feed/ 5
The Kandy to Ella Train: The Ultimate Sri Lanka Experience https://www.charsfootsteps.com/travel/asia/sri-lanka/kandy-to-ella-train/?utm_source=rss&utm_medium=rss&utm_campaign=kandy-to-ella-train https://www.charsfootsteps.com/travel/asia/sri-lanka/kandy-to-ella-train/#comments Thu, 25 Jul 2019 16:26:07 +0000 https://www.charsfootsteps.com/?p=58 The Kandy to Ella train is one of the most scenic train rides in Sri Lanka and provides for a unique journey across the country. Here are some tips on how to get 2nd class tickets (best for photos).

The post The Kandy to Ella Train: The Ultimate Sri Lanka Experience appeared first on Char's Footsteps.

]]>
The famous blue train from Kandy to Ella is one of the most scenic and recognisable journeys in Sri Lanka. With breathtaking views of tea plantations, quaint villages and atmospheric mountains, it’s a must-do whilst visiting the country. The train ride takes around 7-9 hours, covering 144km of distance between the two popular regions. After spending a night in Kandy, I made my way to Ella, largely unaware of what the journey would hold. So I wanted to create a guide for anyone looking to do this stunning journey!

Kandy to Ella Train Tickets

There are a few different ways to purchase your train tickets, along with various carriage and class options:

Buying Tickets at The Station

You can buy your train tickets from the respective train stations, if you’re in Kandy or Ella. This is convenient if you’re planning your trip as you go – as I was. However, if you go down this route, be prepared for long queues and some ticket options selling out! Alternatively, you can ask at your accomodation and they can get in touch with ticket sellers. I originally tried this route but the ticket sellers had sold out. Be mindful if you’re travelling during peak season as it does get very busy.

Buying Your Tickets Online

You can also buy your train tickets online. For information on train timetables and schedule times, visit the official Sri Lankan railway site. To buy your tickets online, check out one of the many third party agencies who sell them; e.g. GetYourGuide, 12go.asia or Visit Sri Lanka Tours. If you find one agency has sold out of tickets, be sure to still check out other third parties who might have some left.

Powered by GetYourGuide

Unreserved vs Reserved Carriages

tea plantation sri lanka

Unreserved Tickets

Tickets for unreserved seats are only available for 2nd and 3rd class seat and CAN’T be booked in advance. You have to buy them on the day of travel and, unlike reserved tickets, they can’t sell out. Therefore, once you’ve bought your unreserved ticket, you can hop on any train that day.

Unreserved carriages are often busy, with people standing throughout the aisles and doorways. Getting a seat is usually dependant on how busy the train is that day and the route you’re taking (the Kandy to Ella train is extremely popular for example). It’ll be easier to get a seat if you’re joining at the starting station.

Reserved Tickets

Longer train journeys typically have designated 2nd class reserved carriages, and sometimes reserved 3rd class carriages. Some will also have a 1st class carriage – these are always reserved. Tickets for reserved seats will become available 30 days in advance. I would recommend buying them as far in advance as possible as they typically sell out quickly.

Reserved tickets guarantee a seat and will come with a designated seat number. Furthermore, you’ll be able to enjoy a quieter journey as these carriage don’t allow people to stand in them. If you hear the train if full, it just means the reserved tickets have sold out. There will always be unreserved tickets left as these can’t sell out (you just won’t be guaranteed a seat).

Kandy to Ella Train Advice & Information

The Kandy to Ella train is one of the most popular in Sri Lanka and you can expect that this will be busy throughout the year. The journey takes over 7 hours, so you if you’re looking for optimum comfort during this time, opt for 1st class reserved tickets. This will guarantee you a seat, space for your bags and air con.

However, for the ultimate Kandy to Ella experience (photos, scenery and all), buy 2nd class carriage tickets. Here you’ll be able to enjoy the incredible views through open windows and doors, whilst having the experience to dangle your legs out the doorways. The 1st and 3rd carriages will have closed windows and doors, therefore, taking photos will be harder.

Tea Plantations Sri Lanka

Best Option for Photos and The View: 2nd Class Carriage

Buy a reserved second class ticket. If you know your travel dates in advance, this will be your best option. A reserved ticket will guarantee you a seat (with a ceiling fan). Plus you’ll be able to open the windows and sit in the doorways to get the best views and pictures.

For unreserved second class tickets, you will have to purchase these on the day at the station. If you’re hoping to get a seat (and bag space), I suggest you get a tuk tuk to Perideniya Station. Perideniya Station is 10 minutes away from Kandy, and trains coming from Colombo will stop here before Kandy. You will be able to get a seat more easily here as fewer people will be getting on. Many people will be getting off at Kandy too, increasing your chances of getting a seat

OR

The less favourable option for getting an unreserved seat on the Kandy to Ella train, is queueing at Kandy station first thing in the morning. This is the route I took. I queued for 45 minutes in the sun and bought my unreserved second class ticket for a train that morning. It’s worth noting the 3rd class ticket queue was practically empty.

Tips for the train ride

  • Pack water and snacks! I arrived at Ella station very dehydrated! – local Sri Lankans hop on at different stations with ice coolers and buckets of food/drinks but you can’t guarantee getting what you want.
  • Bring small change – to buy food/drinks on the train. Locals jump on at different stops and provide lots of delicious, local foods.
  • Make sure you’ve got a fully charged phone/camera to take lots of amazing photos and videos.
  • Bring entertainment – Despite the incredible views, the Kandy to Ella train takes over 7 hours (longer if you start at an earlier station like Colombo). Although the views are stunning, you’ll appreciate having music/podcast/book to help break up the journey.
  • Use toilets beforehand – there are toilets on board but it’s a tight squeeze standing in the aisles and corridors. Trying to walk down the carriages to find the bathroom (and making your way back again) would be a mission. Also I heard they weren’t that pleasant to visit several hours into the ride…

Highlights Along the Way

  • Tea Plantations: You’ll spend several hours of the journey travelling through tea plantations. These are so stunning and the air smells heavenly.
  • Nine Arch Bridge: One of the most iconic things to see in Ella is the Nine Arch Bridge. You should be able to get a glimpse of the bridge as you start approaching the Ella region.
  • Waterfalls: Amongst the hillsides are several waterfalls, including the Ramboda Falls and the Dunhinda Falls.

If you’re looking for more tips of travel in Sri Lanka, I have a few guides on Climbing Sigiriya Lion Rock, Ella, the beaches and visiting Galle!

Sri Lanka Blogs

hiking ella rock

Ella, Sri Lanka: A Guide

Ella is a gem tucked away in the lush greenery of Sri Lanka’s hill country. I got to spend 5 …
nine arch bridge sri lanka

Ultimate Guide for Travel in Sri Lanka

Sri Lanka is an incredible island country located in the Indian Ocean, just south of India. I spent three glorious …
best beaches in sri lanka

Best Beaches in Sri Lanka

When it comes to beaches, Sri Lanka has it all. From scuba diving to whale watching, surfing to sunbathing, there’s …
Galle

The 8 Best Things to Do in Galle, Sri Lanka

When people think about Galle, they usually imagine the infamous Lighthouse and nothing else. I nearly avoided the add journey …
sigiriya lions rock

Everything You Need To Know About Climbing Sigiriya

Sigiriya, or Lion Rock, is an ancient rock fortress located in the central plains of Sri Lanka. As one of …
kandy to ella train

The Kandy to Ella Train: The Ultimate Sri Lanka Experience

The Kandy to Ella train is one of the most scenic train rides in Sri Lanka and provides for a …

The post The Kandy to Ella Train: The Ultimate Sri Lanka Experience appeared first on Char's Footsteps.

]]>
https://www.charsfootsteps.com/travel/asia/sri-lanka/kandy-to-ella-train/feed/ 1