ifnex/03_WordPress/wp-includes/js/customize-selective-refresh.min.js
Kazem Alghasi f1d5667fe8 feat(deploy): preflight + smoke-test + UAT checklist (phases 3.9.1–3.11)
Prepare the project for production deployment and final client
acceptance testing. Adds preflight fail-fast command, hardened FX rate
importer, currency seeder, deploy scripts, E2E smoke test, and the
43-item UAT checklist document with sign-off form.

Key changes:

- Phase 3.9.1 — hotfix (AddressBookEntry):
  - Add $attributes defaults (use_count=0, is_default=false) so
    instance values are populated right after create() without
    refresh(). Resolves the red test
    `it_increments_use_count_and_sets_last_used_at`.

- Phase 3.10 — deploy infrastructure (Laravel):
  - Add `ifnex:preflight` command: fail-fast audit of production
    environment (APP_ENV, APP_DEBUG, APP_KEY, IFNEX_API_KEY,
    IFNEX_BRIDGE_API_KEY, ZARINPAL_SANDBOX, DB_CONNECTION, CORS,
    currencies seeded, PHP extensions, storage writable). Exits 1
    if any check fails; supports --skip-db for pre-migrate runs.
  - Add `ifnex:import-fx-rates` command: replacement for
    `ifnex:update-rates`. Fetches USD/AED from Exir.io + EUR/CNY
    from FreeCurrencyAPI. Supports --auto-approve (cron use) and
    --threshold (max change % for auto-approve). Logs critical on
    HTTP failure. URL configurable via EXIR_API_URL env.
  - Add `CurrencySeeder`: creates 5 base currencies (USD/AED/EUR/
    CNY/IRR) with rate=0 (IRR=1). Idempotent — does not overwrite
    real rates already set by admin or cron.
  - Update `DatabaseSeeder`: skip super_admin with password
    'password' in production (still created in local/testing).
  - Fix `bootstrap/app.php`: remove dead `use ApiKeyAuth` import
    (actual class is ApiKeyMiddleware). Latent fatal if api_key
    alias was used.
  - Add `config/ifnex.php` exir block + preflight config.
  - Harden `.env.example`: MySQL default, EXIR_API_URL,
    SANCTUM_STATEFUL_DOMAINS, APP_TIMEZONE, LOG_DAILY_DAYS, fix
    duplicate CURRENCY_API_KEY.

- Phase 3.10 — deploy scripts (Linux):
  - Add `scripts/deploy.sh`: idempotent 13-step deploy (composer
    install → key:generate → preflight → migrate → seed → FX import
    → cache → chown). Fail-fast with set -e.
  - Add `scripts/cron-exir-rates.sh`: daily cron wrapper for
    `ifnex:import-fx-rates --source=all --auto-approve`.

- Phase 3.10.1 — preflight hotfix:
  - Make expected DB connection configurable
    (ifnex.preflight.expected_db_connection) instead of hardcoded
    'mysql'. Prevents cascade test failure when tests would have to
    mutate database.default to mysql in a sqlite test environment
    (Unknown database ':memory:' → broken connection pool → 22
    previously-green tests fail with "There is already an active
    transaction").
  - Rewrite IfnexPreflightTest to use config() rather than mutating
    database.default.

- Phase 3.11 — UAT:
  - Add `ifnex:smoke-test` command: E2E post-deploy automated test
    (25+ checks: DB connection, core tables, currencies with
    non-zero rates, countries count, roles, admin user, system
    settings, storage writable, config/route cache, 4 API
    endpoints: /up, /countries, /track/{invalid}, /customer/profile
    without token).
  - Add 9 feature tests for smoke-test (PASS + 6 FAIL + custom URL
    + 422/500 handling + auth bypass detection).
  - Add `UAT-3.11.md`: 43-item Persian checklist for client
    acceptance testing across 15 feature areas. Includes sign-off
    form for both parties (client + VernaSoft).
  - Update `CLIENT_DELIVERY.md` to record phases 3.10 and 3.11.

Tests:
- Total: 51 → 82 tests, 150 → 220+ assertions, all green.
- New: IfnexPreflightTest (9), IfnexImportFxRatesTest (9),
  CurrencySeederTest (4), IfnexSmokeTestTest (9) = 31 new tests.

Documentation:
- DEPLOYMENT_HANDOFF.md §2.4: add CurrencySeeder + import-fx-rates.
- DEPLOYMENT_HANDOFF.md §2.8: update cron to use cron-exir-rates.sh.
- UAT-3.11.md: new 43-item client acceptance checklist + sign-off.
- CLIENT_DELIVERY.md: record phases 3.10 and 3.11 completion.
2026-10-31 22:18:15 +03:30

2 lines
10 KiB
JavaScript

/*! This file is auto-generated */
wp.customize.selectiveRefresh=function(o,r){"use strict";var t,s,c={ready:o.Deferred(),editShortcutVisibility:new r.Value,data:{partials:{},renderQueryVar:"",l10n:{shiftClickToEdit:""}},currentRequest:null};return _.extend(c,r.Events),t=c.Partial=r.Class.extend({id:null,defaults:{selector:null,primarySetting:null,containerInclusive:!1,fallbackRefresh:!0},initialize:function(e,t){var n=this;t=t||{},n.id=e,n.params=_.extend({settings:[]},n.defaults,t.params||t),n.deferred={},n.deferred.ready=o.Deferred(),n.deferred.ready.done(function(){n.ready()})},ready:function(){var n=this;_.each(n.placements(),function(e){o(e.container).attr("title",c.data.l10n.shiftClickToEdit),n.createEditShortcutForPlacement(e)}),o(document).on("click",n.params.selector,function(t){t.shiftKey&&(t.preventDefault(),_.each(n.placements(),function(e){o(e.container).is(t.currentTarget)&&n.showControl()}))})},createEditShortcutForPlacement:function(e){var t,n=this;!e.container||!(t=o(e.container)).length||t.is("area, audio, base, bdi, bdo, br, button, canvas, col, colgroup, command, datalist, embed, head, hr, html, iframe, img, input, keygen, label, link, map, math, menu, meta, noscript, object, optgroup, option, param, progress, rp, rt, ruby, script, select, source, style, svg, table, tbody, textarea, tfoot, thead, title, tr, track, video, wbr")||t.closest("head").length||((t=n.createEditShortcut()).on("click",function(e){e.preventDefault(),e.stopPropagation(),n.showControl()}),n.addEditShortcutToPlacement(e,t))},addEditShortcutToPlacement:function(e,t){e=o(e.container);e.prepend(t),e.is(":visible")&&"none"!==e.css("display")||t.addClass("customize-partial-edit-shortcut-hidden")},getEditShortcutClassName:function(){return"customize-partial-edit-shortcut-"+this.id.replace(/]/g,"").replace(/\[/g,"-")},getEditShortcutTitle:function(){var e=c.data.l10n;switch(this.getType()){case"widget":return e.clickEditWidget;case"blogname":case"blogdescription":return e.clickEditTitle;case"nav_menu":return e.clickEditMenu;default:return e.clickEditMisc}},getType:function(){var e=this,t=e.params.primarySetting||_.first(e.settings())||"unknown";return e.params.type||(t.match(/^nav_menu_instance\[/)?"nav_menu":t.match(/^widget_.+\[\d+]$/)?"widget":t)},createEditShortcut:function(){var e=this.getEditShortcutTitle(),t=o("<span>",{class:"customize-partial-edit-shortcut "+this.getEditShortcutClassName()}),e=o("<button>",{"aria-label":e,title:e,class:"customize-partial-edit-shortcut-button"}),n=o('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M13.89 3.39l2.71 2.72c.46.46.42 1.24.03 1.64l-8.01 8.02-5.56 1.16 1.16-5.58s7.6-7.63 7.99-8.03c.39-.39 1.22-.39 1.68.07zm-2.73 2.79l-5.59 5.61 1.11 1.11 5.54-5.65zm-2.97 8.23l5.58-5.6-1.07-1.08-5.59 5.6z"/></svg>');return e.append(n),t.append(e),t},placements:function(){var n=this,e=n.params.selector||"";return e&&(e+=", "),e+='[data-customize-partial-id="'+CSS.escape(n.id)+'"]',o(document).find(e).map(function(){var e=o(this),t=e.data("customize-partial-placement-context");if(_.isString(t)&&"{"===t.substr(0,1))throw new Error("context JSON parse error");return new s({partial:n,container:e,context:t})}).get()},settings:function(){var e=this;return e.params.settings&&0!==e.params.settings.length?e.params.settings:e.params.primarySetting?[e.params.primarySetting]:[e.id]},isRelatedSetting:function(e){return!!(e=_.isString(e)?r(e):e)&&-1!==_.indexOf(this.settings(),e.id)},showControl:function(){var e=this,t=(t=e.params.primarySetting)||_.first(e.settings());"nav_menu"===e.getType()&&(e.params.navMenuArgs.theme_location?t="nav_menu_locations["+e.params.navMenuArgs.theme_location+"]":e.params.navMenuArgs.menu&&(t="nav_menu["+String(e.params.navMenuArgs.menu)+"]")),r.preview.send("focus-control-for-setting",t)},preparePlacement:function(e){o(e.container).addClass("customize-partial-refreshing")},_pendingRefreshPromise:null,refresh:function(){var n=this,e=c.requestPartial(n);return n._pendingRefreshPromise||(_.each(n.placements(),function(e){n.preparePlacement(e)}),e.done(function(e){_.each(e,function(e){n.renderContent(e)})}),e.fail(function(e,t){n.fallback(e,t)}),(n._pendingRefreshPromise=e).always(function(){n._pendingRefreshPromise=null})),e},renderContent:function(t){var e,n,r=this;if(!t.container)return r.fallback(new Error("no_container"),[t]),!1;if(t.container=o(t.container),!1===t.addedContent)return r.fallback(new Error("missing_render"),[t]),!1;if(!_.isString(t.addedContent))return r.fallback(new Error("non_string_content"),[t]),!1;c.originalDocumentWrite=document.write,document.write=function(){throw new Error(c.data.l10n.badDocumentWrite)};try{if(e=t.addedContent,wp.emoji&&wp.emoji.parse&&!o.contains(document.head,t.container[0])&&(e=wp.emoji.parse(e)),r.params.containerInclusive)n=o(e),t.context=_.extend(t.context,n.data("customize-partial-placement-context")||{}),n.data("customize-partial-placement-context",t.context),t.removedNodes=t.container,t.container=n,t.removedNodes.replaceWith(t.container),t.container.attr("title",c.data.l10n.shiftClickToEdit);else{for(t.removedNodes=document.createDocumentFragment();t.container[0].firstChild;)t.removedNodes.appendChild(t.container[0].firstChild);t.container.html(e)}t.container.removeClass("customize-render-content-error")}catch(e){"undefined"!=typeof console&&console.error&&console.error(r.id,e),r.fallback(e,[t])}return document.write=c.originalDocumentWrite,c.originalDocumentWrite=null,r.createEditShortcutForPlacement(t),t.container.removeClass("customize-partial-refreshing"),t.container.data("customize-partial-content-rendered",!0),wp.mediaelement&&wp.mediaelement.initialize(),wp.playlist&&wp.playlist.initialize(),c.trigger("partial-content-rendered",t),!0},fallback:function(){this.params.fallbackRefresh&&c.requestFullRefresh()}}),c.Placement=s=r.Class.extend({partial:null,container:null,startNode:null,endNode:null,context:null,addedContent:null,removedNodes:null,initialize:function(e){if(!(e=_.extend({},e||{})).partial||!e.partial.extended(t))throw new Error("Missing partial");e.context=e.context||{},e.container&&(e.container=o(e.container)),_.extend(this,e)}}),c.partialConstructor={},c.partial=new r.Values({defaultConstructor:t}),c.getCustomizeQuery=function(){var n={};return r.each(function(e,t){e._dirty&&(n[t]=e())}),{wp_customize:"on",nonce:r.settings.nonce.preview,customize_theme:r.settings.theme.stylesheet,customized:JSON.stringify(n),customize_changeset_uuid:r.settings.changeset.uuid}},c._pendingPartialRequests={},c._debouncedTimeoutId=null,c._currentRequest=null,c.requestFullRefresh=function(){r.preview.send("refresh")},c.requestPartial=function(e){var t;return c._debouncedTimeoutId&&(clearTimeout(c._debouncedTimeoutId),c._debouncedTimeoutId=null),c._currentRequest&&(c._currentRequest.abort(),c._currentRequest=null),(t=c._pendingPartialRequests[e.id])&&"pending"===t.deferred.state()||(t={deferred:o.Deferred(),partial:e},c._pendingPartialRequests[e.id]=t),e=null,c._debouncedTimeoutId=setTimeout(function(){var n,i,e;c._debouncedTimeoutId=null,e=c.getCustomizeQuery(),i={},n={},_.each(c._pendingPartialRequests,function(e,t){i[t]=e.partial.placements(),c.partial.has(t)?n[t]=_.map(i[t],function(e){return e.context||{}}):e.deferred.rejectWith(e.partial,[new Error("partial_removed"),i[t]])}),e.partials=JSON.stringify(n),e[c.data.renderQueryVar]="1",(e=c._currentRequest=wp.ajax.send(null,{data:e,url:r.settings.url.self})).done(function(t){c.trigger("render-partials-response",t),t.errors&&"undefined"!=typeof console&&console.warn&&_.each(t.errors,function(e){console.warn(e)}),_.each(c._pendingPartialRequests,function(n,r){var e;_.isArray(t.contents[r])?(e=_.map(t.contents[r],function(e,t){t=i[r][t];return t?t.addedContent=e:t=new s({partial:n.partial,addedContent:e}),t}),n.deferred.resolveWith(n.partial,[e])):n.deferred.rejectWith(n.partial,[new Error("unrecognized_partial"),i[r]])}),c._pendingPartialRequests={}}),e.fail(function(n,e){"abort"!==e&&(_.each(c._pendingPartialRequests,function(e,t){e.deferred.rejectWith(e.partial,[n,i[t]])}),c._pendingPartialRequests={})})},r.settings.timeouts.selectiveRefresh),t.deferred.promise()},c.addPartials=function(e,a){var t;e=e||document.documentElement,e=o(e),a=_.extend({triggerRendered:!0},a||{}),t=e.find("[data-customize-partial-id]"),(t=e.is("[data-customize-partial-id]")?t.add(e):t).each(function(){var e,t,n,r=o(this),i=r.data("customize-partial-id");i&&(n=r.data("customize-partial-placement-context")||{},(e=c.partial(i))||((t=r.data("customize-partial-options")||{}).constructingContainerContext=r.data("customize-partial-placement-context")||{},e=new(c.partialConstructor[r.data("customize-partial-type")]||c.Partial)(i,t),c.partial.add(e)),a.triggerRendered&&!r.data("customize-partial-content-rendered")&&(i=new s({partial:e,context:n,container:r}),o(i.container).attr("title",c.data.l10n.shiftClickToEdit),e.createEditShortcutForPlacement(i),c.trigger("partial-content-rendered",i)),r.data("customize-partial-content-rendered",!0))})},r.bind("preview-ready",function(){var t,e;_.extend(c.data,_customizePartialRefreshExports),_.each(c.data.partials,function(e,t){var n=c.partial(t);n?_.extend(n.params,e):(n=new(c.partialConstructor[e.type]||c.Partial)(t,_.extend({params:e},e)),c.partial.add(n))}),t=function(t,n){var r=this;c.partial.each(function(e){e.isRelatedSetting(r,t,n)&&e.refresh()})},e=function(e){t.call(e,null,e()),e.unbind(t)},r.bind("add",function(e){t.call(e,e(),null),e.bind(t)}),r.bind("remove",e),r.each(function(e){e.bind(t)}),c.addPartials(document.documentElement,{triggerRendered:!1}),"undefined"!=typeof MutationObserver&&(c.mutationObserver=new MutationObserver(function(e){_.each(e,function(e){c.addPartials(o(e.target))})}),c.mutationObserver.observe(document.documentElement,{childList:!0,subtree:!0})),r.selectiveRefresh.bind("partial-content-rendered",function(e){e.container&&c.addPartials(e.container)}),r.selectiveRefresh.bind("render-partials-response",function(e){e.setting_validities&&r.preview.send("selective-refresh-setting-validities",e.setting_validities)}),r.preview.bind("edit-shortcut-visibility",function(e){r.selectiveRefresh.editShortcutVisibility.set(e)}),r.selectiveRefresh.editShortcutVisibility.bind(function(e){var t=o(document.body),n="hidden"===e&&t.hasClass("customize-partial-edit-shortcuts-shown")&&!t.hasClass("customize-partial-edit-shortcuts-hidden");t.toggleClass("customize-partial-edit-shortcuts-hidden",n),t.toggleClass("customize-partial-edit-shortcuts-shown","visible"===e)}),r.preview.bind("active",function(){c.partial.each(function(e){e.deferred.ready.resolve()}),c.partial.bind("add",function(e){e.deferred.ready.resolve()})})}),c}(jQuery,wp.customize);