/** * Webユーティリティ * Webアプリケーションを作成するうえで、便利なユーティリティ。 * ある程度のWebブラウザ間の違いは、この中で吸収します。 * * Version 00.35.00.00 * * このプログラムのライセンスについて。 * このプログラムは、MITライセンス(The MIT License)の元で公開します。 * Released under the MIT Licenses. * * ライセンスの原文は、以下のURLを参照してください。 * http://www.yscjp.com/licenses/MIT_LICENSE.txt * * Copyright (c) 2010-2019 Yagyu Teru, http://yscjp.com/ * */ var com; if (!com) com = {}; if (!com.yscjp) com.yscjp = {}; if (!com.yscjp.jsapp) com.yscjp.jsapp = {}; if (!com.yscjp.jsapp.util) com.yscjp.jsapp.util = {}; com.yscjp.jsapp.util.JS = function () {}; (function() { var JS = com.yscjp.jsapp.util.JS; JS.executeListener = function (listener) { return listener(); }; })(); com.yscjp.jsapp.util.UA = function () {}; (function() { var UA = com.yscjp.jsapp.util.UA; var isInitialized = false; var isFixedSupport = true; var emPx = 0; function init() { var div01 = document.createElement("div"); div01 = document.body.insertBefore(div01, document.body.firstChild); var firstTop = div01.offsetTop; var div02 = document.createElement("div"); div02.style.border = "none"; div02.style.padding = "0"; div02.style.height = "1em"; div02.style.position = "fixed"; div02 = document.body.insertBefore(div02, document.body.firstChild); var secondTop = div01.offsetTop; if (firstTop != secondTop) { isFixedSupport = false; } emPx = div02.offsetHeight; document.body.removeChild(div01); document.body.removeChild(div02); } /** * Webブラウザが、スタイルシートの position: fixed をサポートするかを返します. * @return position: fixed をサポートする場合 true、サポートしない場合 false * @memberOf com.yscjp.jsapp.util.UA */ UA.isFixedSupport = function () { if (!isInitialized) { init(); } return isFixedSupport; }; /** * 1em のピクセル数を返します. * @return 1em のピクセル数 * @memberOf com.yscjp.jsapp.util.UA */ UA.getEmPx = function () { if (!isInitialized) { init(); } return emPx; }; /** * このリクエストに付加されたクエリから、指定のキーの値を取得し返します。 * クエリに該当のキーが複数存在した場合、前に指定されているものが有効となります。 * @param key [string] クエリから値を取得するキー * @return keyに該当する値。クエリが存在しないか、クエリにキーが存在しない場合、null * @memberOf com.yscjp.jsapp.util.UA */ UA.getQueryValue = function (key) { var value = null; var query = window.location.search; if (0 !== query.length) { /* * 先頭の'?'を削除します。 */ query = query.replace(/^\?/, ""); /* * &で分割します。 */ var queries = query.split('&'); for (var i = 0; i < queries.length; i++) { var reg = new RegExp("^" + key + "=(.*)"); var values = queries[i].match(reg); if (values && 2 === values.length) { value = values[1]; break; } } } return value; }; /** * このリクエストに付加されたクエリから、指定のキーの値を取得し返します。 * クエリに該当のキーが複数存在した場合、全てを有効とします。 * @param key [string] クエリから値を取得するキー * @return keyに該当する値を格納した配列。クエリが存在しないか、クエリにキーが存在しない場合、空の配列 * @memberOf com.yscjp.jsapp.util.UA */ UA.getQueryValues = function (key) { var values = []; var query = window.location.search; if (0 !== query.length) { /* * 先頭の'?'を削除します。 */ query = query.replace(/^\?/, ""); /* * &で分割します。 */ var queries = query.split('&'); for (var i = 0; i < queries.length; i++) { var reg = new RegExp("^" + key + "=(.*)"); var _values_ = queries[i].match(reg); if (_values_ && 2 === _values_.length) { values.push(_values_[1]); } } } return values; }; UA.getOuterLeft = function (targetWindow) { if ("undefined" == typeof targetWindow) { targetWindow = window; } return targetWindow.screenX; }; UA.getOuterTop = function (targetWindow) { if ("undefined" == typeof targetWindow) { targetWindow = window; } return targetWindow.screenY; }; UA.getOuterWidth = function (targetWindow) { if ("undefined" == typeof targetWindow) { targetWindow = window; } if ("undefined" != typeof targetWindow.mozInnerScreenX) { let borderWidth = targetWindow.mozInnerScreenX - targetWindow.screenX; return targetWindow.innerWidth + borderWidth * 2; } if ("undefined" != typeof targetWindow.outerWidth) { return targetWindow.outerWidth; } }; UA.getOuterHeight = function (targetWindow) { if ("undefined" == typeof targetWindow) { targetWindow = window; } if ("undefined" != typeof targetWindow.mozInnerScreenY) { let borderWidth = targetWindow.mozInnerScreenX - targetWindow.screenX; let headerHeight = targetWindow.mozInnerScreenY - targetWindow.screenY; return targetWindow.innerHeight + borderWidth + headerHeight; } if ("undefined" != typeof targetWindow.outerHeight) { return targetWindow.outerHeight; } }; UA.getInnerLeft = function (targetWindow) { if ("undefined" == typeof targetWindow) { targetWindow = window; } if ("undefined" != typeof targetWindow.mozInnerScreenX) { return targetWindow.mozInnerScreenX; } else if ("undefined" != typeof targetWindow.screenLeft) { if ("undefined" != typeof targetWindow.screenX) { if (targetWindow.screenLeft == targetWindow.screenX) { let borderWidth = (targetWindow.outerWidth - targetWindow.innerWidth) / 2; return targetWindow.screenLeft + borderWidth; } } return targetWindow.screenLeft; } }; UA.getInnerTop = function (targetWindow) { if ("undefined" == typeof targetWindow) { targetWindow = window; } if ("undefined" != typeof targetWindow.mozInnerScreenY) { return targetWindow.mozInnerScreenY; } else if ("undefined" != typeof targetWindow.screenTop) { if ("undefined" != typeof targetWindow.screenY) { if (targetWindow.screenTop == targetWindow.screenY) { let borderWidth = (targetWindow.outerWidth - targetWindow.innerWidth) / 2; return targetWindow.screenTop + targetWindow.outerHeight - targetWindow.innerHeight - borderWidth; } } return targetWindow.screenTop; } }; /** * 指定されたWindowの、表示領域の高さと横幅をピクセル単位で返します。 * 但し、スクロールバーは表示領域として考慮しないことに注意すること。 * @param targetWindow [Window] 高さと横幅を取得するWindow。指定されていない場合は、window * @return 指定されたWindowの、表示領域の高さと横幅を格納したオブジェクト。 * o.widthで横幅、o.heightで高さを取得できます。 * @memberOf com.yscjp.jsapp.util.UA */ UA.getInnerSize = function (targetWindow) { if ("undefined" == typeof targetWindow) { targetWindow = window; } let targetDocument = targetWindow.document; targetDocument.body.insertAdjacentHTML('beforeend', '
'); let tempElement = targetDocument.body.lastChild; tempElement.style.position = 'fixed'; tempElement.style.top = '0'; tempElement.style.right = '0'; tempElement.style.bottom = '0'; tempElement.style.left = '0'; let size = {}; size.width = tempElement.offsetWidth; size.height = tempElement.offsetHeight; targetDocument.body.removeChild(tempElement); return size; } /** * 指定されたWindowの、表示領域の横幅をピクセル単位で返します。 * 但し、スクロールバーは表示領域として考慮しないことに注意すること。 * @param targetWindow [Window] 横幅を取得するWindow。指定されていない場合は、window * @return 指定されたWindowの、表示領域の横幅 * @memberOf com.yscjp.jsapp.util.UA */ UA.getInnerWidth = function (targetWindow) { if ("undefined" == typeof targetWindow) { targetWindow = window; } //return UA.getInnerSize(targetWindow).width; return targetWindow.innerWidth; }; /** * 指定されたWindowの、表示領域の高さをピクセル単位で返します。 * 但し、スクロールバーは表示領域として考慮しないことに注意すること。 * @param targetWindow [Window] 高さを取得するWindow。指定されていない場合は、window * @return 指定されたWindowの、表示領域の高さ * @memberOf com.yscjp.jsapp.util.UA */ UA.getInnerHeight = function (targetWindow) { if ("undefined" == typeof targetWindow) { targetWindow = window; } //return UA.getInnerSize(targetWindow).height; return targetWindow.innerHeight; }; /** * ページの読み込みを中止します。 * @param targetWindow [Window] ページの読み込みを中止Window。指定されていない場合は、window * @memberOf com.yscjp.jsapp.util.UA */ UA.stopLoad = function (targetWindow) { if ("undefined" == typeof targetWindow) { targetWindow = window; } if (targetWindow.document.execCommand) { targetWindow.document.execCommand("Stop"); } else { targetWindow.stop(); } }; /** * ユーザエージェントの識別子を返します。 *現在サポートしているUAと、返却する識別子は以下の通り。 *
Internet Explorer : IE * Firefox : FF * Google Chrome : GC * Opera : OP * Safari : SF * 不明 : UD*
このメソッドは実験的なので、使用には注意すること。 * 過去のバージョンや将来のバージョンで、正しく動作しません。 * @return 使用中のUAを現す識別子 * @memberOf com.yscjp.jsapp.util.UA */ UA.getUA = function () { // if (window.ActiveXObject) { if (window.screen.deviceXDPI) { return "IE"; } if (window.mozInnerScreenY) { /* * 3.6以降 */ return "FF"; } if (window.webkitConvertPointFromNodeToPage) { /* * Webkit */ if (window.IDBFactory) { return "GC"; } else { return "SF"; } } if (window.opera) { return "OP"; } return "UD"; // undefined }; })(); /** * ローテーションするバッファの実装です. * @class 複数の面を管理し、ローテーションするバッファです. * @constructor * @param {Number} maxLength バッファの最大長 * @param {Number} maxCount バックアップ面数 */ com.yscjp.jsapp.util.RotateBuffer = function (maxLength, maxCount) { this.maxLength = maxLength; this.maxCount = maxCount; this.topIndex = 0; this.bottomIndex = this.topIndex + this.maxCount - 1; this.index = 0; this.areas = []; for (var i = 0; i < this.maxCount; i++) { this.areas[i] = []; } }; (function() { var RotateBuffer = com.yscjp.jsapp.util.RotateBuffer; /** * * @param msg * @memberOf com.yscjp.jsapp.util.RotateBuffer */ RotateBuffer.prototype.put = function (msg) { var putArea = this.areas[this.index]; if (this.maxLength <= putArea.length) { this.index++; if (this.bottomIndex < this.index) { this.areas[this.topIndex] = null; this.topIndex++; this.bottomIndex++; this.areas[this.bottomIndex] = []; } putArea = this.areas[this.index]; } putArea.push(msg); }; /** * @param listener * @memberOf com.yscjp.jsapp.util.RotateBuffer */ RotateBuffer.prototype.print = function (listener) { for (var i = this.topIndex; i <= this.bottomIndex; i++) { var area = this.areas[i]; for (var j = 0; j < area.length; j++) { listener(area[j]); } } }; /** * @memberOf com.yscjp.jsapp.util.RotateBuffer */ RotateBuffer.prototype.clear = function () { this.topIndex = 0; this.bottomIndex = this.topIndex + this.maxCount - 1; this.index = 0; //this.areas = new Array(); for (var i = 0; i < this.maxCount; i++) { this.areas[i] = []; } }; })(); /** * ログ出力の管理を行います. * @class コンソールへログの出力を行います. *
window.console.logが存在し無い場合は、何もしません。 *
TRACE・DEBUG・INFO・WARNING・ERROR・FETAL・NONEの各モードをサポートし、デフォルトのモードはINFOです。 * デフォルトの状態では、info()・warning()・error()・fetal()の各メソッドで出力されたログを表示します。 * モードの変更は、プログラムの中に以下のコードを記述することで変更できます。 *
com.yscjp.jsapp.util.Log.mode=com.yscjp.jsapp.util.Log.MODE_DEBUG*
上記例では、debug()メソッドにより出力されたログを表示させます。 *
また、プログラムの変更が出来無い場合は、URLに以下のクエリを付加することでも変更できます。 *
?com.yscjp.jsapp.util.Log.mode=0*
上記例では、trace()メソッドにより出力されたログを表示させます。 * TRACEが0で、DEBUGが1....FETALが5・NONEが9となります。 */ com.yscjp.jsapp.util.Log = function () {}; (function() { var UA = com.yscjp.jsapp.util.UA; var RotateBuffer = com.yscjp.jsapp.util.RotateBuffer; var Log = com.yscjp.jsapp.util.Log; /** * トレースログの設定。 * 本来このあたりは外部設定により行うが、とりあえずは固定値。 */ var traceBuffer = new RotateBuffer(200, 2); var applicationBuffer = new RotateBuffer(1000, 10); /** * ログの出力モードでトレースを表す定数(0)です. * @type {Number} * @memberOf com.yscjp.jsapp.util.Log */ Log.MODE_TRACE = 0; Log.MODE_DEBUG = 1; Log.MODE_INFO = 2; Log.MODE_WARNING = 3; Log.MODE_ERROR = 4; Log.MODE_FETAL = 5; Log.MODE_NONE = 9; Log.mode = Log.MODE_INFO; var query = window.location.search; if (0 !== query.length) { /* * 先頭の'?'を削除します。 */ query = query.replace(/\?/, ""); /* * &で分割します。 */ var queries = query.split('&'); for (var i = 0; i < queries.length; i++) { var mode = queries[i].match(/com.yscjp.jsapp.util.Log.mode=(\d)/); if (mode && 2 === mode.length) { Log.mode = mode[1]; } } } var isConsoleOut = UA.getQueryValue("com.yscjp.jsapp.util.Log.consoleOut"); if (isConsoleOut && "false" == isConsoleOut.toLowerCase()) { isConsoleOut = false; } else { isConsoleOut = true; } var isTraceTime = UA.getQueryValue("com.yscjp.jsapp.util.Log.traceTime"); if (isTraceTime && "true" == isTraceTime.toLowerCase()) { isTraceTime = true; } else { isTraceTime = false; } function getTime() { var time = new Date(); var hours = "" + (time.getHours() + 100); var minutes = "" + (time.getMinutes() + 100); var seconds = "" + (time.getSeconds() + 100); var milliSec = "" + (time.getMilliseconds() + 1000); return hours.substring(1) + ":" + minutes.substring(1) + ":" + seconds.substring(1) + "." + milliSec.substring(1) + " "; } function _____log_____(level, msg) { let caller = getCaller(new Error().stack); msg = getTime() + level + caller + "\t" + msg; applicationBuffer.put(msg); if (isConsoleOut) { consoleLog(msg); } } function getCaller(stack) { if (!stack) { return ""; } let stacks = stack.split("\n"); try { for(let i = 0; i < stacks.length; i++) { if (null != stacks[i].match(/_____log_____/)) { let callStack = stacks[i + 2]; let startIndex = callStack.lastIndexOf("/"); let callPosi = ""; if (-1 == startIndex) { callPosi = callStack; } else { callPosi = callStack.substr(startIndex + 1); } if (")" == callPosi.charAt(callPosi.length - 1)) { callPosi = callPosi.substr(0, callPosi.length - 1); } return "(" + callPosi + ") "; } } } catch (e) { consoleLog(e); } return ""; } function consoleLog(msg) { if (!window.console) { return; } if (!window.console.log) { return; } console.log(msg); } function putTrace(msg) { if (isTraceTime) { msg = getTime() + msg; } traceBuffer.put(msg); } function printTrace(id) { var console = document.getElementById(id); if (!console) { return; } // com.yscjp.jsapp.util.DomUtil.removeAllChild(console); console.innerHTML = ''; traceBuffer.print(function (msg) { var div = document.createElement("div"); var text = document.createTextNode(msg); div.appendChild(text); console.appendChild(div); }); } function printAppLog(id) { var console = document.getElementById(id); if (!console) { return; } // com.yscjp.jsapp.util.DomUtil.removeAllChild(console); console.innerHTML = ''; applicationBuffer.print(function (msg) { var div = document.createElement("div"); var text = document.createTextNode(msg); div.appendChild(text); div = console.appendChild(div); if (msg.match(/^.............\[TRC\] /)) { div.className = "com_yscjp_htmlclass_TRCLOG"; } else if (msg.match(/^.............\[DBG\] /)) { div.className = "com_yscjp_htmlclass_DBGLOG"; } else if (msg.match(/^.............\[INF\] /)) { div.className = "com_yscjp_htmlclass_INFLOG"; } else if (msg.match(/^.............\[WRN\] /)) { div.className = "com_yscjp_htmlclass_WRNLOG"; } else if (msg.match(/^.............\[ERR\] /)) { div.className = "com_yscjp_htmlclass_ERRLOG"; } else if (msg.match(/^.............\[FTL\] /)) { div.className = "com_yscjp_htmlclass_FTLLOG"; } }); } /** * トレースレベルのログを出力します. * ログの出力モードがMODE_TRACEの場合に出力されます。 * @param {Object} msg ログに出力するメッセージ * @memberOf com.yscjp.jsapp.util.Log */ function trace(msg) { putTrace(msg); } /** * デバッグレベルのログを出力します. * ログの出力モードがMODE_DEBUG以上の場合または、デバッグフラグがtrueの場合に出力されます。 * @param {Object} msg ログに出力するメッセージ * @memberOf com.yscjp.jsapp.util.Log */ function debug(msg) { if (false === Log.isDebug && Log.MODE_DEBUG < Log.mode) { return; } _____log_____("[DBG] ", msg); } /** * インフォメーションレベルのログを出力します. * ログの出力モードがMODE_INFO以上の場合に出力されます。 * @param {Object} msg ログに出力するメッセージ * @memberOf com.yscjp.jsapp.util.Log */ function info(msg) { if (Log.MODE_INFO < Log.mode) { return; } _____log_____("[INF] ", msg); } /** * ワーニングレベルのログを出力します. * ログの出力モードがMODE_WARNING以上の場合に出力されます。 * @param {Object} msg ログに出力するメッセージ * @memberOf com.yscjp.jsapp.util.Log */ function warning(msg) { if (Log.MODE_WARNING < Log.mode) { return; } _____log_____("[WRN] ", msg); } /** * エラーレベルのログを出力します. * ログの出力モードがMODE_ERROR以上の場合に出力されます。 * @param {Object} msg ログに出力するメッセージ * @memberOf com.yscjp.jsapp.util.Log */ function error(msg) { if (Log.MODE_ERROR < Log.mode) { return; } _____log_____("[ERR] ", msg); } /** * 致命的エラーレベルのログを出力します. * ログの出力モードがMODE_FETAL以上の場合に出力されます。 * @param {Object} msg ログに出力するメッセージ * @memberOf com.yscjp.jsapp.util.Log */ function fetal(msg) { if (Log.MODE_FETAL < Log.mode) { return; } _____log_____("[FTL] ", msg); } /** * コンソールにスタックトレースを出力します. * @memberOf com.yscjp.jsapp.util.Log */ function stackTrace() { if (!window.console) { return; } if (!window.console.trace) { return; } console.trace(); } function clearTraceLog() { traceBuffer.clear(); } function clearAppLog() { applicationBuffer.clear(); } function setConsoleOut(bool) { isConsoleOut = bool; } Log.trace = trace; Log.debug = debug; Log.info = info; Log.warning = warning; Log.error = error; Log.fetal = fetal; Log.isDebug = false; Log.stackTrace = stackTrace; Log.printTrace = printTrace; Log.printAppLog = printAppLog; Log.clearTraceLog = clearTraceLog; Log.clearAppLog = clearAppLog; Log.setConsoleOut = setConsoleOut; Log.info("com.yscjp.jsapp.util.Log.mode:" + Log.mode); })(); com.yscjp.jsapp.util.StackTrace = function () {}; (function () { var StackTrace = com.yscjp.jsapp.util.StackTrace; var isStackTrace = true; var isTraceOnly = false; var query = window.location.search; if (0 !== query.length) { /* * 先頭の'?'を削除します。 */ query = query.replace(/\?/, ""); /* * &で分割します。 */ var queries = query.split('&'); for (var i = 0; i < queries.length; i++) { if ("com.yscjp.jsapp.util.StackTrace=NONE" == queries[i]) { isStackTrace = false; break; } if ("com.yscjp.jsapp.util.StackTrace.traceOnly=true" == queries[i]) { isTraceOnly = true; break; } } } var Log = com.yscjp.jsapp.util.Log; var deep = 100; var stackList = new Array(deep); var errorStackList = []; var index = -1; var isStop = false; var id = 1000000; function start(clazzName, methodName, args) { index++; var stack = {}; stack.clazzName = clazzName; stack.methodName = methodName; stack.args = args; errorStackList.length = 0; stackList[index] = stack; isStop = false; } function end() { if (isStop) { errorStackList[index] = stackList[index]; // return; } stackList[index] = null; index--; } function stop() { isStop = true; } function getTrace() { Log.trace("---------- getTrace " + index + " ----------"); var value = ""; var errorIndex = errorStackList.length - 1; for (var i = errorIndex; i >= 0; i --) { var stack = errorStackList[i]; var clazzName = stack.clazzName; var methodName = stack.methodName; value += "\t" + clazzName + "#" + methodName + "("; var args = stack.args; if (args) { for (var j = 0; j < args.length; j ++) { value += args[j]; if (j != (args.length - 1)) { value += ", "; } } } value += ")\n"; } return value; } function wrapping(clazz, clazzName) { for (var name in clazz) { wrapping2(clazz, clazzName, name); } } function wrapping2(clazz, clazzName, name) { var value = clazz[name]; if ("function" == typeof value) { if (isTraceOnly) { clazz[name] = function () { id++; var currentId = id; Log.trace("--- " + clazzName + "#" + name + " START(" + currentId + ") ---"); var rtn = value.apply(this, arguments); Log.trace("--- " + clazzName + "#" + name + " END(" + currentId + ") ---"); return rtn; }; } else { clazz[name] = function () { id++; var currentId = id; var endStatus = ""; try{ start(clazzName, name, arguments); Log.trace("--- " + clazzName + "#" + name + " START(" + currentId + ") ---"); var rtn = value.apply(this, arguments); return rtn; } catch(e) { if (!isStop && e.stack) { Log.error(e.stack); } endStatus = e.toString(); stop(); throw e; } finally { Log.trace("--- " + clazzName + "#" + name + " END(" + currentId + ") ---" + endStatus); end(); } }; } } } function insert(clazz, clazzName) { if (isStackTrace) { wrapping(clazz, clazzName); wrapping(clazz.prototype, clazzName); } } function errorHandler(message, url, line) { alert("エラーを検知しました。\n" + message + "\n" + url + ":" + line + "\n" + getTrace()); return true; } StackTrace.getTrace = getTrace; StackTrace.insert = insert; StackTrace.errorHandler = errorHandler; })(); com.yscjp.jsapp.util.ArgChk = function () {}; (function() { var ArgChk = com.yscjp.jsapp.util.ArgChk; /** * argument が定義されているかを判定します. * 未定義の判定は、以下のコードにより行います。 *
if ("undefined" == typeof argument)* @param {Object} argument 定義済みかを判定するオブジェクト * @param {Object} defaultValue 未定義の場合に返すデフォルトの値 * @return argument が定義済みの場合 argument をそのまま返します。 * argument が未定義の場合、defaultValue が定義されていれば defaultValue を返します。 * defaultValue も未定義の場合、Error をスローします。 * @memberOf com.yscjp.jsapp.util.ArgChk */ function notUndefined(argument, defaultValue) { if ("undefined" == typeof argument) { if ("undefined" != typeof defaultValue) { return defaultValue; } throw new Error("Argument is undefined."); } return argument; } function notUndefinedTypeOf(argument, type, defaultValue) { argument = notUndefined(argument, defaultValue); return typeOf(argument, type, defaultValue); } /** * argument が null 以外かを判定します. * argument が 未定義の場合も、null と判定されます。 * @param {Object} argument null 以外かを判定するオブジェクト * @param {Object} defaultValue argument が null の場合に返すデフォルトの値 * @return argument がnull以外の場合 argument をそのまま返します。 * argument がnullの場合、defaultValue が定義されていれば defaultValue を返します。 * defaultValue も未定義の場合、Error をスローします。 * @memberOf com.yscjp.jsapp.util.ArgChk */ function notNull(argument, defaultValue) { if ("undefined" == typeof argument || null === argument) { if ("undefined" != typeof defaultValue) { return defaultValue; } throw new Error("Argument is null."); } return argument; } function notNullTypeOf(argument, type, defaultValue) { argument = notNull(argument, defaultValue); return typeOf(argument, type, defaultValue); } /** * argument が 空以外かを判定します. * 空の判定方法は以下のとおり。 *
if (type != typeof argument)* 以下のコードは正常に終了し、argument を返します。 *
if (!(argument instanceof instanceType))* 以下のコードは正常に終了し、argument を返します。 *
* (16) (17) (2) (3) (4) * NW NNW N NNE NE * +----+----+----+----+ * | | * (15)WNW+ (1) +ENE(5) * | C | * (14)W+ + +E(6) * | | * (13)WSW+ +ESE(7) * | | * +----+----+----+----+ * SW SSW S SSE SE * (12) (11) (10) (9) (8) ** @return 要素の中心のポイント * @memberOf com.yscjp.jsapp.tools.HtmlPosition */ /** * @memberOf com.yscjp.jsapp.util.JSHtmlUtil */ JSHtmlUtil.getPoint = function (position, direction) { switch (direction) { case "C" : return JSHtmlUtil.getCenter(position); case "N" : return JSHtmlUtil.getN(position); case "NNE" : return JSHtmlUtil.getNNE(position); case "NE" : return JSHtmlUtil.getNE(position); case "ENE" : return JSHtmlUtil.getENE(position); case "E" : return JSHtmlUtil.getE(position); case "ESE" : return JSHtmlUtil.getESE(position); case "SE" : return JSHtmlUtil.getSE(position); case "SSE" : return JSHtmlUtil.getSSE(position); case "S" : return JSHtmlUtil.getS(position); case "SSW" : return JSHtmlUtil.getSSW(position); case "SW" : return JSHtmlUtil.getSW(position); case "WSW" : return JSHtmlUtil.getWSW(position); case "W" : return JSHtmlUtil.getW(position); case "WNW" : return JSHtmlUtil.getWNW(position); case "NW" : return JSHtmlUtil.getNW(position); case "NNW" : return JSHtmlUtil.getNNW(position); default : return JSHtmlUtil.getCenter(position); } }; /** * @memberOf com.yscjp.jsapp.util.JSHtmlUtil */ JSHtmlUtil.getCenter = function (position) { var point = {}; point.x = position.x + position.width / 2; point.y = position.y + position.height / 2; return point; }; /** * @memberOf com.yscjp.jsapp.util.JSHtmlUtil */ JSHtmlUtil.getN = function (position) { var point = {}; point.x = position.x + position.width / 2; point.y = position.y; return point; }; /** * @memberOf com.yscjp.jsapp.util.JSHtmlUtil */ JSHtmlUtil.getNNE = function (position) { var point = {}; point.x = position.x + (position.width / 4) * 3; point.y = position.y; return point; }; /** * @memberOf com.yscjp.jsapp.util.JSHtmlUtil */ JSHtmlUtil.getNE = function (position) { var point = {}; point.x = position.x + position.width; point.y = position.y; return point; }; /** * @memberOf com.yscjp.jsapp.util.JSHtmlUtil */ JSHtmlUtil.getENE = function (position) { var point = {}; point.x = position.x + position.width; point.y = position.y + position.height / 4; return point; }; /** * @memberOf com.yscjp.jsapp.util.JSHtmlUtil */ JSHtmlUtil.getE = function (position) { var point = {}; point.x = position.x + position.width; point.y = position.y + position.height / 2; return point; }; /** * @memberOf com.yscjp.jsapp.util.JSHtmlUtil */ JSHtmlUtil.getESE = function (position) { var point = {}; point.x = position.x + position.width; point.y = position.y + (position.height /4) * 3; return point; }; /** * @memberOf com.yscjp.jsapp.util.JSHtmlUtil */ JSHtmlUtil.getSE = function (position) { var point = {}; point.x = position.x + position.width; point.y = position.y + position.height; return point; }; /** * @memberOf com.yscjp.jsapp.util.JSHtmlUtil */ JSHtmlUtil.getSSE = function (position) { var point = {}; point.x = position.x + (position.width / 4) * 3; point.y = position.y + position.height; return point; }; /** * @memberOf com.yscjp.jsapp.util.JSHtmlUtil */ JSHtmlUtil.getS = function (position) { var point = {}; point.x = position.x + position.width / 2; point.y = position.y + position.height; return point; }; /** * @memberOf com.yscjp.jsapp.util.JSHtmlUtil */ JSHtmlUtil.getSSW = function (position) { var point = {}; point.x = position.x + position.width / 4; point.y = position.y + position.height; return point; }; /** * @memberOf com.yscjp.jsapp.util.JSHtmlUtil */ JSHtmlUtil.getSW = function (position) { var point = {}; point.x = position.x; point.y = position.y + position.height; return point; }; /** * @memberOf com.yscjp.jsapp.util.JSHtmlUtil */ JSHtmlUtil.getWSW = function (position) { var point = {}; point.x = position.x; point.y = position.y + (position.height / 4) * 3; return point; }; /** * @memberOf com.yscjp.jsapp.util.JSHtmlUtil */ JSHtmlUtil.getW = function (position) { var point = {}; point.x = position.x; point.y = position.y + position.height / 2; return point; }; /** * @memberOf com.yscjp.jsapp.util.JSHtmlUtil */ JSHtmlUtil.getWNW = function (position) { var point = {}; point.x = position.x; point.y = position.y + position.height / 4; return point; }; /** * @memberOf com.yscjp.jsapp.util.JSHtmlUtil */ JSHtmlUtil.getNW = function (position) { var point = {}; point.x = position.x; point.y = position.y; return point; }; /** * @memberOf com.yscjp.jsapp.util.JSHtmlUtil */ JSHtmlUtil.getNNW = function (position) { var point = {}; point.x = position.x + position.width / 4; point.y = position.y; return point; }; /** * 指定要素の高さを、ピクセル単位で返します。 * @param target : 要素 : 高さを取得する要素 * @memberOf com.yscjp.jsapp.util.JSHtmlUtil */ JSHtmlUtil.getHeightPixel = function (target) { return target.clientHeight; }; /** * 指定要素の幅を、ピクセル単位で返します。 * @param target : 要素 : 幅を取得する要素 * @memberOf com.yscjp.jsapp.util.JSHtmlUtil */ JSHtmlUtil.getWidthPixel = function (target) { return target.clientWidth; }; /** * 指定のselect要素に、option要素を追加します。 * option要素のvalueには引数のvalueを、表示内容にはdisplayをそれぞれ設定します。 * @param select : 要素 : optionを追加するselect要素 * @param value : 文字列 : option要素のvalueに設定する値 * @param display : 文字列 : option要素の表示内容とする値 * @memberOf com.yscjp.jsapp.util.JSHtmlUtil */ JSHtmlUtil.addOption = function (select, value, display) { var ownerDocument; if (select.ownerDocument) { ownerDocument = select.ownerDocument; } else { ownerDocument = select.document; } var option = ownerDocument.createElement("option"); option.value = value; option.text = display; try { select.add(option, null); } catch (e) { select.add(option); } }; /** * 指定のselect要素の、全てのoption要素を削除します。 * @param select : 要素 : optionを削除するselect要素 * @memberOf com.yscjp.jsapp.util.JSHtmlUtil */ JSHtmlUtil.removeAllOption = function (select) { var length = select.length; for (var i = 0; i < length; i++) { select.remove(0); } }; /** * 指定のテーブルに行を追加します。 * cellCount が指定されている場合、指定された数のセルを行に追加します。 * @param table : 要素 : 行を追加するテーブル要素 * @param cellCount : 数値 : 行に追加するセルの数(オプション) * @return 追加した行 * @memberOf com.yscjp.jsapp.util.JSHtmlUtil */ JSHtmlUtil.addRow = function (table, cellCount) { if ("undefined" == typeof cellCount) { cellCount = 0; } var row = table.insertRow(-1); for (var i = 0; i < cellCount; i++) { row.insertCell(-1); } return row; }; /** * * @memberOf com.yscjp.jsapp.util.JSHtmlUtil */ JSHtmlUtil.removeAllRows = function (table) { while (0 != table.rows.length) { table.deleteRow(-1); } }; JSHtmlUtil.textWidthTuning = function (arg) { let div = arg; if ('string' == typeof arg) { div = document.getElementById(arg); } let span = div.firstElementChild; if (!span) { return; } let divStyle = document.defaultView.getComputedStyle(div, ''); let spanStyle = document.defaultView.getComputedStyle(span, ''); let divWidth = 0; /* * コンテンツ領域のサイズを取得する。 * box-sizingによって、取得方法が異なる。 * content-boxの場合は、ボーダーとパディングの値をマイナスする必要が有る。 */ if ('content-box' == divStyle.boxSizing) { divWidth = parseInt(divStyle.width); } else { let borderLeft = parseInt(divStyle.borderLeftWidth); let borderRight = parseInt(divStyle.borderRightWidth); let paddingLeft = parseInt(divStyle.paddingLeft); let paddingRight = parseInt(divStyle.paddingRight); divWidth = parseInt(divStyle.width) - borderLeft - borderRight - paddingLeft - paddingRight; } Log.debug('divWidth:' + divWidth + ' span.offsetWidth:' + span.offsetWidth); let ratio = divWidth / span.offsetWidth; if (1 <= ratio) { return; } span.style.display = 'inline-block'; span.style.transformOrigin = 'left'; span.style.transform = 'scale(' + ratio + ', 1)'; } })(); com.yscjp.jsapp.util.JSHtml = com.yscjp.jsapp.util.JSHtmlUtil;