PageSourceSearch

https://www.wpc100.co.jp/wp-content/plugins/docodoco-geotargeting/public/js/frontend.bundle.js?ver=2.0.0

js wpc100.co.jp collected 2026-10-05 05:13:18 UTC 13,683 bytes, 377 lines download raw bytes

1/******/ (() => { // webpackBootstrap
2/******/ 	"use strict";
3var __webpack_exports__ = {};
4
5;// CONCATENATED MODULE: ./src/js/abtesting-metrics-handler.js
6/**
7 * PV数・クリック数・離脱数・平均滞在時間を送信する
8 */
9function handleMetrics(targetingId, userGroup) {
10    let isNavigating = false;
11    let isExited = false;
12    const startTime = Date.now();
13
14    // イベントをサーバに送信するユーティリティ関数
15    function trackEvent(eventType, additionalData = {}) {
16        const data = {
17            action: 'track_event',
18            event: eventType,
19            _ajax_nonce: params.nonce,
20            targeting_id: targetingId,
21            group: userGroup,
22            ...additionalData
23        };
24
25       const beaconData = new FormData();
26       for (let key in data) {
27           beaconData.append(key, data[key]);
28       }
29
30       const url = params.ajax_url;
31       if (!navigator.sendBeacon(url, beaconData)) {
32           console.log('データ送信に失敗しました。');
33       }
34    }
35
36    // PV数の計測
37    function trackPageView() {
38        trackEvent('PV');
39    }
40
41    // クリック数の計測
42    let clickCount = 0;
43    function trackClicks() {
44        document.querySelectorAll(`#${targetingId} [data-docogt]`).forEach(function(element) {
45            element.addEventListener('click', function() {
46                if (clickCount > 0) {
47                    // 2回目以降のクリックはクリック数をカウントしない
48                    return;
49                }
50
51                if (isExited) {
52                    // 離脱後のクリックはカウントしない
53                    return;
54                }
55
56                clickCount++;
57                trackEvent('click');
58            });
59        });
60    }
61
62    // リンククリックによるページ遷移の検出
63    function trackNavigation() {
64        document.querySelectorAll('a').forEach(function(anchor) {
65            anchor.addEventListener('click', function() {
66                isNavigating = true; // ページ遷移が発生したとマークする
67            });
68        });
69    }
70
71    // 離脱数と滞在時間の計測
72    function handleUnloadEvents() {
73        window.addEventListener('beforeunload', function() {
74            // 小数点以下は不要なためMath.floorで切り捨てる
75            const timeSpent = Math.floor(performance.now());
76
77            // 滞在時間をサーバに送信
78            if (isExited) {
79                return;
80            }
81            isExited = true;
82
83            // タブやウィンドウが閉じられた場合の離脱を記録
84            if (!isNavigating) {
85                trackEvent('Exit');
86            }
87            trackEvent('timeSpent', { timeSpent: timeSpent });
88        });
89
90        window.addEventListener('visibilitychange', function () {
91            // タブが非アクティブになったら離脱として記録
92            if (!document.hidden) {
93                return;
94            }
95
96            // 別のイベントで既に離脱が記録されている場合は何もしない
97            if (isExited) {
98                return;
99            }
100            isExited = true;
101
102            // 小数点以下は不要なためMath.floorで切り捨てる
103            const timeSpent = Math.floor(performance.now());
104
105            // ページ遷移が発生していない場合は離脱として記録
106            if (!isNavigating) {
107                trackEvent('Exit');
108            }
109            // 滞在時間をサーバに送信
110            trackEvent('timeSpent', { timeSpent: timeSpent });
111        });
112    }
113
114    // メトリクスの計測を開始
115    trackPageView();
116    trackClicks();
117    trackNavigation();
118    handleUnloadEvents();
119};
120
121;// CONCATENATED MODULE: ./src/js/content-switcher.js
122
123
124let ContentSwitcher = {};
125
126/**
127 * ターゲティング種別「位置情報(国)」
128 */
129ContentSwitcher._selectContentByCountry = function (SP, ruleset) {
130    const country = SP.getCountryCode();
131    const selectedRule = ruleset.find(rule => rule.condition.includes(country));
132    return selectedRule ? selectedRule.rule_id : "default";
133}
134
135/**
136 * ターゲティング種別「位置情報(都道府県)」
137 */
138ContentSwitcher._selectContentByPref = function (SP, ruleset) {
139    const pref = SP.getPrefAName();
140    const selectedRule = ruleset.find(rule => rule.condition.includes(pref));
141    return selectedRule ? selectedRule.rule_id : "default";
142}
143
144/**
145 * ターゲティング種別「位置情報(市区町村)」
146 */
147ContentSwitcher._selectContentByCity = function (SP, ruleset) {
148    const city = SP.getCityCode();
149    const selectedRule = ruleset.find(rule => rule.condition.includes(city));
150    return selectedRule ? selectedRule.rule_id : "default";
151}
152
153/**
154 * ターゲティング種別「企業フラグ」
155 */
156ContentSwitcher._selectContentByBcFlag = function (SP, ruleset) {
157    const bcFlag = SP.getBCFlag();
158    const selectedRule = ruleset.find(rule => (rule.condition.includes(bcFlag)));
159    return selectedRule ? selectedRule.rule_id : "default";
160}
161
162/**
163 * ターゲティング種別「業種大分類」
164 */
165 ContentSwitcher._selectContentByOrgCategoryL = function selectRuleId(SP, ruleset) {
166    // orgCategoryLがカンマ区切りで複数の値を持つ場合があるため、分割して配列に変換する
167    const orgCategoryL = SP.getOrgIndustrialCategoryL();
168    const orgCategoryLArray = orgCategoryL.split(',');
169
170    // orgCategoryLArrayの要素がruleのいずれかに含まれる場合にマッチする
171    const selectedRule = ruleset.find(rule => {
172        return orgCategoryLArray.some(orgCategoryL => rule.condition.includes(orgCategoryL));
173    });
174    
175    return selectedRule ? selectedRule.rule_id : "default";
176  }
177
178/**
179 * ターゲティング種別「業種中分類」
180 */
181ContentSwitcher._selectContentByOrgCategoryM = function (SP, ruleset) {
182    // orgCategoryMがカンマ区切りで複数の値を持つ場合があるため、分割して配列に変換する
183    const orgCategoryM = SP.getOrgIndustrialCategoryM();
184    const orgCategoryMArray = orgCategoryM.split(',');
185
186    // orgCategoryMArrayの要素がruleのいずれかに含まれる場合にマッチする
187    const selectedRuleId = ruleset.find(rule => {
188        return orgCategoryMArray.some(orgCategoryM => rule.condition.includes(orgCategoryM));
189    });
190
191    return selectedRuleId ? selectedRuleId.rule_id : "default";
192}
193
194/**
195 * 表示するコンテンツをルールに基づき決定する
196 */
197ContentSwitcher._selectContentByRules = function (SP, targeting_type, ruleset) {
198    let selectedRuleId = "default";
199    switch (targeting_type) {
200        case 'area_country':
201            selectedRuleId = this._selectContentByCountry(SP, ruleset);
202            break;
203
204        case 'area_pref':
205            selectedRuleId = this._selectContentByPref(SP, ruleset);
206            break;
207
208        case 'area_city':
209            selectedRuleId = this._selectContentByCity(SP, ruleset);
210            break;
211
212        case 'bcflag':
213            selectedRuleId = this._selectContentByBcFlag(SP, ruleset);
214            break;
215
216        case 'org_category_l':
217            selectedRuleId = this._selectContentByOrgCategoryL(SP, ruleset);
218            break;
219
220        case 'org_category_m':
221            selectedRuleId = this._selectContentByOrgCategoryM(SP, ruleset);
222            break;
223    
224        case 'preview':
225            selectedRuleId = ruleset[0].rule_id;
226            break;
227
228        default:
229            console.warn("未対応のターゲティングタイプが指定されました。" + targeting_type);
230            break;
231    }
232
233    return selectedRuleId;
234};
235
236/**
237 * コンテンツの表示状態を切り換える
238 */ 
239ContentSwitcher._switchContentVisibility = function (targetingId, ruleId) {
240    let contentsBlock = document.getElementById(targetingId);
241    if (contentsBlock === null) {
242        console.warn("指定されたコンテンツが存在しません。id=" + targetingId);
243        return;
244    }
245
246    // 表示対象のコンテンツを取得する
247    let target = contentsBlock.querySelector('[data-docogt="' + ruleId + '"]');
248    // targetが見つからない場合はdefaultを表示する
249    if (target === null) {
250        console.warn("指定されたコンテンツが存在しません。data-docogt=" + ruleId);
251        target = contentsBlock.querySelector('[data-docogt="default"]');
252        // defaultが見つからない場合は何もしない
253        if (target === null) {
254            console.warn("既定のコンテンツが存在しません。data-docogt=default");
255            return;
256        }
257    }
258
259    // 表示対象のコンテンツを表示する。他のコンテンツは非表示にする
260    contentsBlock.querySelectorAll('[data-docogt]').forEach((element) => {
261        if (element === target) {
262            element.style.display = '';
263        } else {
264            element.style.display = 'none';
265        }
266    });
267};
268
269/**
270 * コンテンツの表示状態を切り換える
271 */
272ContentSwitcher.Run = async function (SP, pluginParams) {
273    // SPがundefinedの場合は何もしない
274    if (SP === null || SP === undefined) {
275        console.warn("SURFPOINTが未定義です。");
276        return;
277    }
278
279    // プラグイン設定がない場合は何もしない
280    if (pluginParams === null || pluginParams.length === 0) {
281        console.warn("プラグイン設定が存在しません。");
282        return;
283    }
284    
285    pluginParams.forEach(pluginParam => {
286        let targetingId = pluginParam.targeting_id;
287        let targetingType = pluginParam.targeting_type;
288        let ruleset = pluginParam.ruleset;
289        let abtestingEnabled = pluginParam.abtesting_enabled;
290        let abtestingTraffic = pluginParam.abtesting_traffic;
291        let selectedRuleId;
292
293        // ログインユーザーか、ABテストが有効か、テスト対象かどうかをチェック
294        if (!params.is_logged_in && abtestingEnabled && Math.random() < abtestingTraffic) {
295            // ABテストの対象者をグループA(無効)とB(有効)に振り分ける
296            let abtesting_group = Math.random() < 0.5 ? 'A' : 'B';
297
298            // グループごとに適用するルールを決定
299            selectedRuleId = abtesting_group === 'A' ? "default" : this._selectContentByRules(SP, targetingType, ruleset);
300
301            // ABテスト対象のユーザーのメトリクスを計測
302            handleMetrics(targetingId, abtesting_group);
303        } else {
304            // ABテストが無効、またはテスト対象外のユーザー
305            selectedRuleId = this._selectContentByRules(SP, targetingType, ruleset);
306        }
307        // コンテンツの表示状態を切り換える
308        this._switchContentVisibility(targetingId, selectedRuleId);
309    });
310};
311
312/* harmony default export */ const content_switcher = (ContentSwitcher);
313
314;// CONCATENATED MODULE: ./src/js/geotargeting-script.js
315
316
317(function() {
318    // クライアント位置情報の使用有無に応じた処理
319    function geoFindMe() {
320        // 対象パスの設定にひとつでもブラウザ位置情報を使用するものがあれば、ブラウザ位置情報を使用する
321        const use_browser_location = docodocoGeotargetingParams.find((param) => param.use_browser_location === true);
322        if (use_browser_location) {
323            if (navigator.geolocation) {
324                navigator.geolocation.getCurrentPosition(geoSuccess, geoError);
325            } else {
326                geoError();
327            }
328        } else {
329            geoError();
330        }
331
332        // 緯度経度が取得できた場合
333        function geoSuccess (position) {
334            var docodoco_api = document.createElement('script');
335            if (typeof bake !== 'undefined' && bake == '1'){
336                docodoco_api.src = 'https://api.docodoco.jp/docodoco_latlon?key=' + docodoco_ke
336y + '&lat=' + position.coords.latitude + '&lon=' + position.coords.longitude + '&bake=1';
337            } else {
338                docodoco_api.src = 'https://api.docodoco.jp/docodoco_latlon?key=' + docodoco_key + '&lat=' + position.coords.latitude + '&lon=' + position.coords.longitude;
339            }
340            docodoco_api.referrerPolicy = 'no-referrer-when-downgrade';
341
342            docodoco_api.onload = function() { content_switcher.Run(SURFPOINT_latlon, docodocoGeotargetingParams) };
343            document.getElementsByTagName('head')[0].appendChild(docodoco_api);
344        };
345        
346        // 緯度経度が取得できなかった場合
347        function geoError (error) {
348            var docodoco_api = document.createElement('script');
349            if (typeof bake !== 'undefined' && bake == '1'){
350                docodoco_api.src = 'https://api.docodoco.jp/v6/docodoco?key=' + docodoco_key + '&bake=1';
351            } else {
352                docodoco_api.src = 'https://api.docodoco.jp/v6/docodoco?key=' + docodoco_key;
353            }
354            docodoco_api.referrerPolicy = 'no-referrer-when-downgrade';
355            
356            docodoco_api.onload = function() { content_switcher.Run(SURFPOINT, docodocoGeotargetingParams) };
357            document.getElementsByTagName('head')[0].appendChild(docodoco_api);
358        };
359    };
360
361    if (document.readyState !== "loading") {
362        geoFindMe();
363    } else {
364        document.addEventListener("DOMContentLoaded", geoFindMe);
365    }
366
367})();
368
369;// CONCATENATED MODULE: ./src/js/frontend.js
370// フロントエンド用のJavaScriptメインファイル
371// Webpackでバンドルされる
372
373
374
375
376/******/ })()
377;

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.