accordion.1840403ce81de408c749.bundle.min.js
4 years ago
accordion.a037e351fac33e9c9dfc.bundle.js
4 years ago
admin-feedback.js
4 years ago
admin-feedback.min.js
4 years ago
admin-modules.js
4 years ago
admin-modules.min.js
4 years ago
admin-top-bar.js
4 years ago
admin-top-bar.min.js
4 years ago
admin.js
4 years ago
admin.min.js
4 years ago
alert.85332a4bfb582d516461.bundle.js
4 years ago
alert.cbc2a0fee74ee3ed0419.bundle.min.js
4 years ago
app-loader.js
4 years ago
app-loader.min.js
4 years ago
app-packages.js
4 years ago
app-packages.min.js
4 years ago
app.js
4 years ago
app.min.js
4 years ago
app.min.js.LICENSE.txt
4 years ago
b5be57139d4edd0d5633.bundle.js
4 years ago
beta-tester.js
4 years ago
beta-tester.min.js
4 years ago
common-modules.js
4 years ago
common-modules.min.js
4 years ago
common.js
4 years ago
common.min.js
4 years ago
container-converter.js
4 years ago
container-converter.min.js
4 years ago
container.e026b16a99db8a3987c9.bundle.min.js
4 years ago
container.f3a37a5bf3c787312748.bundle.js
4 years ago
counter.02cef29c589e742d4c8c.bundle.min.js
4 years ago
counter.c75eea9549b9f8026ad8.bundle.js
4 years ago
editor-document.js
4 years ago
editor-document.min.js
4 years ago
editor-modules.js
4 years ago
editor-modules.min.js
4 years ago
editor.js
4 years ago
editor.min.js
4 years ago
elementor-admin-bar.js
4 years ago
elementor-admin-bar.min.js
4 years ago
fe4cf752908671676148.bundle.min.js
4 years ago
frontend-modules.js
4 years ago
frontend-modules.min.js
4 years ago
frontend.js
4 years ago
frontend.min.js
4 years ago
gutenberg.js
4 years ago
gutenberg.min.js
4 years ago
image-carousel.b69ea9450ea7e942e017.bundle.js
4 years ago
image-carousel.db284b09c0f8a8f1c44d.bundle.min.js
4 years ago
kit-library.4a93dd22359db6c3e7f9.bundle.min.js
4 years ago
kit-library.4b8e9bb062f992326c78.bundle.js
4 years ago
lightbox.2b2c155d6ec60974d8c4.bundle.min.js
4 years ago
lightbox.fe7d7981b2527f42f605.bundle.js
4 years ago
new-template.js
4 years ago
new-template.min.js
4 years ago
onboarding.6a289d52dcf568139a7d.bundle.min.js
4 years ago
onboarding.eff243c8052ee52943bc.bundle.js
4 years ago
preloaded-modules.js
4 years ago
preloaded-modules.min.js
4 years ago
progress.62211c8098d91fc19c5f.bundle.js
4 years ago
progress.ca55d33bb06cee4e6f02.bundle.min.js
4 years ago
tabs.37d5b4877cdb51ea91e9.bundle.min.js
4 years ago
tabs.973c14c2ee401e66e192.bundle.js
4 years ago
text-editor.289ae80d76f0c5abea44.bundle.min.js
4 years ago
text-editor.533215eb763ebfb3a70c.bundle.js
4 years ago
text-path.15d47ed8e5e3031f9610.bundle.js
4 years ago
text-path.9f18ebdea5ac00d653e5.bundle.min.js
4 years ago
toggle.56f8ace4b1e830c02fc5.bundle.min.js
4 years ago
toggle.66e1aea86557ee6b7fd9.bundle.js
4 years ago
video.255c225d20f04576d1bf.bundle.js
4 years ago
video.d86bfd0676264945e968.bundle.min.js
4 years ago
web-cli.js
4 years ago
web-cli.min.js
4 years ago
webpack.runtime.js
4 years ago
webpack.runtime.min.js
4 years ago
wp-audio.75f0ced143febb8cd31a.bundle.min.js
4 years ago
wp-audio.8d458e51b4543ed99c04.bundle.js
4 years ago
text-path.15d47ed8e5e3031f9610.bundle.js
277 lines
| 1 | /*! elementor - v3.5.6 - 21-03-2022 */ |
| 2 | "use strict"; |
| 3 | (self["webpackChunkelementor"] = self["webpackChunkelementor"] || []).push([["text-path"],{ |
| 4 | |
| 5 | /***/ "../modules/shapes/assets/js/frontend/handlers/text-path.js": |
| 6 | /*!******************************************************************!*\ |
| 7 | !*** ../modules/shapes/assets/js/frontend/handlers/text-path.js ***! |
| 8 | \******************************************************************/ |
| 9 | /***/ ((__unused_webpack_module, exports, __webpack_require__) => { |
| 10 | |
| 11 | |
| 12 | |
| 13 | Object.defineProperty(exports, "__esModule", ({ |
| 14 | value: true |
| 15 | })); |
| 16 | exports["default"] = void 0; |
| 17 | |
| 18 | var _utils = __webpack_require__(/*! elementor-frontend/utils/utils */ "../assets/dev/js/frontend/utils/utils.js"); |
| 19 | |
| 20 | class TextPathHandler extends elementorModules.frontend.handlers.Base { |
| 21 | getDefaultSettings() { |
| 22 | return { |
| 23 | selectors: { |
| 24 | pathContainer: '.e-text-path', |
| 25 | svg: '.e-text-path > svg' |
| 26 | } |
| 27 | }; |
| 28 | } |
| 29 | |
| 30 | getDefaultElements() { |
| 31 | const { |
| 32 | selectors |
| 33 | } = this.getSettings(); |
| 34 | const element = this.$element[0]; |
| 35 | return { |
| 36 | widgetWrapper: element, |
| 37 | pathContainer: element.querySelector(selectors.pathContainer), |
| 38 | svg: element.querySelector(selectors.svg), |
| 39 | textPath: element.querySelector(selectors.textPath) |
| 40 | }; |
| 41 | } |
| 42 | /** |
| 43 | * Initialize the object. |
| 44 | * |
| 45 | * @returns {void} |
| 46 | */ |
| 47 | |
| 48 | |
| 49 | onInit() { |
| 50 | this.elements = this.getDefaultElements(); |
| 51 | this.fetchSVG().then(() => { |
| 52 | // Generate unique IDs using the wrapper's `data-id`. |
| 53 | this.pathId = `e-path-${this.elements.widgetWrapper.dataset.id}`; |
| 54 | this.textPathId = `e-text-path-${this.elements.widgetWrapper.dataset.id}`; |
| 55 | |
| 56 | if (!this.elements.svg) { |
| 57 | return; |
| 58 | } |
| 59 | |
| 60 | this.initTextPath(); |
| 61 | }); |
| 62 | } |
| 63 | /** |
| 64 | * Fetch & Inject the SVG markup. |
| 65 | * |
| 66 | * @return {Promise} |
| 67 | */ |
| 68 | |
| 69 | |
| 70 | fetchSVG() { |
| 71 | const { |
| 72 | url |
| 73 | } = this.elements.pathContainer.dataset; |
| 74 | |
| 75 | if (!url || !url.endsWith('.svg')) { |
| 76 | return Promise.reject(url); |
| 77 | } |
| 78 | |
| 79 | return fetch(url).then(res => res.text()).then(svg => { |
| 80 | this.elements.pathContainer.innerHTML = svg; // Re-initialize the elements, so the SVG tag will be added. |
| 81 | |
| 82 | this.elements = this.getDefaultElements(); |
| 83 | }); |
| 84 | } |
| 85 | /** |
| 86 | * Gets a text offset (relative to the starting point) as a string or int, and set it as percents to the |
| 87 | * `startOffset` attribute of the `<textPath>` element. |
| 88 | * |
| 89 | * @param offset {string|int} The text start offset. |
| 90 | * |
| 91 | * @returns {void} |
| 92 | */ |
| 93 | |
| 94 | |
| 95 | setOffset(offset) { |
| 96 | if (!this.elements.textPath) { |
| 97 | return; |
| 98 | } |
| 99 | |
| 100 | if (this.isRTL()) { |
| 101 | offset = 100 - parseInt(offset); |
| 102 | } |
| 103 | |
| 104 | this.elements.textPath.setAttribute('startOffset', offset + '%'); |
| 105 | } |
| 106 | /** |
| 107 | * Handle element settings changes. |
| 108 | * |
| 109 | * @param setting {Object} The settings object from the editor. |
| 110 | * |
| 111 | * @returns {void} |
| 112 | */ |
| 113 | |
| 114 | |
| 115 | onElementChange(setting) { |
| 116 | const { |
| 117 | start_point: startPoint, |
| 118 | text |
| 119 | } = this.getElementSettings(); |
| 120 | |
| 121 | switch (setting) { |
| 122 | case 'start_point': |
| 123 | this.setOffset(startPoint.size); |
| 124 | break; |
| 125 | |
| 126 | case 'text': |
| 127 | this.setText(text); |
| 128 | break; |
| 129 | |
| 130 | case 'text_path_direction': |
| 131 | this.setOffset(startPoint.size); |
| 132 | this.setText(text); |
| 133 | break; |
| 134 | |
| 135 | default: |
| 136 | break; |
| 137 | } |
| 138 | } |
| 139 | /** |
| 140 | * Attach a unique ID to the `path` element in the SVG, based on the container's ID. |
| 141 | * This function selects the first `path` with a `data-path-anchor` attribute, or defaults to the first `path` element. |
| 142 | * |
| 143 | * @returns {void} |
| 144 | */ |
| 145 | |
| 146 | |
| 147 | attachIdToPath() { |
| 148 | // Prioritize the custom `data` attribute over the `path` element, and fallback to the first `path`. |
| 149 | const path = this.elements.svg.querySelector('[data-path-anchor]') || this.elements.svg.querySelector('path'); |
| 150 | path.id = this.pathId; |
| 151 | } |
| 152 | /** |
| 153 | * Initialize & build the SVG markup of the widget using the settings from the panel. |
| 154 | * |
| 155 | * @returns {void} |
| 156 | */ |
| 157 | |
| 158 | |
| 159 | initTextPath() { |
| 160 | const { |
| 161 | start_point: startPoint |
| 162 | } = this.getElementSettings(); |
| 163 | const text = this.elements.pathContainer.dataset.text; |
| 164 | this.attachIdToPath(); // Generate the `textPath` element with its settings. |
| 165 | |
| 166 | this.elements.svg.innerHTML += ` |
| 167 | <text> |
| 168 | <textPath id="${this.textPathId}" href="#${this.pathId}"></textPath> |
| 169 | </text> |
| 170 | `; // Regenerate the elements object to have access to `this.elements.textPath`. |
| 171 | |
| 172 | this.elements.textPath = this.elements.svg.querySelector(`#${this.textPathId}`); |
| 173 | this.setOffset(startPoint.size); |
| 174 | this.setText(text); |
| 175 | } |
| 176 | /** |
| 177 | * Sets the text on the SVG path, including the link (if set) and its properties. |
| 178 | * |
| 179 | * @param newText {string} The new text to put in the text path. |
| 180 | * |
| 181 | * @returns {void} |
| 182 | */ |
| 183 | |
| 184 | |
| 185 | setText(newText) { |
| 186 | var _this$getElementSetti; |
| 187 | |
| 188 | const { |
| 189 | url, |
| 190 | is_external: isExternal, |
| 191 | nofollow |
| 192 | } = (_this$getElementSetti = this.getElementSettings()) === null || _this$getElementSetti === void 0 ? void 0 : _this$getElementSetti.link; |
| 193 | const target = isExternal ? '_blank' : '', |
| 194 | rel = nofollow ? 'nofollow' : ''; // Add link attributes. |
| 195 | |
| 196 | if (url) { |
| 197 | newText = `<a href="${(0, _utils.escapeHTML)(url)}" rel="${rel}" target="${target}">${(0, _utils.escapeHTML)(newText)}</a>`; |
| 198 | } // Set the text. |
| 199 | |
| 200 | |
| 201 | this.elements.textPath.innerHTML = newText; // Remove the cloned element if exists. |
| 202 | |
| 203 | const existingClone = this.elements.svg.querySelector(`#${this.textPathId}-clone`); |
| 204 | |
| 205 | if (existingClone) { |
| 206 | existingClone.remove(); |
| 207 | } // Reverse the text if needed. |
| 208 | |
| 209 | |
| 210 | if (this.shouldReverseText()) { |
| 211 | // Keep an invisible selectable copy of original element for better a11y. |
| 212 | const clone = this.elements.textPath.cloneNode(); |
| 213 | clone.id += '-clone'; |
| 214 | clone.classList.add('elementor-hidden'); |
| 215 | clone.textContent = newText; |
| 216 | this.elements.textPath.parentNode.appendChild(clone); |
| 217 | this.reverseToRTL(); |
| 218 | } |
| 219 | } |
| 220 | /** |
| 221 | * Determine if the text direction of the widget should be RTL or not, based on the site direction and the widget's settings. |
| 222 | * |
| 223 | * @returns {boolean} |
| 224 | */ |
| 225 | |
| 226 | |
| 227 | isRTL() { |
| 228 | const { |
| 229 | text_path_direction: direction |
| 230 | } = this.getElementSettings(); |
| 231 | let isRTL = elementorFrontend.config.is_rtl; |
| 232 | |
| 233 | if (direction) { |
| 234 | isRTL = 'rtl' === direction; |
| 235 | } |
| 236 | |
| 237 | return isRTL; |
| 238 | } |
| 239 | /** |
| 240 | * Determine if it should RTL the text (reversing it, etc.). |
| 241 | * |
| 242 | * @returns {boolean} |
| 243 | */ |
| 244 | |
| 245 | |
| 246 | shouldReverseText() { |
| 247 | return this.isRTL() && -1 === navigator.userAgent.indexOf('Firefox'); |
| 248 | } |
| 249 | /** |
| 250 | * Reverse the text path to support RTL. |
| 251 | * |
| 252 | * @returns {void} |
| 253 | */ |
| 254 | |
| 255 | |
| 256 | reverseToRTL() { |
| 257 | // Make sure to use the inner `a` tag if exists. |
| 258 | let parentElement = this.elements.textPath; |
| 259 | parentElement = parentElement.querySelector('a') || parentElement; // Catch all RTL chars and reverse their order. |
| 260 | |
| 261 | const pattern = /([\u0591-\u07FF\u200F\u202B\u202E\uFB1D-\uFDFD\uFE70-\uFEFC\s$&+,:;=?@#|'<>.^*()%!-]+)/ig; // Reverse the text. |
| 262 | |
| 263 | parentElement.textContent = parentElement.textContent.replace(pattern, word => { |
| 264 | return word.split('').reverse().join(''); |
| 265 | }); // Add a11y attributes. |
| 266 | |
| 267 | parentElement.setAttribute('aria-hidden', true); |
| 268 | } |
| 269 | |
| 270 | } |
| 271 | |
| 272 | exports["default"] = TextPathHandler; |
| 273 | |
| 274 | /***/ }) |
| 275 | |
| 276 | }]); |
| 277 | //# sourceMappingURL=text-path.15d47ed8e5e3031f9610.bundle.js.map |