Update reader.
@@ -31,11 +31,25 @@ namespace AppxPackage
|
|||||||
"Square71x71Logo",
|
"Square71x71Logo",
|
||||||
"StartPage",
|
"StartPage",
|
||||||
"Tall150x310Logo",
|
"Tall150x310Logo",
|
||||||
"VisualGroup",
|
|
||||||
"WideLogo",
|
"WideLogo",
|
||||||
"Wide310x150Logo",
|
"Wide310x150Logo",
|
||||||
"Executable"
|
"Executable"
|
||||||
};
|
};
|
||||||
|
public static readonly string [] ImageFilePathItems = new string []
|
||||||
|
{
|
||||||
|
"LockScreenLogo",
|
||||||
|
"Logo",
|
||||||
|
"SmallLogo",
|
||||||
|
"Square150x150Logo",
|
||||||
|
"Square30x30Logo",
|
||||||
|
"Square310x310Logo",
|
||||||
|
"Square44x44Logo",
|
||||||
|
"Square70x70Logo",
|
||||||
|
"Square71x71Logo",
|
||||||
|
"Tall150x310Logo",
|
||||||
|
"WideLogo",
|
||||||
|
"Wide310x150Logo"
|
||||||
|
};
|
||||||
public static bool IsFilePathKey (string key)
|
public static bool IsFilePathKey (string key)
|
||||||
{
|
{
|
||||||
foreach (var i in FilePathItems)
|
foreach (var i in FilePathItems)
|
||||||
@@ -293,7 +307,7 @@ namespace AppxPackage
|
|||||||
return obj.Trim ().ToLowerInvariant ().GetHashCode ();
|
return obj.Trim ().ToLowerInvariant ().GetHashCode ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private HashSet <string> set = new HashSet<string> (new TrimIgnoreCaseComparer ());
|
private HashSet<string> set = new HashSet<string> (new TrimIgnoreCaseComparer ());
|
||||||
public Dictionary<PriResourceKey, string> FileResourceAllValues (string resid, ZipOutputStream zos)
|
public Dictionary<PriResourceKey, string> FileResourceAllValues (string resid, ZipOutputStream zos)
|
||||||
{
|
{
|
||||||
var comparer = new TrimIgnoreCaseComparer ();
|
var comparer = new TrimIgnoreCaseComparer ();
|
||||||
@@ -716,6 +730,13 @@ namespace AppxPackage
|
|||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
protected bool IsImageFilePathKey (string key)
|
||||||
|
{
|
||||||
|
foreach (var i in ConstData.ImageFilePathItems)
|
||||||
|
if ((i?.Trim ()?.ToLower () ?? "") == (key?.Trim ()?.ToLower () ?? ""))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
public new string this [string key]
|
public new string this [string key]
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -767,7 +788,7 @@ namespace AppxPackage
|
|||||||
string pri = PriGetRes (value);
|
string pri = PriGetRes (value);
|
||||||
return string.IsNullOrEmpty (pri) ? value : pri;
|
return string.IsNullOrEmpty (pri) ? value : pri;
|
||||||
}
|
}
|
||||||
if (IsFilePathKey (key) && !string.IsNullOrEmpty (value))
|
if (IsImageFilePathKey (key) && !string.IsNullOrEmpty (value))
|
||||||
{
|
{
|
||||||
string pri = PriGetRes (value);
|
string pri = PriGetRes (value);
|
||||||
return string.IsNullOrEmpty (pri) ? value : pri;
|
return string.IsNullOrEmpty (pri) ? value : pri;
|
||||||
@@ -777,7 +798,7 @@ namespace AppxPackage
|
|||||||
public string NewAtBase64 (string key)
|
public string NewAtBase64 (string key)
|
||||||
{
|
{
|
||||||
string value = NewAt (key, true);
|
string value = NewAt (key, true);
|
||||||
if (!IsFilePathKey (key) || string.IsNullOrEmpty (value)) return "";
|
if (!IsImageFilePathKey (key) || string.IsNullOrEmpty (value)) return "";
|
||||||
switch (PackageReadHelper.GetPackageType (m_hReader))
|
switch (PackageReadHelper.GetPackageType (m_hReader))
|
||||||
{
|
{
|
||||||
case 1: // PKGTYPE_APPX
|
case 1: // PKGTYPE_APPX
|
||||||
@@ -2458,7 +2479,7 @@ namespace AppxPackage
|
|||||||
#endregion
|
#endregion
|
||||||
#region dependencies
|
#region dependencies
|
||||||
XmlElement nodeDependencies = xml.CreateElement ("Dependencies");
|
XmlElement nodeDependencies = xml.CreateElement ("Dependencies");
|
||||||
var deps = Dependencies;
|
var deps = Dependencies;
|
||||||
if (deps != null)
|
if (deps != null)
|
||||||
{
|
{
|
||||||
foreach (var dep in deps)
|
foreach (var dep in deps)
|
||||||
|
|||||||
@@ -936,6 +936,7 @@ namespace Bridge
|
|||||||
public _I_Notice Notice => new _I_Notice ();
|
public _I_Notice Notice => new _I_Notice ();
|
||||||
public _I_Process Process => proc;
|
public _I_Process Process => proc;
|
||||||
public _I_Web Web => new _I_Web ();
|
public _I_Web Web => new _I_Web ();
|
||||||
|
public _I_Utilities Utilities => new _I_Utilities ();
|
||||||
public string CmdArgs
|
public string CmdArgs
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
|||||||
816
DataUtils/Calendar.cs
Normal file
@@ -0,0 +1,816 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace DataUtils
|
||||||
|
{
|
||||||
|
[ComVisible (true)]
|
||||||
|
[ClassInterface (ClassInterfaceType.AutoDual)]
|
||||||
|
public class _I_Calendar
|
||||||
|
{
|
||||||
|
private DateTime _utcDateTime; // 存储 UTC 时间(所有算术的基础)
|
||||||
|
private Calendar _calendar; // 当前日历系统
|
||||||
|
private TimeZoneInfo _timeZone; // 当前时区
|
||||||
|
private bool _is24HourClock; // true = 24小时制,false = 12小时制
|
||||||
|
private List<string> _languages; // 语言优先级列表
|
||||||
|
private string _numeralSystem = "Latn"; // 数字系统(简化实现,仅存储)
|
||||||
|
private const long TicksPerNanosecond = 100; // 1 tick = 100 ns
|
||||||
|
|
||||||
|
// 缓存的本地时间(根据时区从 _utcDateTime 转换得到)
|
||||||
|
private DateTime _localDateTime;
|
||||||
|
|
||||||
|
// 更新本地时间(当 UTC 时间或时区改变时调用)
|
||||||
|
private void UpdateLocalDateTime ()
|
||||||
|
{
|
||||||
|
_localDateTime = TimeZoneInfo.ConvertTimeFromUtc (_utcDateTime, _timeZone);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 当本地时间被修改后,同步回 UTC 时间
|
||||||
|
private void UpdateUtcDateTime ()
|
||||||
|
{
|
||||||
|
_utcDateTime = TimeZoneInfo.ConvertTimeToUtc (_localDateTime, _timeZone);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 辅助:日历字段的读取
|
||||||
|
private int GetCalendarField (Func<Calendar, DateTime, int> fieldGetter)
|
||||||
|
{
|
||||||
|
return fieldGetter (_calendar, _localDateTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 辅助:日历字段的设置(返回新的本地时间)
|
||||||
|
private DateTime SetCalendarField (DateTime currentLocal, Func<Calendar, DateTime, int, DateTime> fieldSetter, int value)
|
||||||
|
{
|
||||||
|
return fieldSetter (_calendar, currentLocal, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据日历标识符创建日历实例
|
||||||
|
private static Calendar CreateCalendar (string calendarId)
|
||||||
|
{
|
||||||
|
switch (calendarId)
|
||||||
|
{
|
||||||
|
case "GregorianCalendar":
|
||||||
|
return new GregorianCalendar ();
|
||||||
|
case "HebrewCalendar":
|
||||||
|
return new HebrewCalendar ();
|
||||||
|
case "HijriCalendar":
|
||||||
|
return new HijriCalendar ();
|
||||||
|
case "JapaneseCalendar":
|
||||||
|
return new JapaneseCalendar ();
|
||||||
|
case "KoreanCalendar":
|
||||||
|
return new KoreanCalendar ();
|
||||||
|
case "TaiwanCalendar":
|
||||||
|
return new TaiwanCalendar ();
|
||||||
|
case "ThaiBuddhistCalendar":
|
||||||
|
return new ThaiBuddhistCalendar ();
|
||||||
|
case "UmAlQuraCalendar":
|
||||||
|
return new UmAlQuraCalendar ();
|
||||||
|
// 可根据需要增加更多日历
|
||||||
|
default:
|
||||||
|
return new GregorianCalendar ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private _I_Language GetFormatCulture ()
|
||||||
|
{
|
||||||
|
if (_languages == null || _languages.Count == 0)
|
||||||
|
return new _I_Language (CultureInfo.CurrentCulture.Name);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return new _I_Language (_languages [0]);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return new _I_Language (CultureInfo.CurrentCulture.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<object> JsArrayToList (object jsArray)
|
||||||
|
{
|
||||||
|
var result = new List<object> ();
|
||||||
|
|
||||||
|
if (jsArray == null)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
// JS Array 有 length 属性和数字索引器
|
||||||
|
var type = jsArray.GetType ();
|
||||||
|
|
||||||
|
int length = (int)type.InvokeMember (
|
||||||
|
"length",
|
||||||
|
BindingFlags.GetProperty,
|
||||||
|
null,
|
||||||
|
jsArray,
|
||||||
|
null);
|
||||||
|
|
||||||
|
for (int i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
object value = type.InvokeMember (
|
||||||
|
i.ToString (),
|
||||||
|
BindingFlags.GetProperty,
|
||||||
|
null,
|
||||||
|
jsArray,
|
||||||
|
null);
|
||||||
|
|
||||||
|
result.Add (value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public _I_Calendar ()
|
||||||
|
: this (new List<string> { CultureInfo.CurrentCulture.Name },
|
||||||
|
"GregorianCalendar", "24HourClock", TimeZoneInfo.Local.Id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public _I_Calendar (object languages)
|
||||||
|
: this (languages, "GregorianCalendar", "24HourClock", TimeZoneInfo.Local.Id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public _I_Calendar (object languages, string calendar, string clock)
|
||||||
|
: this (languages, calendar, clock, TimeZoneInfo.Local.Id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public _I_Calendar (object languages, string calendar, string clock, string timeZoneId)
|
||||||
|
{
|
||||||
|
_languages = languages == null ? new List<string> () : new List<string> (JsArrayToList (languages).Select (e => e as string));
|
||||||
|
if (_languages.Count == 0)
|
||||||
|
_languages.Add (CultureInfo.CurrentCulture.Name);
|
||||||
|
|
||||||
|
_calendar = CreateCalendar (calendar);
|
||||||
|
_is24HourClock = (clock == "24HourClock");
|
||||||
|
_timeZone = TimeZoneInfo.FindSystemTimeZoneById (timeZoneId);
|
||||||
|
_utcDateTime = DateTime.UtcNow;
|
||||||
|
UpdateLocalDateTime ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Day
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _calendar.GetDayOfMonth (_localDateTime);
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
int currentDay = _calendar.GetDayOfMonth (_localDateTime);
|
||||||
|
if (value == currentDay) return;
|
||||||
|
// 通过加减天数来设置日期
|
||||||
|
DateTime newLocal = _calendar.AddDays (_localDateTime, value - currentDay);
|
||||||
|
_localDateTime = newLocal;
|
||||||
|
UpdateUtcDateTime ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int DayOfWeek
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
// 返回 0-6,0 表示星期日
|
||||||
|
return (int)_calendar.GetDayOfWeek (_localDateTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Era
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _calendar.GetEra (_localDateTime);
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
// 更改纪元较复杂,简化:仅当值不同时不做任何操作(可根据需求实现)
|
||||||
|
// 这里忽略设置,或者可以抛出 NotSupportedException
|
||||||
|
if (value != Era)
|
||||||
|
throw new NotSupportedException ("Setting Era directly is not supported in this implementation.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int FirstDayInThisMonth
|
||||||
|
{
|
||||||
|
get { return 1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int FirstEra
|
||||||
|
{
|
||||||
|
get { return _calendar.GetEra (_calendar.MinSupportedDateTime); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int FirstHourInThisPeriod
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_is24HourClock)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return (Period == 0) ? 1 : 13;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int FirstMinuteInThisHour
|
||||||
|
{
|
||||||
|
get { return 0; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int FirstMonthInThisYear
|
||||||
|
{
|
||||||
|
get { return 1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int FirstPeriodInThisDay
|
||||||
|
{
|
||||||
|
get { return 0; } // 0 = AM
|
||||||
|
}
|
||||||
|
|
||||||
|
public int FirstSecondInThisMinute
|
||||||
|
{
|
||||||
|
get { return 0; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int FirstYearInThisEra
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
DateTime eraStart = _calendar.MinSupportedDateTime;
|
||||||
|
int targetEra = Era;
|
||||||
|
while (_calendar.GetEra (eraStart) != targetEra && eraStart < DateTime.MaxValue)
|
||||||
|
{
|
||||||
|
eraStart = _calendar.AddYears (eraStart, 1);
|
||||||
|
}
|
||||||
|
return _calendar.GetYear (eraStart);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Hour
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
int hour24 = _calendar.GetHour (_localDateTime);
|
||||||
|
if (_is24HourClock)
|
||||||
|
return hour24;
|
||||||
|
int hour12 = hour24 % 12;
|
||||||
|
return (hour12 == 0) ? 12 : hour12;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_is24HourClock)
|
||||||
|
{
|
||||||
|
if (value < 0 || value > 23)
|
||||||
|
throw new ArgumentOutOfRangeException (nameof (value), "Hour must be between 0 and 23 for 24-hour clock.");
|
||||||
|
DateTime newLocal = _localDateTime.Date.AddHours (value).AddMinutes (Minute).AddSeconds (Second);
|
||||||
|
_localDateTime = newLocal;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (value < 1 || value > 12)
|
||||||
|
throw new ArgumentOutOfRangeException (nameof (value), "Hour must be between 1 and 12 for 12-hour clock.");
|
||||||
|
int hour24 = value % 12;
|
||||||
|
if (Period == 1) hour24 += 12;
|
||||||
|
DateTime newLocal = _localDateTime.Date.AddHours (hour24).AddMinutes (Minute).AddSeconds (Second);
|
||||||
|
_localDateTime = newLocal;
|
||||||
|
}
|
||||||
|
UpdateUtcDateTime ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsDaylightSavingTime
|
||||||
|
{
|
||||||
|
get { return _timeZone.IsDaylightSavingTime (_localDateTime); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public _I_List Languages
|
||||||
|
{
|
||||||
|
get { return new _I_List (_languages.AsReadOnly ().Select (e => (object)e), true) ; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int LastDayInThisMonth
|
||||||
|
{
|
||||||
|
get { return _calendar.GetDaysInMonth (_calendar.GetYear (_localDateTime), _calendar.GetMonth (_localDateTime)); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int LastEra
|
||||||
|
{
|
||||||
|
get { return _calendar.GetEra (_calendar.MaxSupportedDateTime); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int LastHourInThisPeriod
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_is24HourClock)
|
||||||
|
return 23;
|
||||||
|
else
|
||||||
|
return (Period == 0) ? 11 : 23;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int LastMinuteInThisHour
|
||||||
|
{
|
||||||
|
get { return 59; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int LastMonthInThisYear
|
||||||
|
{
|
||||||
|
get { return _calendar.GetMonthsInYear (_calendar.GetYear (_localDateTime)); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int LastPeriodInThisDay
|
||||||
|
{
|
||||||
|
get { return 1; } // 1 = PM
|
||||||
|
}
|
||||||
|
|
||||||
|
public int LastSecondInThisMinute
|
||||||
|
{
|
||||||
|
get { return 59; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int LastYearInThisEra
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
DateTime eraEnd = _calendar.MaxSupportedDateTime;
|
||||||
|
int targetEra = Era;
|
||||||
|
while (_calendar.GetEra (eraEnd) != targetEra && eraEnd > DateTime.MinValue)
|
||||||
|
{
|
||||||
|
eraEnd = _calendar.AddYears (eraEnd, -1);
|
||||||
|
}
|
||||||
|
return _calendar.GetYear (eraEnd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Minute
|
||||||
|
{
|
||||||
|
get { return _calendar.GetMinute (_localDateTime); }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value < 0 || value > 59)
|
||||||
|
throw new ArgumentOutOfRangeException (nameof (value), "Minute must be between 0 and 59.");
|
||||||
|
DateTime newLocal = _localDateTime.AddMinutes (value - _calendar.GetMinute (_localDateTime));
|
||||||
|
_localDateTime = newLocal;
|
||||||
|
UpdateUtcDateTime ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Month
|
||||||
|
{
|
||||||
|
get { return _calendar.GetMonth (_localDateTime); }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value < 1 || value > _calendar.GetMonthsInYear (_calendar.GetYear (_localDateTime)))
|
||||||
|
throw new ArgumentOutOfRangeException (nameof (value), "Month is out of range for current year.");
|
||||||
|
DateTime newLocal = SetCalendarField (_localDateTime, (cal, dt, val) => cal.AddMonths (dt, val - cal.GetMonth (dt)), value);
|
||||||
|
_localDateTime = newLocal;
|
||||||
|
UpdateUtcDateTime ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Nanosecond
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
long ticksInSecond = _localDateTime.Ticks % TimeSpan.TicksPerSecond;
|
||||||
|
return (int)(ticksInSecond * 100); // 1 tick = 100 ns
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value < 0 || value > 999999999)
|
||||||
|
throw new ArgumentOutOfRangeException (nameof (value), "Nanosecond must be between 0 and 999,999,999.");
|
||||||
|
long ticks = (_localDateTime.Ticks / TimeSpan.TicksPerSecond) * TimeSpan.TicksPerSecond + (value / 100);
|
||||||
|
_localDateTime = new DateTime (ticks, _localDateTime.Kind);
|
||||||
|
UpdateUtcDateTime ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int NumberOfDaysInThisMonth
|
||||||
|
{
|
||||||
|
get { return LastDayInThisMonth; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int NumberOfEras
|
||||||
|
{
|
||||||
|
get { return _calendar.Eras.Length; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int NumberOfHoursInThisPeriod
|
||||||
|
{
|
||||||
|
get { return _is24HourClock ? 24 : 12; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int NumberOfMinutesInThisHour
|
||||||
|
{
|
||||||
|
get { return 60; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int NumberOfMonthsInThisYear
|
||||||
|
{
|
||||||
|
get { return _calendar.GetMonthsInYear (_calendar.GetYear (_localDateTime)); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int NumberOfPeriodsInThisDay
|
||||||
|
{
|
||||||
|
get { return 2; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int NumberOfSecondsInThisMinute
|
||||||
|
{
|
||||||
|
get { return 60; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int NumberOfYearsInThisEra
|
||||||
|
{
|
||||||
|
get { return LastYearInThisEra - FirstYearInThisEra + 1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string NumeralSystem
|
||||||
|
{
|
||||||
|
get { return _numeralSystem; }
|
||||||
|
set { _numeralSystem = value; } // 简化:未实现实际数字转换
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Period
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
int hour24 = _calendar.GetHour (_localDateTime);
|
||||||
|
return (hour24 >= 12) ? 1 : 0;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value != 0 && value != 1)
|
||||||
|
throw new ArgumentOutOfRangeException (nameof (value), "Period must be 0 (AM) or 1 (PM).");
|
||||||
|
int currentPeriod = Period;
|
||||||
|
if (currentPeriod == value) return;
|
||||||
|
// 切换 AM/PM:加减 12 小时
|
||||||
|
DateTime newLocal = _localDateTime.AddHours (value == 0 ? -12 : 12);
|
||||||
|
_localDateTime = newLocal;
|
||||||
|
UpdateUtcDateTime ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ResolvedLanguage
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_languages != null && _languages.Count > 0)
|
||||||
|
return _languages [0];
|
||||||
|
return CultureInfo.CurrentCulture.Name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Second
|
||||||
|
{
|
||||||
|
get { return _calendar.GetSecond (_localDateTime); }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value < 0 || value > 59)
|
||||||
|
throw new ArgumentOutOfRangeException (nameof (value), "Second must be between 0 and 59.");
|
||||||
|
DateTime newLocal = _localDateTime.AddSeconds (value - _calendar.GetSecond (_localDateTime));
|
||||||
|
_localDateTime = newLocal;
|
||||||
|
UpdateUtcDateTime ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Year
|
||||||
|
{
|
||||||
|
get { return _calendar.GetYear (_localDateTime); }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value < _calendar.GetYear (_calendar.MinSupportedDateTime) || value > _calendar.GetYear (_calendar.MaxSupportedDateTime))
|
||||||
|
throw new ArgumentOutOfRangeException (nameof (value), "Year is out of range for this calendar.");
|
||||||
|
DateTime newLocal = SetCalendarField (_localDateTime, (cal, dt, val) => cal.AddYears (dt, val - cal.GetYear (dt)), value);
|
||||||
|
_localDateTime = newLocal;
|
||||||
|
UpdateUtcDateTime ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddDays (int days)
|
||||||
|
{
|
||||||
|
_localDateTime = _calendar.AddDays (_localDateTime, days);
|
||||||
|
UpdateUtcDateTime ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddEras (int eras)
|
||||||
|
{
|
||||||
|
// 简化:每个纪元按 1000 年估算(实际应基于日历的纪元范围)
|
||||||
|
// 大多数情况下不应频繁使用此方法
|
||||||
|
_localDateTime = _calendar.AddYears (_localDateTime, eras * 1000);
|
||||||
|
UpdateUtcDateTime ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddHours (int hours)
|
||||||
|
{
|
||||||
|
_localDateTime = _localDateTime.AddHours (hours);
|
||||||
|
UpdateUtcDateTime ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddMinutes (int minutes)
|
||||||
|
{
|
||||||
|
_localDateTime = _localDateTime.AddMinutes (minutes);
|
||||||
|
UpdateUtcDateTime ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddMonths (int months)
|
||||||
|
{
|
||||||
|
_localDateTime = _calendar.AddMonths (_localDateTime, months);
|
||||||
|
UpdateUtcDateTime ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddNanoseconds (int nanoseconds)
|
||||||
|
{
|
||||||
|
long ticksToAdd = nanoseconds / 100;
|
||||||
|
_localDateTime = _localDateTime.AddTicks (ticksToAdd);
|
||||||
|
UpdateUtcDateTime ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddPeriods (int periods)
|
||||||
|
{
|
||||||
|
_localDateTime = _localDateTime.AddHours (periods * 12);
|
||||||
|
UpdateUtcDateTime ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddSeconds (int seconds)
|
||||||
|
{
|
||||||
|
_localDateTime = _localDateTime.AddSeconds (seconds);
|
||||||
|
UpdateUtcDateTime ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddWeeks (int weeks)
|
||||||
|
{
|
||||||
|
AddDays (weeks * 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddYears (int years)
|
||||||
|
{
|
||||||
|
_localDateTime = _calendar.AddYears (_localDateTime, years);
|
||||||
|
UpdateUtcDateTime ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ChangeCalendarSystem (string calendarId)
|
||||||
|
{
|
||||||
|
Calendar newCalendar = CreateCalendar (calendarId);
|
||||||
|
// 注意:日历改变不会改变绝对时间,但会影响组件(年、月、日等)
|
||||||
|
// 只需替换日历实例,_localDateTime 保持不变(但解释方式变了)
|
||||||
|
_calendar = newCalendar;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ChangeClock (string clock)
|
||||||
|
{
|
||||||
|
_is24HourClock = (clock == "24HourClock");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ChangeTimeZone (string timeZoneId)
|
||||||
|
{
|
||||||
|
_timeZone = TimeZoneInfo.FindSystemTimeZoneById (timeZoneId);
|
||||||
|
UpdateLocalDateTime (); // 重新计算本地时间(UTC 不变)
|
||||||
|
}
|
||||||
|
|
||||||
|
public _I_Calendar Clone ()
|
||||||
|
{
|
||||||
|
var clone = new _I_Calendar (_languages, GetCalendarSystem (), GetClock (), GetTimeZone ());
|
||||||
|
clone.SetDateTime (GetDateTime ());
|
||||||
|
return clone;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Compare (_I_Calendar other)
|
||||||
|
{
|
||||||
|
if (other == null) return 1;
|
||||||
|
return DateTime.Compare (this.GetDateTime (), other.GetDateTime ());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DateTime JsDateToDateTime (object jsDate)
|
||||||
|
{
|
||||||
|
if (jsDate == null)
|
||||||
|
throw new ArgumentNullException (nameof (jsDate));
|
||||||
|
Type type = jsDate.GetType ();
|
||||||
|
double milliseconds = (double)type.InvokeMember (
|
||||||
|
"getTime",
|
||||||
|
BindingFlags.InvokeMethod,
|
||||||
|
null,
|
||||||
|
jsDate,
|
||||||
|
null);
|
||||||
|
DateTimeOffset epoch = new DateTimeOffset (1970, 1, 1, 0, 0, 0, TimeSpan.Zero);
|
||||||
|
DateTimeOffset dateTimeOffset = epoch.AddMilliseconds (milliseconds);
|
||||||
|
return dateTimeOffset.UtcDateTime;
|
||||||
|
}
|
||||||
|
public int CompareDateTime (object other)
|
||||||
|
{
|
||||||
|
return DateTime.Compare (this.GetDateTime (), JsDateToDateTime (other));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CopyTo (_I_Calendar other)
|
||||||
|
{
|
||||||
|
if (other == null) throw new ArgumentNullException (nameof (other));
|
||||||
|
other._utcDateTime = this._utcDateTime;
|
||||||
|
other._localDateTime = this._localDateTime;
|
||||||
|
other._calendar = this._calendar;
|
||||||
|
other._timeZone = this._timeZone;
|
||||||
|
other._is24HourClock = this._is24HourClock;
|
||||||
|
other._languages = new List<string> (this._languages);
|
||||||
|
other._numeralSystem = this._numeralSystem;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string DayAsPaddedString (int minDigits)
|
||||||
|
{
|
||||||
|
return Day.ToString ().PadLeft (minDigits, '0');
|
||||||
|
}
|
||||||
|
|
||||||
|
public string DayAsString ()
|
||||||
|
{
|
||||||
|
return Day.ToString ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string DayOfWeekAsSoloString ()
|
||||||
|
{
|
||||||
|
return DayOfWeekAsString ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string DayOfWeekAsSoloString (int idealLength)
|
||||||
|
{
|
||||||
|
// 简化:忽略 idealLength
|
||||||
|
return DayOfWeekAsString ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string DayOfWeekAsString ()
|
||||||
|
{
|
||||||
|
return _localDateTime.ToString ("dddd", GetFormatCulture ());
|
||||||
|
}
|
||||||
|
|
||||||
|
public string DayOfWeekAsString (int idealLength)
|
||||||
|
{
|
||||||
|
return DayOfWeekAsString ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string EraAsString ()
|
||||||
|
{
|
||||||
|
// 简化:返回纪元索引的字符串
|
||||||
|
return Era.ToString ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string EraAsString (int idealLength)
|
||||||
|
{
|
||||||
|
return EraAsString ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetCalendarSystem ()
|
||||||
|
{
|
||||||
|
if (_calendar is GregorianCalendar) return "GregorianCalendar";
|
||||||
|
if (_calendar is HebrewCalendar) return "HebrewCalendar";
|
||||||
|
if (_calendar is HijriCalendar) return "HijriCalendar";
|
||||||
|
if (_calendar is JapaneseCalendar) return "JapaneseCalendar";
|
||||||
|
if (_calendar is KoreanCalendar) return "KoreanCalendar";
|
||||||
|
if (_calendar is TaiwanCalendar) return "TaiwanCalendar";
|
||||||
|
if (_calendar is ThaiBuddhistCalendar) return "ThaiBuddhistCalendar";
|
||||||
|
if (_calendar is UmAlQuraCalendar) return "UmAlQuraCalendar";
|
||||||
|
return "GregorianCalendar";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetClock ()
|
||||||
|
{
|
||||||
|
return _is24HourClock ? "24HourClock" : "12HourClock";
|
||||||
|
}
|
||||||
|
|
||||||
|
public DateTime GetDateTime ()
|
||||||
|
{
|
||||||
|
// 返回 UTC 时间
|
||||||
|
return _utcDateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetTimeZone ()
|
||||||
|
{
|
||||||
|
return _timeZone.Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string HourAsPaddedString (int minDigits)
|
||||||
|
{
|
||||||
|
return Hour.ToString ().PadLeft (minDigits, '0');
|
||||||
|
}
|
||||||
|
|
||||||
|
public string HourAsString ()
|
||||||
|
{
|
||||||
|
return Hour.ToString ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string MinuteAsPaddedString (int minDigits)
|
||||||
|
{
|
||||||
|
return Minute.ToString ().PadLeft (minDigits, '0');
|
||||||
|
}
|
||||||
|
|
||||||
|
public string MinuteAsString ()
|
||||||
|
{
|
||||||
|
return Minute.ToString ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string MonthAsNumericString ()
|
||||||
|
{
|
||||||
|
return Month.ToString ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string MonthAsPaddedNumericString (int minDigits)
|
||||||
|
{
|
||||||
|
return Month.ToString ().PadLeft (minDigits, '0');
|
||||||
|
}
|
||||||
|
|
||||||
|
public string MonthAsSoloString ()
|
||||||
|
{
|
||||||
|
return _localDateTime.ToString ("MMMM", GetFormatCulture ());
|
||||||
|
}
|
||||||
|
|
||||||
|
public string MonthAsSoloString (int idealLength)
|
||||||
|
{
|
||||||
|
return MonthAsSoloString ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string MonthAsString ()
|
||||||
|
{
|
||||||
|
return _localDateTime.ToString ("MMM", GetFormatCulture ());
|
||||||
|
}
|
||||||
|
|
||||||
|
public string MonthAsString (int idealLength)
|
||||||
|
{
|
||||||
|
return MonthAsString ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string NanosecondAsPaddedString (int minDigits)
|
||||||
|
{
|
||||||
|
return Nanosecond.ToString ().PadLeft (minDigits, '0');
|
||||||
|
}
|
||||||
|
|
||||||
|
public string NanosecondAsString ()
|
||||||
|
{
|
||||||
|
return Nanosecond.ToString ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string PeriodAsString ()
|
||||||
|
{
|
||||||
|
return PeriodAsString (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string PeriodAsString (int idealLength)
|
||||||
|
{
|
||||||
|
return _localDateTime.ToString ("tt", GetFormatCulture ());
|
||||||
|
}
|
||||||
|
|
||||||
|
public string SecondAsPaddedString (int minDigits)
|
||||||
|
{
|
||||||
|
return Second.ToString ().PadLeft (minDigits, '0');
|
||||||
|
}
|
||||||
|
|
||||||
|
public string SecondAsString ()
|
||||||
|
{
|
||||||
|
return Second.ToString ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetDateTime (DateTime value)
|
||||||
|
{
|
||||||
|
_utcDateTime = value.ToUniversalTime ();
|
||||||
|
UpdateLocalDateTime ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetToMax ()
|
||||||
|
{
|
||||||
|
SetDateTime (DateTime.MaxValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetToMin ()
|
||||||
|
{
|
||||||
|
SetDateTime (DateTime.MinValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetToNow ()
|
||||||
|
{
|
||||||
|
SetDateTime (DateTime.UtcNow);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string TimeZoneAsString ()
|
||||||
|
{
|
||||||
|
return TimeZoneAsString (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string TimeZoneAsString (int idealLength)
|
||||||
|
{
|
||||||
|
// 简化:返回标准显示名称
|
||||||
|
return _timeZone.DisplayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string YearAsPaddedString (int minDigits)
|
||||||
|
{
|
||||||
|
return Year.ToString ().PadLeft (minDigits, '0');
|
||||||
|
}
|
||||||
|
|
||||||
|
public string YearAsString ()
|
||||||
|
{
|
||||||
|
return Year.ToString ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string YearAsTruncatedString (int remainingDigits)
|
||||||
|
{
|
||||||
|
string yearStr = Year.ToString ();
|
||||||
|
if (yearStr.Length <= remainingDigits)
|
||||||
|
return yearStr;
|
||||||
|
return yearStr.Substring (yearStr.Length - remainingDigits);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -45,6 +45,8 @@
|
|||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="Calendar.cs" />
|
||||||
|
<Compile Include="DateTimeFormat.cs" />
|
||||||
<Compile Include="Download.cs" />
|
<Compile Include="Download.cs" />
|
||||||
<Compile Include="Enumerable.cs" />
|
<Compile Include="Enumerable.cs" />
|
||||||
<Compile Include="HResult.cs" />
|
<Compile Include="HResult.cs" />
|
||||||
|
|||||||
494
DataUtils/DateTimeFormat.cs
Normal file
@@ -0,0 +1,494 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace DataUtils
|
||||||
|
{
|
||||||
|
public enum YearFormat
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Default = 1,
|
||||||
|
Abbreviated = 2,
|
||||||
|
Full = 3,
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum MonthFormat
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Default = 1,
|
||||||
|
Abbreviated = 2,
|
||||||
|
Full = 3,
|
||||||
|
Numeric = 4,
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum DayFormat
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Default = 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum DayOfWeekFormat
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Default = 1,
|
||||||
|
Abbreviated = 2,
|
||||||
|
Full = 3,
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum HourFormat
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Default = 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum MinuteFormat
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Default = 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum SecondFormat
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Default = 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
[ComVisible (true)]
|
||||||
|
[ClassInterface (ClassInterfaceType.AutoDual)]
|
||||||
|
public class _I_DateTimeFormatter
|
||||||
|
{
|
||||||
|
// ---------- 私有字段 ----------
|
||||||
|
private string _formatTemplate; // 原始模板字符串
|
||||||
|
private string _formatPattern; // 实际用于 .NET 格式化的模式
|
||||||
|
private List<string> _languages; // 语言优先级列表
|
||||||
|
private string _geographicRegion; // 地理区域
|
||||||
|
private string _calendar = "GregorianCalendar";
|
||||||
|
private string _clock = "24HourClock";
|
||||||
|
private string _numeralSystem = "Latn";
|
||||||
|
private CultureInfo _culture; // 解析后的 CultureInfo
|
||||||
|
private string _resolvedLanguage; // 实际使用的语言
|
||||||
|
private string _resolvedGeographicRegion; // 实际使用的区域
|
||||||
|
|
||||||
|
// 存储构造时传入的枚举值(用于 IncludeXXX 属性)
|
||||||
|
private YearFormat _yearFormat = YearFormat.None;
|
||||||
|
private MonthFormat _monthFormat = MonthFormat.None;
|
||||||
|
private DayFormat _dayFormat = DayFormat.None;
|
||||||
|
private DayOfWeekFormat _dayOfWeekFormat = DayOfWeekFormat.None;
|
||||||
|
private HourFormat _hourFormat = HourFormat.None;
|
||||||
|
private MinuteFormat _minuteFormat = MinuteFormat.None;
|
||||||
|
private SecondFormat _secondFormat = SecondFormat.None;
|
||||||
|
|
||||||
|
// ---------- 辅助方法 ----------
|
||||||
|
private static string MapTemplateToPattern (string template, CultureInfo culture, string clock)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty (template))
|
||||||
|
return string.Empty;
|
||||||
|
|
||||||
|
switch (template.ToLowerInvariant ())
|
||||||
|
{
|
||||||
|
case "longdate":
|
||||||
|
return culture.DateTimeFormat.LongDatePattern;
|
||||||
|
case "shortdate":
|
||||||
|
return culture.DateTimeFormat.ShortDatePattern;
|
||||||
|
case "longtime":
|
||||||
|
return culture.DateTimeFormat.LongTimePattern;
|
||||||
|
case "shorttime":
|
||||||
|
return culture.DateTimeFormat.ShortTimePattern;
|
||||||
|
case "dayofweek":
|
||||||
|
return culture.DateTimeFormat.ShortestDayNames? [0] ?? "dddd"; // 近似
|
||||||
|
case "dayofweek.full":
|
||||||
|
return "dddd";
|
||||||
|
case "dayofweek.abbreviated":
|
||||||
|
return "ddd";
|
||||||
|
case "day":
|
||||||
|
return "dd";
|
||||||
|
case "month":
|
||||||
|
return "MMMM";
|
||||||
|
case "month.full":
|
||||||
|
return "MMMM";
|
||||||
|
case "month.abbreviated":
|
||||||
|
return "MMM";
|
||||||
|
case "month.numeric":
|
||||||
|
return "MM";
|
||||||
|
case "year":
|
||||||
|
return "yyyy";
|
||||||
|
case "year.full":
|
||||||
|
return "yyyy";
|
||||||
|
case "year.abbreviated":
|
||||||
|
return "yy";
|
||||||
|
case "hour":
|
||||||
|
return clock == "24HourClock" ? "HH" : "hh";
|
||||||
|
case "minute":
|
||||||
|
return "mm";
|
||||||
|
case "second":
|
||||||
|
return "ss";
|
||||||
|
case "timezone":
|
||||||
|
return "zzz";
|
||||||
|
default:
|
||||||
|
// 如果不是预定义模板,则当作自定义模式直接返回
|
||||||
|
return template;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据枚举组合构建格式模式
|
||||||
|
private static string BuildPatternFromEnums (YearFormat year, MonthFormat month, DayFormat day, DayOfWeekFormat dayOfWeek,
|
||||||
|
HourFormat hour, MinuteFormat minute, SecondFormat second,
|
||||||
|
string clock, CultureInfo culture)
|
||||||
|
{
|
||||||
|
var parts = new List<string> ();
|
||||||
|
// 日期部分
|
||||||
|
if (dayOfWeek != DayOfWeekFormat.None)
|
||||||
|
{
|
||||||
|
if (dayOfWeek == DayOfWeekFormat.Abbreviated)
|
||||||
|
parts.Add ("ddd");
|
||||||
|
else // Full or Default
|
||||||
|
parts.Add ("dddd");
|
||||||
|
}
|
||||||
|
if (year != YearFormat.None)
|
||||||
|
{
|
||||||
|
if (year == YearFormat.Abbreviated)
|
||||||
|
parts.Add ("yy");
|
||||||
|
else
|
||||||
|
parts.Add ("yyyy");
|
||||||
|
}
|
||||||
|
if (month != MonthFormat.None)
|
||||||
|
{
|
||||||
|
switch (month)
|
||||||
|
{
|
||||||
|
case MonthFormat.Numeric:
|
||||||
|
parts.Add ("MM");
|
||||||
|
break;
|
||||||
|
case MonthFormat.Abbreviated:
|
||||||
|
parts.Add ("MMM");
|
||||||
|
break;
|
||||||
|
case MonthFormat.Full:
|
||||||
|
parts.Add ("MMMM");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
parts.Add ("MM");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (day != DayFormat.None)
|
||||||
|
{
|
||||||
|
parts.Add ("dd");
|
||||||
|
}
|
||||||
|
string datePart = string.Join (" ", parts);
|
||||||
|
// 时间部分
|
||||||
|
var timeParts = new List<string> ();
|
||||||
|
if (hour != HourFormat.None)
|
||||||
|
{
|
||||||
|
if (clock == "24HourClock")
|
||||||
|
timeParts.Add ("HH");
|
||||||
|
else
|
||||||
|
timeParts.Add ("hh");
|
||||||
|
}
|
||||||
|
if (minute != MinuteFormat.None)
|
||||||
|
{
|
||||||
|
timeParts.Add ("mm");
|
||||||
|
}
|
||||||
|
if (second != SecondFormat.None)
|
||||||
|
{
|
||||||
|
timeParts.Add ("ss");
|
||||||
|
}
|
||||||
|
string timePart = timeParts.Count > 0 ? string.Join (":", timeParts) : "";
|
||||||
|
if (!string.IsNullOrEmpty (datePart) && !string.IsNullOrEmpty (timePart))
|
||||||
|
return datePart + " " + timePart;
|
||||||
|
if (!string.IsNullOrEmpty (datePart))
|
||||||
|
return datePart;
|
||||||
|
return timePart;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将 JS Date 对象转换为 DateTime
|
||||||
|
private DateTime ConvertJsDateToDateTime (object jsDate)
|
||||||
|
{
|
||||||
|
if (jsDate == null)
|
||||||
|
throw new ArgumentNullException (nameof (jsDate));
|
||||||
|
|
||||||
|
Type type = jsDate.GetType ();
|
||||||
|
// 调用 getTime() 获取毫秒数 (double)
|
||||||
|
double milliseconds = (double)type.InvokeMember (
|
||||||
|
"getTime",
|
||||||
|
BindingFlags.InvokeMethod,
|
||||||
|
null,
|
||||||
|
jsDate,
|
||||||
|
null);
|
||||||
|
|
||||||
|
// 手动计算 Unix 纪元转换(兼容低版本 .NET)
|
||||||
|
DateTime epoch = new DateTime (1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
||||||
|
DateTime utcDateTime = epoch.AddMilliseconds (milliseconds);
|
||||||
|
// 返回本地时间(可根据需求调整)
|
||||||
|
return utcDateTime.ToLocalTime ();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化文化信息
|
||||||
|
private void InitializeCulture ()
|
||||||
|
{
|
||||||
|
string lang = (_languages != null && _languages.Count > 0) ? _languages [0] : CultureInfo.CurrentCulture.Name;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_culture = new CultureInfo (lang);
|
||||||
|
_resolvedLanguage = _culture.Name;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
_culture = CultureInfo.CurrentCulture;
|
||||||
|
_resolvedLanguage = _culture.Name;
|
||||||
|
}
|
||||||
|
_resolvedGeographicRegion = _geographicRegion ?? _culture.Name;
|
||||||
|
// 根据区域和语言更新格式模式(如果使用模板)
|
||||||
|
if (!string.IsNullOrEmpty (_formatTemplate))
|
||||||
|
{
|
||||||
|
_formatPattern = MapTemplateToPattern (_formatTemplate, _culture, _clock);
|
||||||
|
}
|
||||||
|
else if (_yearFormat != YearFormat.None || _monthFormat != MonthFormat.None ||
|
||||||
|
_dayFormat != DayFormat.None || _dayOfWeekFormat != DayOfWeekFormat.None ||
|
||||||
|
_hourFormat != HourFormat.None || _minuteFormat != MinuteFormat.None ||
|
||||||
|
_secondFormat != SecondFormat.None)
|
||||||
|
{
|
||||||
|
_formatPattern = BuildPatternFromEnums (_yearFormat, _monthFormat, _dayFormat, _dayOfWeekFormat,
|
||||||
|
_hourFormat, _minuteFormat, _secondFormat, _clock, _culture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------- 构造函数 ----------
|
||||||
|
public _I_DateTimeFormatter (string formatTemplate)
|
||||||
|
: this (formatTemplate, null, null, null, null)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public _I_DateTimeFormatter (string formatTemplate, IEnumerable<string> languages)
|
||||||
|
: this (formatTemplate, languages, null, null, null)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public _I_DateTimeFormatter (string formatTemplate, IEnumerable<string> languages, string geographicRegion, string calendar, string clock)
|
||||||
|
{
|
||||||
|
_formatTemplate = formatTemplate;
|
||||||
|
_languages = languages == null ? new List<string> () : new List<string> (languages);
|
||||||
|
_geographicRegion = geographicRegion;
|
||||||
|
if (!string.IsNullOrEmpty (calendar))
|
||||||
|
_calendar = calendar;
|
||||||
|
if (!string.IsNullOrEmpty (clock))
|
||||||
|
_clock = clock;
|
||||||
|
InitializeCulture ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public _I_DateTimeFormatter (YearFormat year, MonthFormat month, DayFormat day, DayOfWeekFormat dayOfWeek)
|
||||||
|
: this (year, month, day, dayOfWeek, HourFormat.None, MinuteFormat.None, SecondFormat.None, null, null, null, null)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public _I_DateTimeFormatter (HourFormat hour, MinuteFormat minute, SecondFormat second)
|
||||||
|
: this (YearFormat.None, MonthFormat.None, DayFormat.None, DayOfWeekFormat.None, hour, minute, second, null, null, null, null)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public _I_DateTimeFormatter (YearFormat year, MonthFormat month, DayFormat day, DayOfWeekFormat dayOfWeek,
|
||||||
|
HourFormat hour, MinuteFormat minute, SecondFormat second,
|
||||||
|
IEnumerable<string> languages)
|
||||||
|
: this (year, month, day, dayOfWeek, hour, minute, second, languages, null, null, null)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public _I_DateTimeFormatter (YearFormat year, MonthFormat month, DayFormat day, DayOfWeekFormat dayOfWeek,
|
||||||
|
HourFormat hour, MinuteFormat minute, SecondFormat second,
|
||||||
|
IEnumerable<string> languages, string geographicRegion, string calendar, string clock)
|
||||||
|
{
|
||||||
|
_yearFormat = year;
|
||||||
|
_monthFormat = month;
|
||||||
|
_dayFormat = day;
|
||||||
|
_dayOfWeekFormat = dayOfWeek;
|
||||||
|
_hourFormat = hour;
|
||||||
|
_minuteFormat = minute;
|
||||||
|
_secondFormat = second;
|
||||||
|
_languages = languages == null ? new List<string> () : new List<string> (languages);
|
||||||
|
_geographicRegion = geographicRegion;
|
||||||
|
if (!string.IsNullOrEmpty (calendar))
|
||||||
|
_calendar = calendar;
|
||||||
|
if (!string.IsNullOrEmpty (clock))
|
||||||
|
_clock = clock;
|
||||||
|
InitializeCulture ();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------- 属性 ----------
|
||||||
|
public string Calendar
|
||||||
|
{
|
||||||
|
get { return _calendar; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_calendar = value;
|
||||||
|
// 日历更改可能需要重新初始化模式,这里简化处理
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Clock
|
||||||
|
{
|
||||||
|
get { return _clock; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_clock = value;
|
||||||
|
InitializeCulture (); // 重新生成模式(因为小时格式可能变化)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GeographicRegion
|
||||||
|
{
|
||||||
|
get { return _geographicRegion; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_geographicRegion = value;
|
||||||
|
InitializeCulture ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int IncludeDay
|
||||||
|
{
|
||||||
|
get { return (int)_dayFormat; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int IncludeDayOfWeek
|
||||||
|
{
|
||||||
|
get { return (int)_dayOfWeekFormat; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int IncludeHour
|
||||||
|
{
|
||||||
|
get { return (int)_hourFormat; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int IncludeMinute
|
||||||
|
{
|
||||||
|
get { return (int)_minuteFormat; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int IncludeMonth
|
||||||
|
{
|
||||||
|
get { return (int)_monthFormat; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int IncludeSecond
|
||||||
|
{
|
||||||
|
get { return (int)_secondFormat; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int IncludeYear
|
||||||
|
{
|
||||||
|
get { return (int)_yearFormat; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public _I_List Languages
|
||||||
|
{
|
||||||
|
get { return new _I_List (_languages.AsReadOnly ().Select (e => (object)e), true); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static _I_DateTimeFormatter LongDate
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return new _I_DateTimeFormatter ("longdate");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static _I_DateTimeFormatter LongTime
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return new _I_DateTimeFormatter ("longtime");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string NumeralSystem
|
||||||
|
{
|
||||||
|
get { return _numeralSystem; }
|
||||||
|
set { _numeralSystem = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public _I_List Patterns
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return new _I_List (new List<string> { _formatPattern }.AsReadOnly ().Select (e => (object)e), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ResolvedGeographicRegion
|
||||||
|
{
|
||||||
|
get { return _resolvedGeographicRegion; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ResolvedLanguage
|
||||||
|
{
|
||||||
|
get { return _resolvedLanguage; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static _I_DateTimeFormatter ShortDate
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return new _I_DateTimeFormatter ("shortdate");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static _I_DateTimeFormatter ShortTime
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return new _I_DateTimeFormatter ("shorttime");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Template
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty (_formatTemplate))
|
||||||
|
return _formatTemplate;
|
||||||
|
// 从枚举组合生成模板描述(简化)
|
||||||
|
return _formatPattern;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------- 方法 ----------
|
||||||
|
public string FormatC (DateTime dateTime)
|
||||||
|
{
|
||||||
|
return dateTime.ToString (_formatPattern, _culture);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string FormatC (DateTime dateTime, string timeZoneId)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty (timeZoneId))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById (timeZoneId);
|
||||||
|
DateTime targetTime = TimeZoneInfo.ConvertTime (dateTime, tzi);
|
||||||
|
return targetTime.ToString (_formatPattern, _culture);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// 时区无效,回退到原始时间
|
||||||
|
return dateTime.ToString (_formatPattern, _culture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dateTime.ToString (_formatPattern, _culture);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 为方便 JS 调用,提供接受 object 的重载(自动识别 JS Date)
|
||||||
|
public string Format (object jsDate)
|
||||||
|
{
|
||||||
|
DateTime dt = ConvertJsDateToDateTime (jsDate);
|
||||||
|
return FormatC (dt);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string FormatWithTimeZone (object jsDate, string timeZoneId)
|
||||||
|
{
|
||||||
|
DateTime dt = ConvertJsDateToDateTime (jsDate);
|
||||||
|
return FormatC (dt, timeZoneId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,7 +10,7 @@ namespace DataUtils
|
|||||||
{
|
{
|
||||||
[ComVisible (true)]
|
[ComVisible (true)]
|
||||||
[InterfaceType (ComInterfaceType.InterfaceIsDual)]
|
[InterfaceType (ComInterfaceType.InterfaceIsDual)]
|
||||||
public interface _I_Enumerable
|
public interface _I_Enumerable: IDisposable
|
||||||
{
|
{
|
||||||
int Length { get; set; }
|
int Length { get; set; }
|
||||||
object this [int index] { get; set; }
|
object this [int index] { get; set; }
|
||||||
@@ -33,6 +33,9 @@ namespace DataUtils
|
|||||||
int IndexOfKey (int key); // 按内部 key 查找
|
int IndexOfKey (int key); // 按内部 key 查找
|
||||||
void Move (int index, int newIndex); // 移动元素
|
void Move (int index, int newIndex); // 移动元素
|
||||||
void PushAll (object [] items); // 一次性 push 多个
|
void PushAll (object [] items); // 一次性 push 多个
|
||||||
|
object Get (int index);
|
||||||
|
object Set (int index, object value);
|
||||||
|
object At (int index);
|
||||||
}
|
}
|
||||||
public class _I_List: _I_Enumerable, IList
|
public class _I_List: _I_Enumerable, IList
|
||||||
{
|
{
|
||||||
@@ -43,6 +46,9 @@ namespace DataUtils
|
|||||||
IsReadOnly = readOnly;
|
IsReadOnly = readOnly;
|
||||||
IsSynchronized = sync;
|
IsSynchronized = sync;
|
||||||
}
|
}
|
||||||
|
public _I_List (bool readOnly = false, bool fixedSize = false, bool sync = true) :
|
||||||
|
this (null, readOnly, fixedSize, sync)
|
||||||
|
{ }
|
||||||
protected List<object> _list;
|
protected List<object> _list;
|
||||||
protected object _lock = new object ();
|
protected object _lock = new object ();
|
||||||
public object this [int index] { get { return _list [index]; } set { _list [index] = value; } }
|
public object this [int index] { get { return _list [index]; } set { _list [index] = value; } }
|
||||||
@@ -155,5 +161,13 @@ namespace DataUtils
|
|||||||
return first;
|
return first;
|
||||||
}
|
}
|
||||||
public void Unshift (object value) => _list.Insert (0, value);
|
public void Unshift (object value) => _list.Insert (0, value);
|
||||||
|
public void Dispose ()
|
||||||
|
{
|
||||||
|
_list?.Clear ();
|
||||||
|
_list = null;
|
||||||
|
}
|
||||||
|
public object Get (int index) => this [index];
|
||||||
|
public object Set (int index, object value) => this [index] = value;
|
||||||
|
public object At (int index) => this [index];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,29 +1,116 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
namespace DataUtils
|
namespace DataUtils
|
||||||
{
|
{
|
||||||
internal static class NativeMethods
|
internal static class NativeMethods
|
||||||
{
|
{
|
||||||
|
public const int LOCALE_SSHORTESTSCRIPT = 0x0000004F; // 获取四字母脚本代码
|
||||||
|
public const uint KLF_ACTIVATE = 0x00000001; // 激活键盘布局
|
||||||
// GetLocaleInfoW for LCID-based queries
|
// GetLocaleInfoW for LCID-based queries
|
||||||
[DllImport ("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
[DllImport ("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||||
public static extern int GetLocaleInfoW (int Locale, int LCType, [Out] StringBuilder lpLCData, int cchData);
|
public static extern int GetLocaleInfoW (int Locale, int LCType, [Out] StringBuilder lpLCData, int cchData);
|
||||||
|
|
||||||
// GetLocaleInfoEx for locale name based queries
|
// GetLocaleInfoEx for locale name based queries
|
||||||
[DllImport ("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
[DllImport ("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||||
public static extern int GetLocaleInfoEx (string lpLocaleName, int LCType, [Out] StringBuilder lpLCData, int cchData);
|
public static extern int GetLocaleInfoEx (string lpLocaleName, int LCType, [Out] StringBuilder lpLCData, int cchData);
|
||||||
|
|
||||||
// LocaleNameToLCID - available on Vista+; fallback is to use CultureInfo
|
// LocaleNameToLCID - available on Vista+; fallback is to use CultureInfo
|
||||||
[DllImport ("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
[DllImport ("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||||
public static extern int LocaleNameToLCID (string lpName, uint dwFlags);
|
public static extern int LocaleNameToLCID (string lpName, uint dwFlags);
|
||||||
|
|
||||||
// LCIDToLocaleName (Vista+)
|
// LCIDToLocaleName (Vista+)
|
||||||
[DllImport ("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
[DllImport ("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||||
public static extern int LCIDToLocaleName (int Locale, [Out] StringBuilder lpName, int cchName, uint dwFlags);
|
public static extern int LCIDToLocaleName (int Locale, [Out] StringBuilder lpName, int cchName, uint dwFlags);
|
||||||
|
[DllImport ("user32.dll")]
|
||||||
|
public static extern IntPtr GetKeyboardLayout (uint dwLayout);
|
||||||
|
[DllImport ("user32.dll", CharSet = CharSet.Auto)]
|
||||||
|
public static extern IntPtr LoadKeyboardLayout (string pwszKLID, uint Flags);
|
||||||
}
|
}
|
||||||
|
[ComVisible (true)]
|
||||||
|
[ClassInterface (ClassInterfaceType.AutoDual)]
|
||||||
|
public class _I_Language: System.Globalization.CultureInfo
|
||||||
|
{
|
||||||
|
public _I_Language (string localeName) : base (localeName) { }
|
||||||
|
public string AbbreviatedName => this.ThreeLetterISOLanguageName;
|
||||||
|
public string LanguageTag => this.IetfLanguageTag ?? this.Name;
|
||||||
|
public int LayoutDirection
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (base.TextInfo.IsRightToLeft) return 1;
|
||||||
|
string tag = this.LanguageTag;
|
||||||
|
bool isVerticalCandidate = false;
|
||||||
|
if (tag != null)
|
||||||
|
{
|
||||||
|
var scriptMatch = Regex.Match (tag, @"-([A-Za-z]{4})(?:-|$)");
|
||||||
|
if (scriptMatch.Success)
|
||||||
|
{
|
||||||
|
string script = scriptMatch.Groups [1].Value;
|
||||||
|
if (script == "Hani" || script == "Hira" || script == "Kana" || script == "Jpan" || script == "Kore" || script == "Hans" || script == "Hant")
|
||||||
|
isVerticalCandidate = true;
|
||||||
|
}
|
||||||
|
if (!isVerticalCandidate)
|
||||||
|
{
|
||||||
|
var regionMatch = Regex.Match (tag, @"-([A-Za-z]{2})$");
|
||||||
|
if (regionMatch.Success)
|
||||||
|
{
|
||||||
|
string region = regionMatch.Groups [1].Value.ToUpperInvariant ();
|
||||||
|
if (region == "JP" || region == "CN" || region == "TW" || region == "HK" || region == "MO" || region == "KR")
|
||||||
|
isVerticalCandidate = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isVerticalCandidate)
|
||||||
|
{
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public string Script
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder (10);
|
||||||
|
if (NativeMethods.GetLocaleInfoEx (this.Name, NativeMethods.LOCALE_SSHORTESTSCRIPT, sb, sb.Capacity) > 0)
|
||||||
|
return sb.ToString ();
|
||||||
|
|
||||||
|
// 如果失败,尝试从语言标记中解析脚本子标记(如 "zh-Hans-CN" 中的 "Hans")
|
||||||
|
var match = Regex.Match (this.Name, @"-([A-Za-z]{4})(?:-|$)");
|
||||||
|
if (match.Success)
|
||||||
|
return match.Groups [1].Value;
|
||||||
|
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public _I_List GetExtensionSubtags (string singleton)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty (singleton) || singleton.Length != 1)
|
||||||
|
throw new ArgumentException ("Singleton must be a single character", nameof (singleton));
|
||||||
|
var subtags = new List<string> ();
|
||||||
|
string tag = this.LanguageTag;
|
||||||
|
string pattern = $@"-{Regex.Escape (singleton)}-([a-zA-Z0-9](?:-[a-zA-Z0-9]+)*)";
|
||||||
|
var match = Regex.Match (tag, pattern);
|
||||||
|
if (match.Success)
|
||||||
|
{
|
||||||
|
string extPart = match.Groups [1].Value;
|
||||||
|
subtags.AddRange (extPart.Split ('-'));
|
||||||
|
}
|
||||||
|
return new _I_List (subtags.Select (i => (object)i));
|
||||||
|
}
|
||||||
|
public bool TrySetInputMethodLanguageTag (string languageTag)
|
||||||
|
{
|
||||||
|
int lcid = NativeMethods.LocaleNameToLCID (languageTag, 0);
|
||||||
|
if (lcid == 0)
|
||||||
|
return false;
|
||||||
|
string klid = $"{lcid:X8}";
|
||||||
|
IntPtr hkl = NativeMethods.LoadKeyboardLayout (klid, NativeMethods.KLF_ACTIVATE);
|
||||||
|
return hkl != IntPtr.Zero;
|
||||||
|
}
|
||||||
|
}
|
||||||
[ComVisible (true)]
|
[ComVisible (true)]
|
||||||
[ClassInterface (ClassInterfaceType.AutoDual)]
|
[ClassInterface (ClassInterfaceType.AutoDual)]
|
||||||
public class _I_Locale
|
public class _I_Locale
|
||||||
@@ -47,7 +134,6 @@ namespace DataUtils
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Current LCID (int)
|
// Current LCID (int)
|
||||||
public int CurrentLCID
|
public int CurrentLCID
|
||||||
{
|
{
|
||||||
@@ -63,7 +149,6 @@ namespace DataUtils
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert LCID -> locale name (e.g. 1033 -> "en-US")
|
// Convert LCID -> locale name (e.g. 1033 -> "en-US")
|
||||||
public string ToLocaleName (int lcid)
|
public string ToLocaleName (int lcid)
|
||||||
{
|
{
|
||||||
@@ -87,7 +172,6 @@ namespace DataUtils
|
|||||||
}
|
}
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert locale name -> LCID
|
// Convert locale name -> LCID
|
||||||
public int ToLCID (string localeName)
|
public int ToLCID (string localeName)
|
||||||
{
|
{
|
||||||
@@ -111,7 +195,6 @@ namespace DataUtils
|
|||||||
// fallback: invariant culture
|
// fallback: invariant culture
|
||||||
return CultureInfo.InvariantCulture.LCID;
|
return CultureInfo.InvariantCulture.LCID;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return a locale info string for given LCID and LCTYPE. LCTYPE is the Win32 LOCALE_* constant.
|
// Return a locale info string for given LCID and LCTYPE. LCTYPE is the Win32 LOCALE_* constant.
|
||||||
// Returns a string (or empty string on failure).
|
// Returns a string (or empty string on failure).
|
||||||
public object LocaleInfo (int lcid, int lctype)
|
public object LocaleInfo (int lcid, int lctype)
|
||||||
@@ -177,7 +260,6 @@ namespace DataUtils
|
|||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// LocaleInfoEx: query by locale name string and LCTYPE
|
// LocaleInfoEx: query by locale name string and LCTYPE
|
||||||
// Returns string if available; otherwise returns the integer result code (as int) if string empty (mimic C++ behavior).
|
// Returns string if available; otherwise returns the integer result code (as int) if string empty (mimic C++ behavior).
|
||||||
public object LocaleInfoEx (string localeName, int lctype)
|
public object LocaleInfoEx (string localeName, int lctype)
|
||||||
@@ -239,7 +321,6 @@ namespace DataUtils
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helpers similar to the C++: restricted (language) and elaborated (region) codes
|
// Helpers similar to the C++: restricted (language) and elaborated (region) codes
|
||||||
public string GetLocaleRestrictedCode (string localeName)
|
public string GetLocaleRestrictedCode (string localeName)
|
||||||
{
|
{
|
||||||
@@ -257,7 +338,6 @@ namespace DataUtils
|
|||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetLocaleElaboratedCode (string localeName)
|
public string GetLocaleElaboratedCode (string localeName)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty (localeName)) localeName = CurrentLocale;
|
if (string.IsNullOrEmpty (localeName)) localeName = CurrentLocale;
|
||||||
@@ -284,7 +364,6 @@ namespace DataUtils
|
|||||||
}
|
}
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
// LCID -> combined code like "en-US" (with configurable separator)
|
// LCID -> combined code like "en-US" (with configurable separator)
|
||||||
public string LcidToLocaleCode (int lcid)
|
public string LcidToLocaleCode (int lcid)
|
||||||
{
|
{
|
||||||
@@ -304,7 +383,6 @@ namespace DataUtils
|
|||||||
}
|
}
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the user default locale name
|
// Get the user default locale name
|
||||||
public string GetUserDefaultLocaleName ()
|
public string GetUserDefaultLocaleName ()
|
||||||
{
|
{
|
||||||
@@ -317,7 +395,6 @@ namespace DataUtils
|
|||||||
catch { }
|
catch { }
|
||||||
return LcidToLocaleCode (CultureInfo.CurrentCulture.LCID);
|
return LcidToLocaleCode (CultureInfo.CurrentCulture.LCID);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get system default locale name (machine)
|
// Get system default locale name (machine)
|
||||||
public string GetSystemDefaultLocaleName ()
|
public string GetSystemDefaultLocaleName ()
|
||||||
{
|
{
|
||||||
@@ -330,7 +407,6 @@ namespace DataUtils
|
|||||||
catch { }
|
catch { }
|
||||||
return LcidToLocaleCode (CultureInfo.InstalledUICulture.LCID);
|
return LcidToLocaleCode (CultureInfo.InstalledUICulture.LCID);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get computer locale code similar to C++ approach
|
// Get computer locale code similar to C++ approach
|
||||||
public string GetComputerLocaleCode ()
|
public string GetComputerLocaleCode ()
|
||||||
{
|
{
|
||||||
@@ -350,7 +426,38 @@ namespace DataUtils
|
|||||||
// fallback to invariant
|
// fallback to invariant
|
||||||
return CultureInfo.InvariantCulture.Name ?? string.Empty;
|
return CultureInfo.InvariantCulture.Name ?? string.Empty;
|
||||||
}
|
}
|
||||||
|
public _I_List RecommendLocaleNames
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var arr = new string [] {
|
||||||
|
System.Threading.Thread.CurrentThread.CurrentCulture.Name,
|
||||||
|
GetUserDefaultLocaleName (),
|
||||||
|
GetSystemDefaultLocaleName (),
|
||||||
|
LcidToLocaleCode (CurrentLCID),
|
||||||
|
GetLocaleRestrictedCode (System.Threading.Thread.CurrentThread.CurrentCulture.Name),
|
||||||
|
GetLocaleRestrictedCode (GetUserDefaultLocaleName ()),
|
||||||
|
GetLocaleRestrictedCode (GetSystemDefaultLocaleName ()),
|
||||||
|
"en-US",
|
||||||
|
"en"
|
||||||
|
};
|
||||||
|
var list = new _I_List ();
|
||||||
|
foreach (var loc in arr)
|
||||||
|
{
|
||||||
|
var lloc = loc.Trim ().ToLowerInvariant ();
|
||||||
|
var isfind = false;
|
||||||
|
foreach (var item in list)
|
||||||
|
{
|
||||||
|
var str = item as string;
|
||||||
|
if (string.IsNullOrWhiteSpace (str)) isfind = true;
|
||||||
|
isfind = str.Trim ().ToLowerInvariant () == lloc;
|
||||||
|
if (isfind) break;
|
||||||
|
}
|
||||||
|
if (!isfind) list.Add (loc);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
||||||
// Compare two locale names; returns true if equal by name or LCID
|
// Compare two locale names; returns true if equal by name or LCID
|
||||||
public bool LocaleNameCompare (string left, string right)
|
public bool LocaleNameCompare (string left, string right)
|
||||||
{
|
{
|
||||||
@@ -366,8 +473,62 @@ namespace DataUtils
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
private const int LOCALE_NAME_MAX_LENGTH = 85; // defined by Windows
|
private const int LOCALE_NAME_MAX_LENGTH = 85; // defined by Windows
|
||||||
|
public _I_Language CreateLanguage (string localeName) => new _I_Language (localeName);
|
||||||
|
public static string CurrentInputMethodLanguageTag
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
IntPtr hkl = NativeMethods.GetKeyboardLayout (0);
|
||||||
|
int lcid = hkl.ToInt32 () & 0xFFFF;
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder (85);
|
||||||
|
int result = NativeMethods.LCIDToLocaleName (lcid, sb, sb.Capacity, 0);
|
||||||
|
if (result > 0)
|
||||||
|
return sb.ToString ();
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static bool IsWellFormed (string languageTag)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty (languageTag))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var _ = new CultureInfo (languageTag);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static _I_List GetMuiCompatibleLanguageListFromLanguageTags (IEnumerable<string> languageTags)
|
||||||
|
{
|
||||||
|
var result = new List<string> ();
|
||||||
|
foreach (string tag in languageTags)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty (tag))
|
||||||
|
continue;
|
||||||
|
result.Add (tag);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var ci = new CultureInfo (tag);
|
||||||
|
string parent = ci.Parent.Name;
|
||||||
|
if (!string.IsNullOrEmpty (parent) && parent != tag && !result.Contains (parent))
|
||||||
|
result.Add (parent);
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
string neutral = Regex.Replace (tag, @"-.*$", "");
|
||||||
|
if (neutral != tag && !result.Contains (neutral))
|
||||||
|
result.Add (neutral);
|
||||||
|
}
|
||||||
|
if (!result.Contains ("neutral"))
|
||||||
|
result.Add ("neutral");
|
||||||
|
return new _I_List (result.Select (t => (object)t));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@@ -382,5 +384,236 @@ namespace DataUtils
|
|||||||
}
|
}
|
||||||
[ComVisible (true)]
|
[ComVisible (true)]
|
||||||
[ClassInterface (ClassInterfaceType.AutoDual)]
|
[ClassInterface (ClassInterfaceType.AutoDual)]
|
||||||
public class _I_Exception: IExcep
|
public class _I_Exception: Exception, IDisposable
|
||||||
|
{
|
||||||
|
private Exception bex = null;
|
||||||
|
public _I_Exception (Exception ex) { bex = ex; }
|
||||||
|
public _I_Exception (string message) { bex = new Exception (message); }
|
||||||
|
public _I_Exception (string msg, Exception innerEx) { bex = new Exception (msg, innerEx); }
|
||||||
|
public override IDictionary Data => bex.Data;
|
||||||
|
public override Exception GetBaseException () => bex.GetBaseException ();
|
||||||
|
public override void GetObjectData (SerializationInfo info, StreamingContext context) => bex.GetObjectData (info, context);
|
||||||
|
public override string HelpLink
|
||||||
|
{
|
||||||
|
get { return bex.HelpLink; }
|
||||||
|
set { bex.HelpLink = value; }
|
||||||
|
}
|
||||||
|
public override string Message => bex.Message;
|
||||||
|
public override string Source
|
||||||
|
{
|
||||||
|
get { return bex.Source; }
|
||||||
|
set { bex.Source = value; }
|
||||||
|
}
|
||||||
|
public override string StackTrace => bex.StackTrace;
|
||||||
|
public override string ToString () => bex.ToString ();
|
||||||
|
public override int GetHashCode () => bex.GetHashCode ();
|
||||||
|
public override bool Equals (object obj) => bex.Equals (obj);
|
||||||
|
public void Dispose () { bex = null; }
|
||||||
|
}
|
||||||
|
[ComVisible (true)]
|
||||||
|
[ClassInterface (ClassInterfaceType.AutoDual)]
|
||||||
|
public class _I_KeyValuePair: IDisposable
|
||||||
|
{
|
||||||
|
object key = null;
|
||||||
|
object value = null;
|
||||||
|
public _I_KeyValuePair (object k, object v)
|
||||||
|
{
|
||||||
|
key = k;
|
||||||
|
value = v;
|
||||||
|
}
|
||||||
|
public object Key { get { return key; } set { key = value; } }
|
||||||
|
public object Value { get { return value; } set { this.value = value; } }
|
||||||
|
public void Dispose ()
|
||||||
|
{
|
||||||
|
key = null;
|
||||||
|
value = null;
|
||||||
|
}
|
||||||
|
~_I_KeyValuePair ()
|
||||||
|
{
|
||||||
|
key = null;
|
||||||
|
value = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[ComVisible (true)]
|
||||||
|
[ClassInterface (ClassInterfaceType.AutoDual)]
|
||||||
|
public class _I_WwwFormUrlDecoder
|
||||||
|
{
|
||||||
|
private readonly Dictionary<string, string> _params = new Dictionary<string, string> ();
|
||||||
|
public _I_WwwFormUrlDecoder (string query)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty (query)) return;
|
||||||
|
if (query.StartsWith ("?")) query = query.Substring (1);
|
||||||
|
foreach (var pair in query.Split ('&'))
|
||||||
|
{
|
||||||
|
var kv = pair.Split ('=');
|
||||||
|
if (kv.Length == 2)
|
||||||
|
_params [Uri.UnescapeDataString (kv [0])] = Uri.UnescapeDataString (kv [1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public string GetFirstValueByName (string name)
|
||||||
|
{
|
||||||
|
string value = null;
|
||||||
|
return _params.TryGetValue (name, out value) ? value : null;
|
||||||
|
}
|
||||||
|
public int Size => _params.Count;
|
||||||
|
public _I_KeyValuePair GetAt (uint index)
|
||||||
|
{
|
||||||
|
var pair = _params.ElementAt ((int)index);
|
||||||
|
return new _I_KeyValuePair (pair.Key, pair.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[ComVisible (true)]
|
||||||
|
[ClassInterface (ClassInterfaceType.AutoDual)]
|
||||||
|
public class _I_Uri: Uri
|
||||||
|
{
|
||||||
|
public _I_Uri (string uri): base (uri) { }
|
||||||
|
public _I_Uri (string baseUri, string relativeUri) : base (new Uri (baseUri), relativeUri) { }
|
||||||
|
public string AbsoluteCanonicalUri => this.GetLeftPart (UriPartial.Authority) + this.PathAndQuery + this.Fragment;
|
||||||
|
public string DisplayIri => Uri.UnescapeDataString (this.OriginalString);
|
||||||
|
public string DisplayUri => Uri.UnescapeDataString (this.OriginalString);
|
||||||
|
public string Domain => ExtractDomain (this.Host);
|
||||||
|
public string Extension => System.IO.Path.GetExtension (this.AbsolutePath)?.TrimStart ('.') ?? "";
|
||||||
|
public string Password => ExtractPassword (this.UserInfo);
|
||||||
|
public string Path => this.AbsolutePath;
|
||||||
|
public object QueryParsed => new _I_WwwFormUrlDecoder (this.Query);
|
||||||
|
public string RawUri => this.OriginalString;
|
||||||
|
public string SchemeName => this.Scheme;
|
||||||
|
public bool Suspicious => !Uri.IsWellFormedUriString (this.OriginalString, UriKind.Absolute);
|
||||||
|
public string UserName => ExtractUserName (this.UserInfo);
|
||||||
|
public _I_Uri CombineUri (string relativeUri)
|
||||||
|
{
|
||||||
|
return new _I_Uri (this.AbsoluteUri, relativeUri);
|
||||||
|
}
|
||||||
|
public static string EscapeComponent (string component)
|
||||||
|
{
|
||||||
|
return Uri.EscapeDataString (component);
|
||||||
|
}
|
||||||
|
public static string UnescapeComponent (string component)
|
||||||
|
{
|
||||||
|
return Uri.UnescapeDataString (component);
|
||||||
|
}
|
||||||
|
private static string ExtractDomain (string host)
|
||||||
|
{
|
||||||
|
var parts = host.Split ('.');
|
||||||
|
if (parts.Length >= 2)
|
||||||
|
return string.Join (".", parts.Skip (1));
|
||||||
|
return host;
|
||||||
|
}
|
||||||
|
private static string ExtractUserName (string userInfo)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty (userInfo)) return "";
|
||||||
|
var parts = userInfo.Split (':');
|
||||||
|
return parts [0];
|
||||||
|
}
|
||||||
|
private static string ExtractPassword (string userInfo)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty (userInfo)) return "";
|
||||||
|
var parts = userInfo.Split (':');
|
||||||
|
return parts.Length > 1 ? parts [1] : "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[ComVisible (true)]
|
||||||
|
[ClassInterface (ClassInterfaceType.AutoDual)]
|
||||||
|
public class _I_Utilities
|
||||||
|
{
|
||||||
|
public _I_Uri CreateUri (string uri) => new _I_Uri (uri);
|
||||||
|
public _I_Uri CreateUri2 (string baseUri, string relaUri) => new _I_Uri (baseUri, relaUri);
|
||||||
|
public _I_Exception CreateException (string message) => new _I_Exception (message);
|
||||||
|
public _I_Exception CreateException2 (string message, _I_Exception innerEx) => new _I_Exception (message, innerEx);
|
||||||
|
public _I_Calendar CreateCalendar () => new _I_Calendar ();
|
||||||
|
public _I_Calendar CreateCalendar2 (object list) => new _I_Calendar (list);
|
||||||
|
public _I_Calendar CreateCalendar3 (object list, string arg1, string arg2) => new _I_Calendar (list, arg1, arg2);
|
||||||
|
public _I_Calendar CreateCalendar4 (object list, string arg1, string arg2, string arg3) => new _I_Calendar (list, arg1, arg2, arg3);
|
||||||
|
public _I_DateTimeFormatter CreateDateTimeFormatterFromTemplate (string formatTemplate)
|
||||||
|
{
|
||||||
|
return new _I_DateTimeFormatter (formatTemplate);
|
||||||
|
}
|
||||||
|
public _I_DateTimeFormatter CreateDateTimeFormatterFromTemplateAndLanguages (string formatTemplate, object languagesArray)
|
||||||
|
{
|
||||||
|
List<string> languages = JsArrayToStringList (languagesArray);
|
||||||
|
return new _I_DateTimeFormatter (formatTemplate, languages);
|
||||||
|
}
|
||||||
|
public _I_DateTimeFormatter CreateDateTimeFormatterFromTemplateFull (string formatTemplate, object languagesArray,
|
||||||
|
string geographicRegion, string calendar, string clock)
|
||||||
|
{
|
||||||
|
List<string> languages = JsArrayToStringList (languagesArray);
|
||||||
|
return new _I_DateTimeFormatter (formatTemplate, languages, geographicRegion, calendar, clock);
|
||||||
|
}
|
||||||
|
public _I_DateTimeFormatter CreateDateTimeFormatterFromDateEnums (int year, int month, int day, int dayOfWeek)
|
||||||
|
{
|
||||||
|
return new _I_DateTimeFormatter (
|
||||||
|
(YearFormat)year,
|
||||||
|
(MonthFormat)month,
|
||||||
|
(DayFormat)day,
|
||||||
|
(DayOfWeekFormat)dayOfWeek
|
||||||
|
);
|
||||||
|
}
|
||||||
|
public _I_DateTimeFormatter CreateDateTimeFormatterFromTimeEnums (int hour, int minute, int second)
|
||||||
|
{
|
||||||
|
return new _I_DateTimeFormatter (
|
||||||
|
(HourFormat)hour,
|
||||||
|
(MinuteFormat)minute,
|
||||||
|
(SecondFormat)second
|
||||||
|
);
|
||||||
|
}
|
||||||
|
public _I_DateTimeFormatter CreateDateTimeFormatterFromDateTimeEnums (int year, int month, int day, int dayOfWeek,
|
||||||
|
int hour, int minute, int second, object languagesArray)
|
||||||
|
{
|
||||||
|
List<string> languages = JsArrayToStringList (languagesArray);
|
||||||
|
return new _I_DateTimeFormatter (
|
||||||
|
(YearFormat)year,
|
||||||
|
(MonthFormat)month,
|
||||||
|
(DayFormat)day,
|
||||||
|
(DayOfWeekFormat)dayOfWeek,
|
||||||
|
(HourFormat)hour,
|
||||||
|
(MinuteFormat)minute,
|
||||||
|
(SecondFormat)second,
|
||||||
|
languages
|
||||||
|
);
|
||||||
|
}
|
||||||
|
public _I_DateTimeFormatter CreateDateTimeFormatterFromDateTimeEnumsFull (int year, int month, int day, int dayOfWeek,
|
||||||
|
int hour, int minute, int second, object languagesArray,
|
||||||
|
string geographicRegion, string calendar, string clock)
|
||||||
|
{
|
||||||
|
List<string> languages = JsArrayToStringList (languagesArray);
|
||||||
|
return new _I_DateTimeFormatter (
|
||||||
|
(YearFormat)year,
|
||||||
|
(MonthFormat)month,
|
||||||
|
(DayFormat)day,
|
||||||
|
(DayOfWeekFormat)dayOfWeek,
|
||||||
|
(HourFormat)hour,
|
||||||
|
(MinuteFormat)minute,
|
||||||
|
(SecondFormat)second,
|
||||||
|
languages,
|
||||||
|
geographicRegion,
|
||||||
|
calendar,
|
||||||
|
clock
|
||||||
|
);
|
||||||
|
}
|
||||||
|
private List<string> JsArrayToStringList (object jsArray)
|
||||||
|
{
|
||||||
|
var result = new List<string> ();
|
||||||
|
if (jsArray == null) return result;
|
||||||
|
|
||||||
|
Type type = jsArray.GetType ();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int length = (int)type.InvokeMember ("length", BindingFlags.GetProperty, null, jsArray, null);
|
||||||
|
for (int i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
object value = type.InvokeMember (i.ToString (), BindingFlags.GetProperty, null, jsArray, null);
|
||||||
|
if (value != null)
|
||||||
|
result.Add (value.ToString ());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// 如果无法获取 length,则假设是单个字符串
|
||||||
|
string single = jsArray.ToString ();
|
||||||
|
if (!string.IsNullOrEmpty (single))
|
||||||
|
result.Add (single);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -297,11 +297,18 @@ namespace DataUtils
|
|||||||
return new HttpResponse (res);
|
return new HttpResponse (res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public void SendAsync (string sBody, string encoding, object pfResolve)
|
public void SendAsync (string sBody, string encoding, object pfResolve, object pfReject)
|
||||||
{
|
{
|
||||||
System.Threading.ThreadPool.QueueUserWorkItem (delegate
|
System.Threading.ThreadPool.QueueUserWorkItem (delegate
|
||||||
{
|
{
|
||||||
JsUtils.Call (pfResolve, Send (sBody, encoding));
|
try
|
||||||
|
{
|
||||||
|
JsUtils.Call (pfResolve, Send (sBody, encoding));
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
JsUtils.Call (pfReject, new _I_Exception (ex));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
public void Dispose () { }
|
public void Dispose () { }
|
||||||
|
|||||||
17
LICENSE.SharpZipLib
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
Copyright © 2000-2018 SharpZipLib Contributors
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||||
|
software and associated documentation files (the "Software"), to deal in the Software
|
||||||
|
without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||||
|
publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||||
|
to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all copies or
|
||||||
|
substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||||
|
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||||
|
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||||
|
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
@@ -18,10 +18,6 @@ namespace Reader
|
|||||||
static void Main ()
|
static void Main ()
|
||||||
{
|
{
|
||||||
Directory.SetCurrentDirectory (AppDomain.CurrentDomain.BaseDirectory);
|
Directory.SetCurrentDirectory (AppDomain.CurrentDomain.BaseDirectory);
|
||||||
AppxPackage.PackageReader.AddApplicationItem ("SmallLogo");
|
|
||||||
AppxPackage.PackageReader.AddApplicationItem ("Square30x30Logo");
|
|
||||||
AppxPackage.PackageReader.AddApplicationItem ("Logo");
|
|
||||||
AppxPackage.PackageReader.AddApplicationItem ("Square44x44Logo");
|
|
||||||
DataUtils.BrowserEmulation.SetWebBrowserEmulation ();
|
DataUtils.BrowserEmulation.SetWebBrowserEmulation ();
|
||||||
Application.EnableVisualStyles ();
|
Application.EnableVisualStyles ();
|
||||||
Application.SetCompatibleTextRenderingDefault (false);
|
Application.SetCompatibleTextRenderingDefault (false);
|
||||||
|
|||||||
BIN
Reader/Project2.ico
Normal file
|
After Width: | Height: | Size: 359 KiB |
@@ -71,6 +71,9 @@
|
|||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<ApplicationIcon>Project2.ico</ApplicationIcon>
|
||||||
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\Newtonsoft.Json.13.0.3\lib\net40\Newtonsoft.Json.dll</HintPath>
|
<HintPath>..\packages\Newtonsoft.Json.13.0.3\lib\net40\Newtonsoft.Json.dll</HintPath>
|
||||||
@@ -170,6 +173,9 @@
|
|||||||
<Install>false</Install>
|
<Install>false</Install>
|
||||||
</BootstrapperPackage>
|
</BootstrapperPackage>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="Project2.ico" />
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
Other similar extension points exist, see Microsoft.Common.targets.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
|||||||
4
Reader/ReaderShell.Designer.cs
generated
@@ -31,14 +31,14 @@
|
|||||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ReaderShell));
|
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ReaderShell));
|
||||||
this.SuspendLayout();
|
this.SuspendLayout();
|
||||||
//
|
//
|
||||||
// ManagerShell
|
// ReaderShell
|
||||||
//
|
//
|
||||||
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 15F);
|
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 15F);
|
||||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||||
this.ClientSize = new System.Drawing.Size(657, 414);
|
this.ClientSize = new System.Drawing.Size(657, 414);
|
||||||
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||||
this.Location = new System.Drawing.Point(0, 0);
|
this.Location = new System.Drawing.Point(0, 0);
|
||||||
this.Name = "ManagerShell";
|
this.Name = "ReaderShell";
|
||||||
this.PageScale = 125;
|
this.PageScale = 125;
|
||||||
this.Text = "Form1";
|
this.Text = "Form1";
|
||||||
this.WindowIcon = ((System.Drawing.Icon)(resources.GetObject("$this.WindowIcon")));
|
this.WindowIcon = ((System.Drawing.Icon)(resources.GetObject("$this.WindowIcon")));
|
||||||
|
|||||||
21141
Reader/ReaderShell.resx
@@ -71,6 +71,45 @@ Original Project:
|
|||||||
License: MIT License
|
License: MIT License
|
||||||
License File: LICENSE.WinJS
|
License File: LICENSE.WinJS
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
CodeMirror
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
This product includes CodeMirror, which is licensed under the MIT License.
|
||||||
|
|
||||||
|
Original Project:
|
||||||
|
Name: CodeMirror
|
||||||
|
Author: Marijn Haverbeke and contributors
|
||||||
|
Project Homepage: https://codemirror.net/
|
||||||
|
License: MIT License
|
||||||
|
License File: LICENSE.CodeMirror
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
Json.NET (Newtonsoft.Json)
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
This product includes Json.NET (also known as Newtonsoft.Json), which is licensed under the MIT License.
|
||||||
|
|
||||||
|
Original Project:
|
||||||
|
Name: Json.NET
|
||||||
|
Author: James Newton-King
|
||||||
|
Project Homepage: https://www.newtonsoft.com/json
|
||||||
|
License: MIT License
|
||||||
|
License File: LICENSE.Newtonsoft.Json
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
SharpZipLib
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
This product includes SharpZipLib, which is licensed under the MIT License.
|
||||||
|
|
||||||
|
Original Project:
|
||||||
|
Name: SharpZipLib
|
||||||
|
Author: SharpZipLib Contributors
|
||||||
|
Project Homepage: https://icsharpcode.github.io/SharpZipLib/
|
||||||
|
License: MIT License
|
||||||
|
License File: LICENSE.SharpZipLib
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
End of notices.
|
End of notices.
|
||||||
|
|||||||
@@ -502,6 +502,7 @@ namespace Win32
|
|||||||
using namespace System;
|
using namespace System;
|
||||||
using namespace System::Runtime::InteropServices;
|
using namespace System::Runtime::InteropServices;
|
||||||
[ComVisible (true)]
|
[ComVisible (true)]
|
||||||
|
[ClassInterface (ClassInterfaceType::AutoDual)]
|
||||||
public ref class Key
|
public ref class Key
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
@@ -523,6 +524,7 @@ namespace Win32
|
|||||||
);
|
);
|
||||||
return CStringToMPString (res);
|
return CStringToMPString (res);
|
||||||
}
|
}
|
||||||
|
Object ^GetWithDefault (Object ^dflt) { return Get (dflt); }
|
||||||
Object ^Get ()
|
Object ^Get ()
|
||||||
{
|
{
|
||||||
auto res = GetPrivateProfileStringW (
|
auto res = GetPrivateProfileStringW (
|
||||||
|
|||||||
4
shared/Reader.VisualElementsManifest.xml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" GeneratedByTileIconifier="true">
|
||||||
|
<VisualElements ShowNameOnSquare150x150Logo="on" Square150x150Logo="VisualElements\MediumIconReader.png" Square70x70Logo="VisualElements\SmallIconReader.png" ForegroundText="light" BackgroundColor="#004fe2" TileIconifierColorSelection="Default" TileIconifierCreatedWithUpgrade="true" />
|
||||||
|
</Application>
|
||||||
BIN
shared/VisualElements/MediumIconReader.png
Normal file
|
After Width: | Height: | Size: 7.6 KiB |
9
shared/VisualElements/MediumIconReader_Metadata.xml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<ShortcutItemImage xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
|
<OriginalBytes>iVBORw0KGgoAAAANSUhEUgAAANIAAADSCAYAAAA/mZ5CAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAAnoSURBVHhe7d17qKR1HcdxsbKLS2WWsFBiEUoRGRUZUVhBEOZ1ddW8oKbrHyJUEkkKuRRhRekfUeHSvUgpoljX3dpatXUttYzoQkGEZkpRoNAfQSC7vX/zfGc958yZM7/nPJf5PWfeL/gyc+b53c6Z78f13OYcIUmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJG0whw4d2n7w4MHL4k1JdRGgzxKkEe7/lbo0LknDRjNvo/5GPR0PdYL1vxgZWobH/0JdFMOkYaF5r6GeiH4e4e0n43KrWPfW2GIqxvyZuiCmSGWjWT9ELQvQUlx7NIa2giW3VyvnYf8/UufFdKksNOdH1wrQUoz7XUxrhHWuiyVrY+7vqS2xlDRfNOONVFaAlmLOgVhiXZi/LZZqhHV+S50Vy0r9of+eTaUvM9cO0FLM3x1L1sK8C2KJ1rDmw9TpsYXUHfrtBVTjAC3FWnfE8lmYsrWa2Q3O85CBUiforxdTrQZoKdbdEVutiaGdhmgpzvSAgVIraKSX0VOdBWgp9vh8bLsqhvQWoqU41/0GSutC42ymh3oJ0FLsd1McYRkuzSVES3G2/QZK2eiZ3gO0FHt/OI4ywkNzD9EK9xoorYkGuT6aZa44x5XpPNwtLUSHccZ9BkpT0RyfjF6ZK85xS9wtGufca6C0KhrjE9EnvWPvndy8Kc7xWuqe6krZOOceykBpOXqj1s+wNZUCNK0RuXw1135VjSwb57zLQGkZ+qLzMK0VoJUYdxX1UEwtWp33SwuAnugkTE0ajXlXUg/GUkVr8n5qg6EfWgtTm43FOh+gHoili9bm+60BoxcahanLRmLdK6hfxFZF6/LjoIGgAdLnKE9HT2Tps3HY7nL2ur/auWx9flxUIHrgGBrg0aodpptno7DvZdSBOErR5vlxUgF48lf9/k5JjcE5LqXui6MVraSPm3rEc38CT/zfqzYouxE41yXU/jhq0dLHkZsj4+haBDzp6YVOHqEG8YKMnPNi6udVy5aJ8x0dx9Ui4Yl/jNpBD4x+rGcIOO9FVIk/evTSOKIWDQ359WiC9F/T27gZUqDeT91dnX6+OMcr4lhaRPTAxPeXBhioC6l91en7x94nxlG0qOiDqd+oHWCgzqd+Vp2+H+x3cmyvRUYj3Bw9MdXQAsVZt3Lmn44O3yH2eGtsqUVHM3w5+mKmoQWK855H7a1O3y7WfVdsI42a7fbojWwDDNS51I+r0zfHWqfF0lKFptgT/VHbAAO1pcn7mzD/3FhOegaN0fj7MQMM1DnU7ur0tWyNJaTl2gjS2AADdRZ1V3X6mQyRpmszSGMDDNSZ1K7q9KsyRFpbF0EaG2CgzqDurE5/mCHSbF0GaWyAgfog9SRnTi9w+c42KpbWRtVHkMZKDxRnO5Izfpyq9VvE07DOdyh/fGgR8ET3FqQx9iwqUJzlKM50A/W/0QEbYp0UoFNieS0CnvDegzTG3nMNFPs/n0p/O/e/1YmaYR0DtKh44ucWpDHO0Gug2GsTe15H/Wd0gIZYxwAtOhpg7kEa4yydBoq1X8QeH6GeGm3YEOt8lTJAKitIY5yp1UCx3rHU9dS/qx2aSeejDJCeQUMUF6Sx1LDcrDtQzD+OupH6R7ViM+k8lAHSJBqj2CCNpQbmJjtQjN9MpS9jH36VpCbS/pQB0nQ0SPFBGuOsN8exp2LMtdRjMaUR1jFAykOjDCZI4dNx9Am8LxfHmEYiQG+JZaXZhhYkzrszjj6Ba4/EsHVJAeKmty/DawMZYJDuiaNPWE+QmPMvA6TGNliQ0hcYPkal7xWlHzy9htrGtPRXLtL/9qUfQj2b+++j3sN9f5hU7aChNkyQpLkxSFILNlKQuHx53JX6tVqQeOxH3KTPJ4qzVpDSNSp9wcFAqV8rg8Tb6fXfnhOX03/lizIrSDEsjfsTNwZK/VjRfOn+prg0wtvPGl0sRG6QxnjsYW5qB4o5fkVP+cbNx+0vqZfEw8tw+ag0pgTpvHGsCeP3ZTVc209dGENXxfXxL/o9zhSDpHw0Tfq84jfU5nhoVTTW80YdOWfpvHGkCelaDJuKMXuoM2LKCA8fT23n8SdGgyoGSfmi+U6IN9fE2KOrHpufdN44zoR4X7Iw9p/Ut7j7veqRCQZJ+Wimk+JuFsa/MBptLlJY4igT0rUY1gaDpG7RZMdUvdY/g6QNhaY9NhquVwZJg0IjzXypXhr3uKrn+mOQNBg05B3RTDlh2hxje2GQNAg043ejkcZywvTyGNs5g6Ti0YjfjiZaaWaYGJO+F9M5g6Si0YTfjAaaJudfplfG2M4YJBWLBvxaNM8sOWF6dYzthEFSkWi+r0Tj5MoJ00kxtnUGScWh8XZE09SVE6bXxNhWGSQVhaar+y/RSjlhel2MbY1BUjFokm9UvdJYTphOjrGtMEgqAs027Uvc65UTpjfG2MYMkuaORrs9mqRtOWF6c4xtxCBprmiy70eDdCUnTKfE2HUzSJobGuyH0RxdywnT22LsuhgkzQXNtTMaoy85YXpHjK3NIKl3NNbuaIq+5YTp1Bhbi0FSr2iqvdEQ85ITpmtjbDaDpN7QUHdHM8zbmmHinCfGuGwGSZ3jyT+eZvpD1QfFWDNMMSabQVLnePLfnhqgTtF86/nXa9W11qo44gSu1WKQVCSar/bnUjG1FbFkNoOkItF8e6JxssXUVsSS2QySikTz7YrGyRZTWxFLZjNIKhLNl/4WUi0xtRWxZDaDpCLRfD+IxskWU1sRS2YzSCoSDTPtReSniqkTuLSJZr6pTlUr5mNOX0F6VSwrzUbzrXwdu5li6qq4fDX169HADvQRJNZJf6niubGsNBsNU/sX/WLqmhjWSaB6CtItsaSUh76p/WvnMTULw1sNVNdBYo3HqdfHklIemqb2i6DE1FqY1kqgugwS85+iTovlpHw0zm3RR9li6rowvVGgugoSc9MvP74hlpLqoYG+VLVSvpjaCPtexVK1A9V2kJizmzozlpDWhyb6QvRUtpjaCva/giWzA5XCElMnpGsxbCbG/oTaElOlZmimW6O3ssXUVnGOS1h6ZqBSWGLKhHQthk3FmH3UeTFFagdN9bnosWwxtROc53y2mBqoFJYYOiFdi2GruZc6O4ZK7aL5PlP1Wb6Y2inOdQ5bTQSqbpB47D7q9BgidYMm+1T0XLaY2osUAurB2Do7SNw/QL03LkndotluoNL3T7IrpvaKfd9N7aXujIcmpGvULurUeEiSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJKmuI474P9M94UzlaHRYAAAAAElFTkSuQmCC</OriginalBytes>
|
||||||
|
<OriginalPath>E:\Profiles\Bruce\Desktop\tilesassets\medium.scale-140.png</OriginalPath>
|
||||||
|
<Height>100</Height>
|
||||||
|
<Width>100</Width>
|
||||||
|
<X>0</X>
|
||||||
|
<Y>0</Y>
|
||||||
|
</ShortcutItemImage>
|
||||||
BIN
shared/VisualElements/SmallIconReader.png
Normal file
|
After Width: | Height: | Size: 5.1 KiB |
9
shared/VisualElements/SmallIconReader_Metadata.xml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<ShortcutItemImage xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
|
<OriginalBytes>iVBORw0KGgoAAAANSUhEUgAAAGIAAABiCAYAAACrpQYOAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAAYaSURBVHhe7ZxrqFRVFMclSqKIqLAyMope2DuCoiJIiAj80osoKgr6Zh/K3m8lJKwsRCw0sJBQ1Ii+BPUlIoqIiiCSoAdJZIlaiGWZlff22+f8z25mzpyZPTNn3+7ss37w59yzznrctZZ35p6Z8c4wDMMwDMMwDMMwDMMwDMMwDMMwDMMIY3Jy8na0eGJiYrZMxjC4IaIrdDoQDH8u2kL8JMcfbSFDoAV4GOB8XQqmWEIrtpBA3JCyiXWB4V0nt77g+67CumILqcANJZtQHxjczQqppN8SWrGFCAbwbD6ScIi5Q+ElBllCK41dCA2vykcwHJ3L4PxQNNQSWiFHMxZCg+vzlkeHXLcq52z0vsy1QL50F0JTF+Vt1gc5F6LPdVo7yS6Epi7POqwBhrPa5eS4QAOLRpILoaGRlsEw1qALlS7DDQg9gX6QWxTIn9ZCaGbgZdD8WtS2gE64fgx6DG1VWBTIn85CaCRoGTS7Dp2vsCDwn4UeQT8pTRTIn8ZCaGBO3lIZrm1EZ8l1KIg/ilQPcdyeZ40D+cd/IRqWh/NX0Wm6XAukPYKcD6CdeZU4kH+8F8I3fht6GZ0kUxQY0uHUuB/9kk0uAuSe4DBTJccPDcf9azpOpmhQ4zB0L9qVTa8myLfP5VaZ8YQGvlAz29CT6HhdigY13Esj96Bfs0mOADn2oFlKPb7QxIfqKYPz7WgJX54gl2hQ4xBq3Yf2ZMUHhLhdaI7SjTc0Unojx4F9J3oKRX3+cFDuYOo8iP7Iq/cH3x3oFKUYf2hmn3rrCtfdc8hSjicrJBrUmUmdh9GfWfEKuL4VjfQr9rRDvfWFxt3DwDPoVIVGg3IHUudR9Fde/T+wuZ/gC+SaDnl74TCI3WgZOl0pokG5A6jzONqv2l+js3U5LVyDw8BAfkPPo7lKFRXqrKCse2s3VCcqdDzgGx4JBvQ7Wo7OVMraIL17znA/EaWHqG7g9wYa+JMn0wL1MDIMYC9agUZ+6CCHu89wd+JBv9bi9zq6SuHjiXqpDQbi7nJXonNVIhjC3WtT7r4i6M4bv9c4DPVBuGlH3lL9MKS/0Yuo70vp+ByN3MvnOxTeE/zcQ9A8haeBeosGA9uPVqFzVLIN7ItQ0Dt8+L2JLlNoWqjHKUElPQz1Y13qCX5vo0sUlibqdUpQSY/MlTD8d9Clck8b9TwlqKQHk3vbtlJyawY0PGWopNENzahgEw8F7m3HKKikh1pL0JE6bTaakWOTzs9jOJtzU71kBVuQ2T0XvIB6vrqL20H6Mk3yUeRLKGAoZ8RYhtJ7ZPZQczWHtldWOT8W+9McF8uUJjTYtoSCGMtQao/MJaj7CrqWL9176cVNXtqL6EXdy1Baj8yhNHcRjjqXoZQemUNpziJcs27wOvXUtQyl88gcSjMWwaDdJzfc4/PmWMtQKo/MoaS/CJpcmveaE2sZSuOROZS0F8Fgl6nRNmIsQyk8MoeS7iIY6HI12ZW6l6Fwj8yhpLkIBrlSDfakzmUo1CNzKOktggG6O9hg6lqGwjwyh5LWIhjcGjU2EHUsQyEemUNJZxEMbK2aGopRlyF3j8yhpLEIBrVODY1Ej2VcLJdK5OqROZTxXgQNuI+obMx7qYcey+j5IQC5eWQOZbwXwXDuQu6TElX6R42W4Jr7OxvdPs6Yietty+D8LeyVyM0jcyhpPVl3wvD2qtESbhFyCwL/DQrtitw8MoeS/CJ2q9ESQyziJYV2RW4emUNJfhE/q9ESQyziOYV2RW4emUNJfhHb1GiJzkVwPg9z5/PEog5bJUrjkTkI6lyjsDShwe/Va4nORRRgvxIN/LeaFO6ROQjqRf+vY/8rNPitei1RtYgCrs9HH8m9LwrzyNwXatytkHShyS/Vb4l+iyjA9Wr0aRbUA7l7ZK6E+p+hm+SeNjRa+ZfIQhdRgP/1vfLJzSNzCXK4G8Y75dYMaPgT9V+CawMtooC4G1HpJ02XPTJ7iPkKLdTlZkHjbX95oBWuDbWIAuJvQd8oXeUi8NmCFsjcTBjABvRdhdbLbSTI4x6yPtCpB9t76AadGoZhGIZhGIZhGIZhGIZhGIZhGIbRcGbM+BeN+q7PrwKDyAAAAABJRU5ErkJggg==</OriginalBytes>
|
||||||
|
<OriginalPath>E:\Profiles\Bruce\Desktop\tilesassets\small.scale-140.png</OriginalPath>
|
||||||
|
<Height>50</Height>
|
||||||
|
<Width>50</Width>
|
||||||
|
<X>0</X>
|
||||||
|
<Y>0</Y>
|
||||||
|
</ShortcutItemImage>
|
||||||
@@ -34,4 +34,11 @@
|
|||||||
<scale dpi="180">splash\manager\splash.scale-180.png</scale>
|
<scale dpi="180">splash\manager\splash.scale-180.png</scale>
|
||||||
<scale dpi="default">splash\manager\splash.png</scale>
|
<scale dpi="default">splash\manager\splash.png</scale>
|
||||||
</resource>
|
</resource>
|
||||||
|
<resource id="reader">
|
||||||
|
<scale dpi="80">splash\reader\splash.scale-80.png</scale>
|
||||||
|
<scale dpi="100">splash\reader\splash.scale-100.png</scale>
|
||||||
|
<scale dpi="140">splash\reader\splash.scale-140.png</scale>
|
||||||
|
<scale dpi="180">splash\reader\splash.scale-180.png</scale>
|
||||||
|
<scale dpi="default">splash\reader\splash.png</scale>
|
||||||
|
</resource>
|
||||||
</resources>
|
</resources>
|
||||||
BIN
shared/VisualElements/splash/reader/splash.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
shared/VisualElements/splash/reader/splash.scale-100.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
shared/VisualElements/splash/reader/splash.scale-140.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
shared/VisualElements/splash/reader/splash.scale-180.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
shared/VisualElements/splash/reader/splash.scale-80.png
Normal file
|
After Width: | Height: | Size: 8.6 KiB |
@@ -32,7 +32,7 @@
|
|||||||
ForegroundText='light'
|
ForegroundText='light'
|
||||||
BackgroundColor='#004fe2'>
|
BackgroundColor='#004fe2'>
|
||||||
<DefaultTile ShowName='allLogos' />
|
<DefaultTile ShowName='allLogos' />
|
||||||
<SplashScreen Image="VisualElements\splash\manager\splash.png"
|
<SplashScreen Image="VisualElements\splash\reader\splash.png"
|
||||||
BackgroundColor="#004fe2" DarkModeBackgroundColor='#002770' />
|
BackgroundColor="#004fe2" DarkModeBackgroundColor='#002770' />
|
||||||
</VisualElements>
|
</VisualElements>
|
||||||
</Application>
|
</Application>
|
||||||
|
|||||||
@@ -35,6 +35,8 @@
|
|||||||
try {
|
try {
|
||||||
inst.sendAsync(body, encoding, function(resp) {
|
inst.sendAsync(body, encoding, function(resp) {
|
||||||
if (c) c(resp);
|
if (c) c(resp);
|
||||||
|
}, function(err) {
|
||||||
|
if (e) e(err);
|
||||||
});
|
});
|
||||||
} catch (ex) { if (e) e(ex); }
|
} catch (ex) { if (e) e(ex); }
|
||||||
});
|
});
|
||||||
|
|||||||
285
shared/html/js/polyfill-winrt.js
Normal file
@@ -0,0 +1,285 @@
|
|||||||
|
(function(global) {
|
||||||
|
function isString(obj) {
|
||||||
|
return typeof obj === "string" || obj instanceof String;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isFunction(obj) {
|
||||||
|
return typeof obj === "function";
|
||||||
|
}
|
||||||
|
|
||||||
|
function isBool(obj) {
|
||||||
|
return typeof obj === "boolean" || obj instanceof Boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isNumber(obj) {
|
||||||
|
return typeof obj === "number" || obj instanceof Number;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isDate(obj) {
|
||||||
|
return obj instanceof Date;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isDevToolsOpen() {
|
||||||
|
if (window.__IE_DEVTOOLBAR_CONSOLE_COMMAND_LINE) {
|
||||||
|
return true; // IE10 或更早版本
|
||||||
|
}
|
||||||
|
if (window.__BROWSERTOOLS_CONSOLE) {
|
||||||
|
return true; // IE11
|
||||||
|
}
|
||||||
|
if (window.__BROWSERTOOLS_DOMEXPLORER_ADDED) {
|
||||||
|
return true; // IE11
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var APIs = [
|
||||||
|
"Windows.ApplicationModel.DesignMode.designModeEnabled",
|
||||||
|
"Windows.ApplicationModel.Resources.Core.ResourceContext",
|
||||||
|
"Windows.ApplicationModel.Resources.Core.ResourceManager",
|
||||||
|
"Windows.ApplicationModel.Search.Core.SearchSuggestionManager",
|
||||||
|
"Windows.ApplicationModel.Search.SearchQueryLinguisticDetails",
|
||||||
|
"Windows.Data.Text.SemanticTextQuery",
|
||||||
|
"Windows.Foundation.Collections.CollectionChange",
|
||||||
|
"Windows.Foundation.Uri",
|
||||||
|
"Windows.Globalization.ApplicationLanguages",
|
||||||
|
"Windows.Globalization.Calendar",
|
||||||
|
"Windows.Globalization.DateTimeFormatting",
|
||||||
|
"Windows.Globalization.Language",
|
||||||
|
"Windows.Phone.UI.Input.HardwareButtons",
|
||||||
|
"Windows.Storage.ApplicationData",
|
||||||
|
"Windows.Storage.CreationCollisionOption",
|
||||||
|
"Windows.Storage.BulkAccess.FileInformationFactory",
|
||||||
|
"Windows.Storage.FileIO",
|
||||||
|
"Windows.Storage.FileProperties.ThumbnailType",
|
||||||
|
"Windows.Storage.FileProperties.ThumbnailMode",
|
||||||
|
"Windows.Storage.FileProperties.ThumbnailOptions",
|
||||||
|
"Windows.Storage.KnownFolders",
|
||||||
|
"Windows.Storage.Search.FolderDepth",
|
||||||
|
"Windows.Storage.Search.IndexerOption",
|
||||||
|
"Windows.Storage.Streams.RandomAccessStreamReference",
|
||||||
|
"Windows.UI.ApplicationSettings.SettingsEdgeLocation",
|
||||||
|
"Windows.UI.ApplicationSettings.SettingsCommand",
|
||||||
|
"Windows.UI.ApplicationSettings.SettingsPane",
|
||||||
|
"Windows.UI.Core.AnimationMetrics",
|
||||||
|
"Windows.UI.Input.EdgeGesture",
|
||||||
|
"Windows.UI.Input.EdgeGestureKind",
|
||||||
|
"Windows.UI.Input.PointerPoint",
|
||||||
|
"Windows.UI.ViewManagement.HandPreference",
|
||||||
|
"Windows.UI.ViewManagement.InputPane",
|
||||||
|
"Windows.UI.ViewManagement.UISettings",
|
||||||
|
"Windows.UI.WebUI.Core.WebUICommandBar",
|
||||||
|
"Windows.UI.WebUI.Core.WebUICommandBarBitmapIcon",
|
||||||
|
"Windows.UI.WebUI.Core.WebUICommandBarClosedDisplayMode",
|
||||||
|
"Windows.UI.WebUI.Core.WebUICommandBarIconButton",
|
||||||
|
"Windows.UI.WebUI.Core.WebUICommandBarSymbolIcon",
|
||||||
|
"Windows.UI.WebUI.WebUIApplication",
|
||||||
|
];
|
||||||
|
for (var i = 0; i < APIs.length; i++) {
|
||||||
|
var api = APIs[i];
|
||||||
|
apiNs = api.split(".");
|
||||||
|
var lastNs = global;
|
||||||
|
for (var j = 0; j < apiNs.length - 1; j++) {
|
||||||
|
var ns = apiNs[j];
|
||||||
|
if (typeof lastNs[ns] === "undefined") lastNs[ns] = {};
|
||||||
|
lastNs = lastNs[ns];
|
||||||
|
}
|
||||||
|
var leaf = apiNs[apiNs.length - 1];
|
||||||
|
if ("abcdefghijklmnopqrstuvwxyz".indexOf(leaf[0]) < 0) {
|
||||||
|
lastNs[leaf] = {};
|
||||||
|
Object.defineProperty(lastNs[leaf], "current", {
|
||||||
|
get: function() { return null; },
|
||||||
|
enumerable: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Object.defineProperty(Windows.ApplicationModel.DesignMode, "designModeEnabled", {
|
||||||
|
get: isDevToolsOpen,
|
||||||
|
enumerable: true,
|
||||||
|
});
|
||||||
|
Windows.Foundation.Collections.CollectionChange = {
|
||||||
|
reset: 0,
|
||||||
|
itemInserted: 1,
|
||||||
|
itemRemoved: 2,
|
||||||
|
itemChanged: 3
|
||||||
|
};
|
||||||
|
Windows.Foundation.Uri = function(uri) {
|
||||||
|
var inst = null;
|
||||||
|
if (arguments.length === 2) {
|
||||||
|
inst = external.Utilities.createUri2(uri, arguments[1]);
|
||||||
|
} else {
|
||||||
|
inst = external.Utilities.createUri(uri);
|
||||||
|
}
|
||||||
|
inst.jsType = this;
|
||||||
|
return inst;
|
||||||
|
};
|
||||||
|
Windows.Globalization.ApplicationLanguages = {};
|
||||||
|
Object.defineProperty(Windows.Globalization.ApplicationLanguages, "languages", {
|
||||||
|
get: function() {
|
||||||
|
try {
|
||||||
|
var list = [];
|
||||||
|
var langs = external.System.Locale.recommendLocaleNames;
|
||||||
|
langs.forEach(function(item) {
|
||||||
|
list.push(item);
|
||||||
|
});
|
||||||
|
return list;
|
||||||
|
} catch (e) {
|
||||||
|
return navigator.languages;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
});
|
||||||
|
Object.defineProperty(Windows.Globalization.ApplicationLanguages, "Languages", {
|
||||||
|
get: function() {
|
||||||
|
return Windows.Globalization.ApplicationLanguages.languages;
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
});
|
||||||
|
Windows.Globalization.LanguageLayoutDirection = {
|
||||||
|
ltr: 0,
|
||||||
|
rtl: 1,
|
||||||
|
ttbLtr: 2,
|
||||||
|
ttbRtl: 3
|
||||||
|
};
|
||||||
|
Windows.Globalization.Language = function(languageTag) {
|
||||||
|
var inst = external.System.Locale.createLanguage(languageTag);
|
||||||
|
inst.jsType = this;
|
||||||
|
return inst;
|
||||||
|
};
|
||||||
|
Object.defineProperty(Windows.Globalization.Language, "currentInputMethodLanguageTag", {
|
||||||
|
get: function() {
|
||||||
|
return external.System.Locale.currentInputMethodLanguageTag;
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
});
|
||||||
|
Windows.Globalization.Language.isWellFormed = external.System.Locale.isWellFormed;
|
||||||
|
Windows.Globalization.Language.getMuiCompatibleLanguageListFromLanguageTags = external.System.Locale.getMuiCompatibleLanguageListFromLanguageTags;
|
||||||
|
Windows.Globalization.Calendar = function(args) {
|
||||||
|
var inst = null;
|
||||||
|
if (arguments.length === 0) {
|
||||||
|
inst = external.Utilities.createCalendar(args);
|
||||||
|
} else if (arguments.length === 1) {
|
||||||
|
inst = external.Utilities.createCalendar2(args);
|
||||||
|
} else if (arguments.length === 3) {
|
||||||
|
inst = external.Utilities.createCalendar3(args, arguments[1], arguments[2], arguments[3]);
|
||||||
|
} else if (arguments.length === 4) {
|
||||||
|
inst = external.Utilities.createCalendar4(args, arguments[1], arguments[2], arguments[3], arguments[4]);
|
||||||
|
}
|
||||||
|
return inst;
|
||||||
|
};
|
||||||
|
Windows.Globalization.DateTimeFormatting = {};
|
||||||
|
Windows.Globalization.DateTimeFormatting.DayFormat = {
|
||||||
|
default: 1,
|
||||||
|
none: 0
|
||||||
|
};
|
||||||
|
Windows.Globalization.DateTimeFormatting.DayOfWeekFormat = {
|
||||||
|
none: 0,
|
||||||
|
default: 1,
|
||||||
|
abberviated: 2,
|
||||||
|
full: 3
|
||||||
|
};
|
||||||
|
Windows.Globalization.DateTimeFormatting.HourFormat = {
|
||||||
|
none: 0,
|
||||||
|
default: 1
|
||||||
|
};
|
||||||
|
Windows.Globalization.DateTimeFormatting.MinuteFormat = {
|
||||||
|
none: 0,
|
||||||
|
default: 1
|
||||||
|
};
|
||||||
|
Windows.Globalization.DateTimeFormatting.MonthFormat = {
|
||||||
|
none: 0,
|
||||||
|
default: 1,
|
||||||
|
abberviated: 2,
|
||||||
|
full: 3,
|
||||||
|
numeric: 4
|
||||||
|
};
|
||||||
|
Windows.Globalization.DateTimeFormatting.SecondFormat = {
|
||||||
|
default: 1,
|
||||||
|
none: 0
|
||||||
|
};
|
||||||
|
Windows.Globalization.DateTimeFormatting.YearFormat = {
|
||||||
|
default: 1,
|
||||||
|
none: 0,
|
||||||
|
abberviated: 2,
|
||||||
|
full: 3,
|
||||||
|
};
|
||||||
|
Windows.Globalization.DateTimeFormatting.DateTimeFormatter = function() {
|
||||||
|
var args = Array.prototype.slice.call(arguments);
|
||||||
|
var inst = null;
|
||||||
|
if (args.length === 1) inst = external.Utilities.createDateTimeFormatterFromTemplate(args[0]);
|
||||||
|
else if (args.length === 2) inst = external.Utilities.CreateDateTimeFormatterFromTemplateAndLanguages(args[0], args[1]);
|
||||||
|
else if (args.length === 3) inst = external.Utilities.CreateDateTimeFormatterFromTimeEnums(args[0], args[1], args[2]);
|
||||||
|
else if (args.length === 4) inst = external.Utilities.CreateDateTimeFormatterFromDateEnums(args[0], args[1], args[2], args[3]);
|
||||||
|
else if (args.length === 5) inst = external.Utilities.CreateDateTimeFormatterFromTemplateFull(args[0], args[1], args[2], args[3], args[4]);
|
||||||
|
else if (args.length === 8) inst = external.Utilities.CreateDateTimeFormatterFromDateTimeEnums(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]);
|
||||||
|
else if (args.length === 11) inst = external.Utilities.CreateDateTimeFormatterFromDateTimeEnumsFull(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9], args[10]);
|
||||||
|
return inst;
|
||||||
|
};
|
||||||
|
Windows.Storage.CreationCollisionOption = {
|
||||||
|
generateUniqueName: 0,
|
||||||
|
replaceExisting: 1,
|
||||||
|
failIfExists: 2,
|
||||||
|
openIfExists: 3
|
||||||
|
};
|
||||||
|
Windows.Storage.FileProperties = {
|
||||||
|
ThumbnailType: {
|
||||||
|
image: 0,
|
||||||
|
icon: 1
|
||||||
|
},
|
||||||
|
ThumbnailMode: {
|
||||||
|
pictureView: 0,
|
||||||
|
videosView: 1,
|
||||||
|
musicView: 2,
|
||||||
|
documentsView: 3,
|
||||||
|
listView: 4,
|
||||||
|
singleItem: 5
|
||||||
|
},
|
||||||
|
ThumbnailType: {
|
||||||
|
image: 0,
|
||||||
|
icon: 1
|
||||||
|
},
|
||||||
|
VideoOrientation: {
|
||||||
|
normal: 0,
|
||||||
|
rotate90: 90,
|
||||||
|
rotate180: 180,
|
||||||
|
rotate270: 270
|
||||||
|
},
|
||||||
|
PhotoOrientation: {
|
||||||
|
unspecified: 0,
|
||||||
|
normal: 1,
|
||||||
|
flipHorizontal: 2,
|
||||||
|
rotate180: 3,
|
||||||
|
flipVertical: 4,
|
||||||
|
transpose: 5,
|
||||||
|
rotate270: 6,
|
||||||
|
transverse: 7,
|
||||||
|
rotate90: 8
|
||||||
|
},
|
||||||
|
};
|
||||||
|
Windows.Storage.Search = {
|
||||||
|
FolderDepth: function() {},
|
||||||
|
IndexerOption: function() {}
|
||||||
|
};
|
||||||
|
Windows.Storage.Search.FolderDepth.deep = 1;
|
||||||
|
Windows.Storage.Search.FolderDepth.shallow = 0;
|
||||||
|
Windows.Storage.Search.IndexerOption.useIndexerWhenAvailable = 0;
|
||||||
|
Windows.Storage.Search.IndexerOption.onlyUseIndexer = 1;
|
||||||
|
Windows.Storage.Search.IndexerOption.doNotUseIndexer = 2;
|
||||||
|
Windows.Storage.Search.IndexerOption.onlyUseIndexerAndOptimizeForIndexedProperties = 3;
|
||||||
|
Windows.UI.ApplicationSettings.SettingsEdgeLocation = {
|
||||||
|
right: 0,
|
||||||
|
left: 1
|
||||||
|
};
|
||||||
|
Windows.UI.Input.EdgeGestureKind = {
|
||||||
|
touch: 0,
|
||||||
|
keyboard: 1,
|
||||||
|
mouse: 2
|
||||||
|
};
|
||||||
|
Windows.UI.ViewManagement.HandPreference = {
|
||||||
|
leftHanded: 0,
|
||||||
|
rightHanded: 1
|
||||||
|
};
|
||||||
|
Windows.UI.WebUI.Core.WebUICommandBarClosedDisplayMode = {
|
||||||
|
default: 0,
|
||||||
|
minimal: 1,
|
||||||
|
compact: 2
|
||||||
|
};
|
||||||
|
})(this);
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
var strres = external.StringResources;
|
var strres = external.StringResources;
|
||||||
var conf = external.Config.current;
|
var conf = external.Config.current;
|
||||||
var set = conf.getSection("Settings");
|
var set = conf.getSection("Settings");
|
||||||
|
var metadata = conf.getSection("PackageReader:AppMetadatas");
|
||||||
|
|
||||||
function createLocalizedCompare(locale) {
|
function createLocalizedCompare(locale) {
|
||||||
return function(a, b) {
|
return function(a, b) {
|
||||||
@@ -15,6 +16,26 @@
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
var pagemgr = new PageManager();
|
var pagemgr = new PageManager();
|
||||||
|
(function() {
|
||||||
|
var nstrutil = Bridge.NString;
|
||||||
|
var boolTrue = ["true", "1", "yes", "on", "y", "t", "zhen", "真"];
|
||||||
|
var boolFalse = ["false", "0", "no", "off", "n", "f", "jia", "假"];
|
||||||
|
global.parseBool = function(str) {
|
||||||
|
if (typeof str === "boolean") return str;
|
||||||
|
str = "" + str;
|
||||||
|
for (var i = 0; i < boolTrue.length; i++) {
|
||||||
|
if (nstrutil.equals(str, boolTrue[i])) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (var i = 0; i < boolFalse.length; i++) {
|
||||||
|
if (nstrutil.equals(str, boolFalse[i])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
})();
|
||||||
OnLoad.add(function() {
|
OnLoad.add(function() {
|
||||||
var mgr = Package.manager;
|
var mgr = Package.manager;
|
||||||
var nstr = Bridge.NString;
|
var nstr = Bridge.NString;
|
||||||
@@ -24,8 +45,59 @@
|
|||||||
return Bridge.String.tolower(Bridge.String.trim(item.Identity.FullName));
|
return Bridge.String.tolower(Bridge.String.trim(item.Identity.FullName));
|
||||||
});
|
});
|
||||||
var themeColor = Bridge.UI.themeColor;
|
var themeColor = Bridge.UI.themeColor;
|
||||||
|
var reader = Package.reader;
|
||||||
|
var appitems = [
|
||||||
|
"Id",
|
||||||
|
"StartPage",
|
||||||
|
"EntryPoint",
|
||||||
|
"Executable",
|
||||||
|
"BackgroundColor",
|
||||||
|
"DisplayName",
|
||||||
|
"Description",
|
||||||
|
"ShortName",
|
||||||
|
"ForegroundText",
|
||||||
|
"SmallLogo",
|
||||||
|
"Square30x30Logo",
|
||||||
|
"Square44x44Logo",
|
||||||
|
"Square70x70Logo",
|
||||||
|
"Square71x71Logo",
|
||||||
|
"Logo",
|
||||||
|
"Square150x150Logo",
|
||||||
|
"WideLogo",
|
||||||
|
"Wide310x150Logo",
|
||||||
|
"Square310x310Logo",
|
||||||
|
"Tall150x310Logo",
|
||||||
|
"LockScreenLogo",
|
||||||
|
"LockScreenNotification",
|
||||||
|
"DefaultSize",
|
||||||
|
"AppListEntry",
|
||||||
|
"VisualGroup",
|
||||||
|
"MinWidth",
|
||||||
|
];
|
||||||
|
var defaultItems = [
|
||||||
|
"Id",
|
||||||
|
"DisplayName",
|
||||||
|
"BackgroundColor",
|
||||||
|
"ForegroundText",
|
||||||
|
"ShortName",
|
||||||
|
"Square44x44Logo",
|
||||||
|
"SmallLogo"
|
||||||
|
];
|
||||||
|
var metaitemlist = [];
|
||||||
|
for (var i = 0; i < appitems.length; i++) {
|
||||||
|
var item = appitems[i];
|
||||||
|
var isenable = metadata.getKey(item).value;
|
||||||
|
if (isenable === null || isenable === void 0 || isenable === "") {
|
||||||
|
isenable = defaultItems.indexOf(item) >= 0;
|
||||||
|
}
|
||||||
|
if (parseBool(isenable) == true) {
|
||||||
|
metaitemlist.push(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reader.updateApplicationReadItems(metaitemlist);
|
||||||
pagemgr.register("reader", document.getElementById("tag-reader"), document.getElementById("page-reader"));
|
pagemgr.register("reader", document.getElementById("tag-reader"), document.getElementById("page-reader"));
|
||||||
pagemgr.register("acquire", document.getElementById("tag-acquire"), document.getElementById("page-acquire"));
|
pagemgr.register("acquire", document.getElementById("tag-acquire"), document.getElementById("page-acquire"));
|
||||||
|
pagemgr.register("search", document.getElementById("tag-search"), document.getElementById("page-search"));
|
||||||
pagemgr.go("reader");
|
pagemgr.go("reader");
|
||||||
});
|
});
|
||||||
})(this);
|
})(this);
|
||||||
@@ -57,6 +57,7 @@
|
|||||||
try {
|
try {
|
||||||
var obj = nodes[i].getAttribute('data-res-resxml');
|
var obj = nodes[i].getAttribute('data-res-resxml');
|
||||||
var strres = external.StringResources;
|
var strres = external.StringResources;
|
||||||
|
if (!strres) strres = Bridge.External.WinJsStringRes;
|
||||||
if (strres) {
|
if (strres) {
|
||||||
try {
|
try {
|
||||||
nodes[i].textContent = strres.get(obj);
|
nodes[i].textContent = strres.get(obj);
|
||||||
|
|||||||
@@ -8,10 +8,13 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<script type="text/javascript" src="js/module.js"></script>
|
<script type="text/javascript" src="js/module.js"></script>
|
||||||
<script type="text/javascript" src="js/polyfill-ie.js"></script>
|
<script type="text/javascript" src="js/polyfill-ie.js"></script>
|
||||||
|
<script type="text/javascript" src="js/polyfill-winrt.js"></script>
|
||||||
<link rel="stylesheet" href="libs/winjs/1.0/css/ui-light.css" id="winjs-style-1">
|
<link rel="stylesheet" href="libs/winjs/1.0/css/ui-light.css" id="winjs-style-1">
|
||||||
<link rel="stylesheet" href="libs/winjs/2.0/css/ui-light.css" id="winjs-style">
|
<link rel="stylesheet" href="libs/winjs/2.0/css/ui-light.css" id="winjs-style">
|
||||||
<script type="text/javascript" src="libs/winjs/1.0/js/base.js"></script>
|
<script type="text/javascript" src="libs/winjs/1.0/js/base.js"></script>
|
||||||
<script type="text/javascript" src="libs/winjs/1.0/js/ui.js"></script>
|
<script type="text/javascript" src="libs/winjs/1.0/js/ui.js"></script>
|
||||||
|
<script type="text/javascript" src="libs/winjs/1.0/js/en-us/base.strings.js"></script>
|
||||||
|
<script type="text/javascript" src="libs/winjs/1.0/js/en-us/ui.strings.js"></script>
|
||||||
<script type="text/javascript" src="js/color.js"></script>
|
<script type="text/javascript" src="js/color.js"></script>
|
||||||
<script type="text/javascript" src="js/promise.js"></script>
|
<script type="text/javascript" src="js/promise.js"></script>
|
||||||
<script type="text/javascript" src="js/bridge.js"></script>
|
<script type="text/javascript" src="js/bridge.js"></script>
|
||||||
@@ -60,13 +63,13 @@
|
|||||||
<div class="page full guide fold">
|
<div class="page full guide fold">
|
||||||
<main class="main">
|
<main class="main">
|
||||||
<div id="page-reader" style="display: none;" class="ispage padding">
|
<div id="page-reader" style="display: none;" class="ispage padding">
|
||||||
<h2>读取</h2>
|
<h2 data-res-resxml="READER_READER_TITLE"></h2>
|
||||||
<p>请选择一个包,获取其信息。</p>
|
<p data-res-resxml="READER_READER_DESC"></p>
|
||||||
<div>
|
<div>
|
||||||
<label for="read-pkgpath">文件路径</label>
|
<label for="read-pkgpath" data-res-resxml="READER_READER_FILEPATH"></label>
|
||||||
<div class="itemrow">
|
<div class="itemrow">
|
||||||
<input type="text" id="read-pkgpath" style="margin-right: 10px;">
|
<input type="text" id="read-pkgpath" style="margin-right: 10px;">
|
||||||
<button id="read-browse">浏览</button>
|
<button id="read-browse" data-res-resxml="READER_READER_BROWSER"></button>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
(function() {
|
(function() {
|
||||||
@@ -76,7 +79,9 @@
|
|||||||
readBrowse.onclick = function() {
|
readBrowse.onclick = function() {
|
||||||
var explorer = external.Storage.Explorer;
|
var explorer = external.Storage.Explorer;
|
||||||
explorer.file(
|
explorer.file(
|
||||||
"{appxpkg}|*.appx;*.appxbundle;*.msix;*.msixbundle|{allfiles}|*.*",
|
"{appxpkg}|*.appx;*.appxbundle;*.msix;*.msixbundle|{allfiles}|*.*"
|
||||||
|
.replace("{appxpkg}", stringRes("READER_READER_APPXFILE"))
|
||||||
|
.replace("{allfiles}", stringRes("READER_READER_ALLFILES")),
|
||||||
lastDir,
|
lastDir,
|
||||||
function(result) {
|
function(result) {
|
||||||
if (!result) return;
|
if (!result) return;
|
||||||
@@ -90,20 +95,20 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="itemrow">
|
<div class="itemrow">
|
||||||
<input type="checkbox" id="read-usepri" style="margin-left: 0;">
|
<input type="checkbox" id="read-usepri" style="margin-left: 0;">
|
||||||
<label for="read-usepri">需要解析 PRI 资源文件</label>
|
<label for="read-usepri" data-res-resxml="READER_READER_USEPRI"></label>
|
||||||
</div>
|
</div>
|
||||||
<style>
|
<style>
|
||||||
.part-read-button {
|
.part-read-button {
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<button id="read-btn" class="part-read-button">读取</button>
|
<button id="read-btn" class="part-read-button" data-res-resxml="READER_READER_READ"></button>
|
||||||
<button id="read-result-save" class="part-read-button">将读取结果保存为文件</button>
|
<button id="read-result-save" class="part-read-button" data-res-resxml="READER_READER_SAVEFILE"></button>
|
||||||
<button id="read-result-xml" class="part-read-button">保存为 XML 文件</button>
|
<button id="read-result-xml" class="part-read-button" data-res-resxml="READER_READER_SAVEXML"></button>
|
||||||
<button id="read-result-json" class="part-read-button">保存为 JSON 文件</button>
|
<button id="read-result-json" class="part-read-button" data-res-resxml="READER_READER_SAVEJSON"></button>
|
||||||
<br>
|
<br>
|
||||||
<progress id="read-loading" style="display: none;"></progress>
|
<progress id="read-loading" style="display: none;"></progress>
|
||||||
<p style="margin-bottom: 2px; margin-top: 5px;">读取结果:</p>
|
<p style="margin-bottom: 2px; margin-top: 5px;" data-res-resxml="READER_READER_RESULT"></p>
|
||||||
<iframe id="read-result" width="100%" frameborder="0" src="report.html"></iframe>
|
<iframe id="read-result" width="100%" frameborder="0" src="report.html"></iframe>
|
||||||
<script>
|
<script>
|
||||||
(function() {
|
(function() {
|
||||||
@@ -112,7 +117,7 @@
|
|||||||
|
|
||||||
function readResultResizeEvent(e) {
|
function readResultResizeEvent(e) {
|
||||||
var parent = readResult.parentElement.parentElement;
|
var parent = readResult.parentElement.parentElement;
|
||||||
var newHeight = parent.getBoundingClientRect().height - readResult.getBoundingClientRect().top - 24;
|
var newHeight = parent.getBoundingClientRect().height - readResult.getBoundingClientRect().top - 60;
|
||||||
//console.log(e, parent.getBoundingClientRect().height, readResult.getBoundingClientRect().top, newHeight);
|
//console.log(e, parent.getBoundingClientRect().height, readResult.getBoundingClientRect().top, newHeight);
|
||||||
readResult.style.height = parseInt(newHeight) + "px";
|
readResult.style.height = parseInt(newHeight) + "px";
|
||||||
}
|
}
|
||||||
@@ -123,6 +128,8 @@
|
|||||||
</script>
|
</script>
|
||||||
<script>
|
<script>
|
||||||
(function(global) {
|
(function(global) {
|
||||||
|
var conf = external.Config.current;
|
||||||
|
var set = conf.getSection("Settings");
|
||||||
var readBtn = document.getElementById("read-btn");
|
var readBtn = document.getElementById("read-btn");
|
||||||
var readResult = document.getElementById("read-result");
|
var readResult = document.getElementById("read-result");
|
||||||
var readPkgpath = document.getElementById("read-pkgpath");
|
var readPkgpath = document.getElementById("read-pkgpath");
|
||||||
@@ -132,6 +139,7 @@
|
|||||||
var readSave = document.getElementById("read-result-save");
|
var readSave = document.getElementById("read-result-save");
|
||||||
var readToXml = document.getElementById("read-result-xml");
|
var readToXml = document.getElementById("read-result-xml");
|
||||||
var readToJson = document.getElementById("read-result-json");
|
var readToJson = document.getElementById("read-result-json");
|
||||||
|
readUsepri.checked = set.getKey("PackageReader:DefaultParsingPriFile").readBool();
|
||||||
readResult.style.display = "none";
|
readResult.style.display = "none";
|
||||||
readBtn.onclick = function() {
|
readBtn.onclick = function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
@@ -160,7 +168,7 @@
|
|||||||
onCompleted();
|
onCompleted();
|
||||||
readResult.contentWindow.setReport({
|
readResult.contentWindow.setReport({
|
||||||
status: false,
|
status: false,
|
||||||
message: "请选择一个有效文件"
|
message: stringRes("READER_READER_PLEASESELECT")
|
||||||
});
|
});
|
||||||
self.disabled = false;
|
self.disabled = false;
|
||||||
return;
|
return;
|
||||||
@@ -187,7 +195,7 @@
|
|||||||
progress.classList.add("win-ring");
|
progress.classList.add("win-ring");
|
||||||
progress.style.color = "white";
|
progress.style.color = "white";
|
||||||
var span = document.createElement("span");
|
var span = document.createElement("span");
|
||||||
span.textContent = "正在保存文件";
|
span.textContent = stringRes("READER_READER_SAVINGHTML");
|
||||||
progress.style.marginRight = "10px";
|
progress.style.marginRight = "10px";
|
||||||
cont.setAttribute("style", "display: flex; flex-direction: row; align-items: center; display: -ms-flexbox; -ms-flex-direction: row; -ms-align-items: center;")
|
cont.setAttribute("style", "display: flex; flex-direction: row; align-items: center; display: -ms-flexbox; -ms-flex-direction: row; -ms-align-items: center;")
|
||||||
cont.appendChild(progress);
|
cont.appendChild(progress);
|
||||||
@@ -199,7 +207,7 @@
|
|||||||
return dlg.show().then(function(id) {
|
return dlg.show().then(function(id) {
|
||||||
return new Promise(function(c, e) {
|
return new Promise(function(c, e) {
|
||||||
external.Storage.save(
|
external.Storage.save(
|
||||||
"{htmlfile}|*.html;*.htm",
|
"{htmlfile}|*.html;*.htm".replace("{htmlfile}", stringRes("READER_READER_HTMLFILE")),
|
||||||
lastDir,
|
lastDir,
|
||||||
"report-" + new Date().getTime(),
|
"report-" + new Date().getTime(),
|
||||||
c
|
c
|
||||||
@@ -216,7 +224,7 @@
|
|||||||
});
|
});
|
||||||
}).then(null, function(err) {
|
}).then(null, function(err) {
|
||||||
dlg.hide().then(function() {
|
dlg.hide().then(function() {
|
||||||
dlg.title = "保存时发生问题";
|
dlg.title = stringRes("READER_READER_SAVEERR");
|
||||||
dlg.content = err.message || err;
|
dlg.content = err.message || err;
|
||||||
dlg.commands.push(new WinJS.UI.ContentDialogCommand(
|
dlg.commands.push(new WinJS.UI.ContentDialogCommand(
|
||||||
getPublicRes(800)
|
getPublicRes(800)
|
||||||
@@ -238,7 +246,7 @@
|
|||||||
progress.classList.add("win-ring");
|
progress.classList.add("win-ring");
|
||||||
progress.style.color = "white";
|
progress.style.color = "white";
|
||||||
var span = document.createElement("span");
|
var span = document.createElement("span");
|
||||||
span.textContent = "正在生成 JSON 文件,请稍候... \n这可能需要比较长的时间。";
|
span.textContent = stringRes("READER_READER_SAVEINGJSON");
|
||||||
progress.style.marginRight = "10px";
|
progress.style.marginRight = "10px";
|
||||||
cont.setAttribute("style", "display: flex; flex-direction: row; align-items: center; display: -ms-flexbox; -ms-flex-direction: row; -ms-align-items: center;")
|
cont.setAttribute("style", "display: flex; flex-direction: row; align-items: center; display: -ms-flexbox; -ms-flex-direction: row; -ms-align-items: center;")
|
||||||
cont.appendChild(progress);
|
cont.appendChild(progress);
|
||||||
@@ -250,7 +258,7 @@
|
|||||||
return dlg.show().then(function(id) {
|
return dlg.show().then(function(id) {
|
||||||
return new Promise(function(c, e) {
|
return new Promise(function(c, e) {
|
||||||
external.Storage.save(
|
external.Storage.save(
|
||||||
"{jsonzipfile}|*.zip",
|
"{jsonzipfile}|*.zip".replace("{jsonzipfile}", stringRes("READER_READER_JSONFILE")),
|
||||||
lastDir,
|
lastDir,
|
||||||
"report-" + new Date().getTime(),
|
"report-" + new Date().getTime(),
|
||||||
c
|
c
|
||||||
@@ -259,7 +267,7 @@
|
|||||||
}).then(function(filepath) {
|
}).then(function(filepath) {
|
||||||
return new Promise(function(c, e) {
|
return new Promise(function(c, e) {
|
||||||
if (!readPkgpath.value) {
|
if (!readPkgpath.value) {
|
||||||
e(new Error("请选择一个有效文件"));
|
e(new Error(stringRes("READER_READER_PLEASESELECT")));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
@@ -284,7 +292,7 @@
|
|||||||
});
|
});
|
||||||
}).then(null, function(err) {
|
}).then(null, function(err) {
|
||||||
dlg.hide().then(function() {
|
dlg.hide().then(function() {
|
||||||
dlg.title = "保存时发生问题";
|
dlg.title = stringRes("READER_READER_SAVEERR");
|
||||||
dlg.content = err.message || err;
|
dlg.content = err.message || err;
|
||||||
dlg.commands.push(new WinJS.UI.ContentDialogCommand(
|
dlg.commands.push(new WinJS.UI.ContentDialogCommand(
|
||||||
getPublicRes(800)
|
getPublicRes(800)
|
||||||
@@ -307,7 +315,7 @@
|
|||||||
progress.classList.add("win-ring");
|
progress.classList.add("win-ring");
|
||||||
progress.style.color = "white";
|
progress.style.color = "white";
|
||||||
var span = document.createElement("span");
|
var span = document.createElement("span");
|
||||||
span.textContent = "正在生成 XML 文件,请稍候... \n这可能需要比较长的时间。";
|
span.textContent = stringRes("READER_READER_SAVEINGXML");
|
||||||
progress.style.marginRight = "10px";
|
progress.style.marginRight = "10px";
|
||||||
cont.setAttribute("style", "display: flex; flex-direction: row; align-items: center; display: -ms-flexbox; -ms-flex-direction: row; -ms-align-items: center;")
|
cont.setAttribute("style", "display: flex; flex-direction: row; align-items: center; display: -ms-flexbox; -ms-flex-direction: row; -ms-align-items: center;")
|
||||||
cont.appendChild(progress);
|
cont.appendChild(progress);
|
||||||
@@ -319,7 +327,7 @@
|
|||||||
return dlg.show().then(function(id) {
|
return dlg.show().then(function(id) {
|
||||||
return new Promise(function(c, e) {
|
return new Promise(function(c, e) {
|
||||||
external.Storage.save(
|
external.Storage.save(
|
||||||
"{xmlzipfile}|*.zip",
|
"{xmlzipfile}|*.zip".replace("{xmlzipfile}", stringRes("READER_READER_XMLFILE")),
|
||||||
lastDir,
|
lastDir,
|
||||||
"report-" + new Date().getTime(),
|
"report-" + new Date().getTime(),
|
||||||
c
|
c
|
||||||
@@ -329,7 +337,7 @@
|
|||||||
return new Promise(function(c, e) {
|
return new Promise(function(c, e) {
|
||||||
try {
|
try {
|
||||||
if (!readPkgpath.value) {
|
if (!readPkgpath.value) {
|
||||||
e(new Error("请选择一个有效文件"));
|
e(new Error(stringRes("READER_READER_PLEASESELECT")));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var pkg = Package.reader.package(readPkgpath.value);
|
var pkg = Package.reader.package(readPkgpath.value);
|
||||||
@@ -353,7 +361,7 @@
|
|||||||
});
|
});
|
||||||
}).then(null, function(err) {
|
}).then(null, function(err) {
|
||||||
dlg.hide().then(function() {
|
dlg.hide().then(function() {
|
||||||
dlg.title = "保存时发生问题";
|
dlg.title = stringRes("READER_READER_SAVEERR");
|
||||||
dlg.content = err.message || err;
|
dlg.content = err.message || err;
|
||||||
dlg.commands.push(new WinJS.UI.ContentDialogCommand(
|
dlg.commands.push(new WinJS.UI.ContentDialogCommand(
|
||||||
getPublicRes(800)
|
getPublicRes(800)
|
||||||
@@ -369,35 +377,35 @@
|
|||||||
</script>
|
</script>
|
||||||
</div>
|
</div>
|
||||||
<div id="page-acquire" style="display: none;" class="ispage padding">
|
<div id="page-acquire" style="display: none;" class="ispage padding">
|
||||||
<h2>获取</h2>
|
<h2 data-res-resxml="READER_ACQUIRE_TITLE"></h2>
|
||||||
<div id="acquire-forbidden" style="width: 100%;">
|
<div id="acquire-forbidden" style="width: 100%;">
|
||||||
<p>由于来自 store.rg-adguard.net 的限制,现在暂时无法实现对包的获取。请自行打开下面 URL 进行访问。</p>
|
<p data-res-resxml="READER_ACQUIRE_PROHIBIT"></p>
|
||||||
<a onclick="external.Process.open ('https://store.rg-adguard.net')">store.rg-adguard.net</a>
|
<a onclick="external.Process.open ('https://store.rg-adguard.net')">store.rg-adguard.net</a>
|
||||||
</div>
|
</div>
|
||||||
<div id="acquire-enable" style="width: 100%;">
|
<div id="acquire-enable" style="width: 100%;">
|
||||||
<p>请在下面的输入框中输入要查询的内容,设置好参数后将进行查询。</p>
|
<p data-res-resxml="READER_ACQUIRE_DESC"></p>
|
||||||
<div>
|
<div>
|
||||||
<div>
|
<div>
|
||||||
<input type="text" id="acquire-input">
|
<input type="text" id="acquire-input">
|
||||||
<select id="acquire-valuetype" name="type">
|
<select id="acquire-valuetype" name="type" value="url">
|
||||||
<option value="url">分享链接</option>
|
<option value="url" data-res-resxml="READER_ACQUIRE_SHAREDURL"></option>
|
||||||
<option value="ProductId">产品 ID</option>
|
<option value="ProductId" data-res-resxml="READER_ACQUIRE_PRODUCTID"></option>
|
||||||
<option value="PackageFamilyName">包系列名</option>
|
<option value="PackageFamilyName" data-res-resxml="READER_ACQUIRE_PFN"></option>
|
||||||
<option value="CategoryId">类别 ID</option>
|
<option value="CategoryId" data-res-resxml="READER_ACQUIRE_CATEGORYID"></option>
|
||||||
</select>
|
</select>
|
||||||
<select id="acquire-channel" name="ring">
|
<select id="acquire-channel" name="ring" value="RP">
|
||||||
<option title="Windows Insider Fast" value="WIF">快速</option>
|
<option title="Windows Insider Fast" value="WIF" data-res-resxml="READER_ACQUIRE_WIF"></option>
|
||||||
<option title="Windows Insider Slow" value="WIS">慢速</option>
|
<option title="Windows Insider Slow" value="WIS" data-res-resxml="READER_ACQUIRE_WIS"></option>
|
||||||
<option title="Release Preview" value="RP" selected>发布预览</option>
|
<option title="Release Preview" value="RP" data-res-resxml="READER_ACQUIRE_RP"></option>
|
||||||
<option title="Default OS" value="Retail">正式</option>
|
<option title="Default OS" value="Retail" data-res-resxml="READER_ACQUIRE_RETAIL"></option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="itemrow">
|
<div class="itemrow">
|
||||||
<input type="checkbox" id="acquire-smartquery" style="margin-left: 0px;">
|
<input type="checkbox" id="acquire-smartquery" style="margin-left: 0px;">
|
||||||
<label for="acquire-smartquery">自动查询</label>
|
<label for="acquire-smartquery" data-res-resxml="READER_ACQUIRE_SMARTQUERY"></label>
|
||||||
</div>
|
</div>
|
||||||
<button id="acquire-query">查询</button>
|
<button id="acquire-query" data-res-resxml="READER_ACQUIRE_QUERY"></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<style>
|
<style>
|
||||||
@@ -492,17 +500,19 @@
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<div id="acquire-template" class="acquire-item" style="display: none;">
|
<div id="acquire-template" class="acquire-item" style="display: none;">
|
||||||
<div id="name" class="top" title="Identity Name">Identity Name</div>
|
<div id="name" class="top" title="Identity Name"></div>
|
||||||
<div class="medium">
|
<div class="medium">
|
||||||
<div id="ext" title="File Type">Appx</div>
|
<div id="ext" title="File Type"></div>
|
||||||
<div id="version" title="Version">1.0.0.0</div>
|
<div id="version" title="Version"></div>
|
||||||
<div id="architecture" title="Processor Architecture">neutral</div>
|
<div id="architecture" title="Processor Architecture"></div>
|
||||||
<div id="publisherId" title="Identity Publisher Id"></div>
|
<div id="publisherId" title="Identity Publisher Id"></div>
|
||||||
<div id="size" title="File Size"></div>
|
<div id="size" title="File Size"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="bottom">
|
<div class="bottom">
|
||||||
<div id="hashpart"><span>SHA-1: </span><span id="hash"></span></div>
|
<div id="hashpart"><span>SHA-1: </span><span id="hash"></span></div>
|
||||||
<div><a download id="download" href="">点击下载</a></div>
|
<div>
|
||||||
|
<a download id="download" href="" data-res-resxml="READER_ACQUIRE_CLICKDOWNLOAD"></a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="acquire-loading">
|
<div id="acquire-loading">
|
||||||
@@ -514,17 +524,17 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="acquire-result" style="width: 100%;">
|
<div id="acquire-result" style="width: 100%;">
|
||||||
<p style="font-weight: normal;" title="Category ID"><span>类别 ID</span>: <span id="acquire-categoryid" style="user-select: text; -ms-user-select: element;"></span></p>
|
<p style="font-weight: normal;" title="Category ID"><span data-res-resxml="READER_ACQUIRE_CATEGORYID"></span>: <span id="acquire-categoryid" style="user-select: text; -ms-user-select: element;"></span></p>
|
||||||
<h3>以下可能为检索到的应用</h3>
|
<h3 data-res-resxml="READER_ACQUIRE_RESULTAPPS"></h3>
|
||||||
<div id="acquire-list-app" style="width: 100%;"></div>
|
<div id="acquire-list-app" style="width: 100%;"></div>
|
||||||
<h3>以下可能为检索到的依赖项</h3>
|
<h3 data-res-resxml="READER_ACQUIRE_RESULTDEPS"></h3>
|
||||||
<div id="acquire-list-dep" style="width: 100%;"></div>
|
<div id="acquire-list-dep" style="width: 100%;"></div>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
(function(global) {
|
(function(global) {
|
||||||
var conf = external.Config.current;
|
var conf = external.Config.current;
|
||||||
var set = conf.getSection("Settings");
|
var set = conf.getSection("Settings");
|
||||||
var isForbidden = !set.getKey("EnableAcquire").readBool(false);
|
var isForbidden = !set.getKey("PackageReader:EnableAcquire").readBool(false);
|
||||||
var acquireInput = document.getElementById("acquire-input");
|
var acquireInput = document.getElementById("acquire-input");
|
||||||
var acquireValuetype = document.getElementById("acquire-valuetype");
|
var acquireValuetype = document.getElementById("acquire-valuetype");
|
||||||
var acquireChannel = document.getElementById("acquire-channel");
|
var acquireChannel = document.getElementById("acquire-channel");
|
||||||
@@ -578,7 +588,7 @@
|
|||||||
keys.forEach(function(k, i) {
|
keys.forEach(function(k, i) {
|
||||||
var listview = listView[k];
|
var listview = listView[k];
|
||||||
var p = document.createElement("p");
|
var p = document.createElement("p");
|
||||||
p.textContent = "还没有内容...";
|
p.textContent = stringRes("READER_ACQUIRE_NOCONTENT");
|
||||||
listview.emptyView = p;
|
listview.emptyView = p;
|
||||||
});
|
});
|
||||||
acquireLoading.statusBar = new TransitionPanel(acquireLoading, {
|
acquireLoading.statusBar = new TransitionPanel(acquireLoading, {
|
||||||
@@ -607,7 +617,7 @@
|
|||||||
acquireValuetype.disabled =
|
acquireValuetype.disabled =
|
||||||
acquireChannel.disabled = true;
|
acquireChannel.disabled = true;
|
||||||
queryFunc = StoreRG.test;
|
queryFunc = StoreRG.test;
|
||||||
acquireLoadingLabel.textContent = "正在查询...";
|
acquireLoadingLabel.textContent = stringRes("READER_ACQUIRE_QUERYING");
|
||||||
queryFunc(acquireInput.value, acquireValuetype.value, acquireChannel.value).then(function(result) {
|
queryFunc(acquireInput.value, acquireValuetype.value, acquireChannel.value).then(function(result) {
|
||||||
acquireCategoryid.textContent = result.categoryId;
|
acquireCategoryid.textContent = result.categoryId;
|
||||||
var applist = [];
|
var applist = [];
|
||||||
@@ -628,7 +638,7 @@
|
|||||||
return item.file;
|
return item.file;
|
||||||
});
|
});
|
||||||
listView.deps.refresh();
|
listView.deps.refresh();
|
||||||
acquireLoadingLabel.textContent = "已获取到 {0} 个信息"
|
acquireLoadingLabel.textContent = stringRes("READER_ACQUIRE_RESULTCNT")
|
||||||
.replace("{0}", applist.length + deplist.length);
|
.replace("{0}", applist.length + deplist.length);
|
||||||
}, function(err) {
|
}, function(err) {
|
||||||
dataSrc.apps.clear();
|
dataSrc.apps.clear();
|
||||||
@@ -654,6 +664,13 @@
|
|||||||
</script>
|
</script>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="page-search" style="display: none;" class="ispage padding">
|
||||||
|
<h2 data-res-resxml="READER_SEARCH_TITLE"></h2>
|
||||||
|
<div id="search-forbidden" style="width: 100%;">
|
||||||
|
<p data-res-resxml="READER_SEARCH_PROHIBIT"></p>
|
||||||
|
<a onclick="external.Process.open ('https://dbox.tools')">dbox.tools</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</main>
|
</main>
|
||||||
<aside class="win-ui-dark">
|
<aside class="win-ui-dark">
|
||||||
<nav class="container">
|
<nav class="container">
|
||||||
@@ -677,15 +694,19 @@
|
|||||||
<ul class="list">
|
<ul class="list">
|
||||||
<li id="tag-reader">
|
<li id="tag-reader">
|
||||||
<div role="img"></div>
|
<div role="img"></div>
|
||||||
<span class="win-type-base" data-res-resxml="MANAGER_MANAGE"></span>
|
<span class="win-type-base" data-res-resxml="READER_READER_TITLE"></span>
|
||||||
</li>
|
</li>
|
||||||
<li id="tag-acquire">
|
<li id="tag-acquire">
|
||||||
<div role="img"></div>
|
<div role="img"></div>
|
||||||
<span class="win-type-base" data-res-resxml="MANAGER_MANAGE"></span>
|
<span class="win-type-base" data-res-resxml="READER_ACQUIRE_TITLE"></span>
|
||||||
|
</li>
|
||||||
|
<li id="tag-search">
|
||||||
|
<div role="img"></div>
|
||||||
|
<span class="win-type-base" data-res-resxml="READER_SEARCH_TITLE"></span>
|
||||||
</li>
|
</li>
|
||||||
<li id="tag-settings">
|
<li id="tag-settings">
|
||||||
<div role="img"></div>
|
<div role="img"></div>
|
||||||
<span class="win-type-base" data-res-resxml="MANAGER_SETTINGS"></span>
|
<span class="win-type-base" data-res-resxml="READER_SETTINGS_TITLE"></span>
|
||||||
</li>
|
</li>
|
||||||
<script>
|
<script>
|
||||||
(function(global) {
|
(function(global) {
|
||||||
|
|||||||
@@ -195,6 +195,42 @@
|
|||||||
</table>
|
</table>
|
||||||
<script>
|
<script>
|
||||||
(function(global) {
|
(function(global) {
|
||||||
|
var imageItem = [
|
||||||
|
"LockScreenLogo",
|
||||||
|
"Logo",
|
||||||
|
"SmallLogo",
|
||||||
|
"Square150x150Logo",
|
||||||
|
"Square30x30Logo",
|
||||||
|
"Square310x310Logo",
|
||||||
|
"Square44x44Logo",
|
||||||
|
"Square70x70Logo",
|
||||||
|
"Square71x71Logo",
|
||||||
|
"Tall150x310Logo",
|
||||||
|
"WideLogo",
|
||||||
|
"Wide310x150Logo"
|
||||||
|
];
|
||||||
|
|
||||||
|
function toLowerCase(str) {
|
||||||
|
if (typeof str !== "string") return "";
|
||||||
|
return str.replace(/[A-Z]/g, function(ch) {
|
||||||
|
return String.fromCharCode(ch.charCodeAt(0) + 32);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function trim(str) {
|
||||||
|
return str.replace(/^\s+|\s+$/g, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
function isImageItem(item) {
|
||||||
|
var tl = trim(toLowerCase(item));
|
||||||
|
for (var i = 0; i < imageItem.length; i++) {
|
||||||
|
var lower = trim(toLowerCase(imageItem[i]));
|
||||||
|
if (lower == tl) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (typeof Array.prototype.forEach !== "function") {
|
if (typeof Array.prototype.forEach !== "function") {
|
||||||
Array.prototype.forEach = function(callback, thisArg) {
|
Array.prototype.forEach = function(callback, thisArg) {
|
||||||
var T, k;
|
var T, k;
|
||||||
@@ -317,7 +353,7 @@
|
|||||||
var tdv = document.createElement("td");
|
var tdv = document.createElement("td");
|
||||||
tdk.textContent = key;
|
tdk.textContent = key;
|
||||||
tdv.textContent = t[key];
|
tdv.textContent = t[key];
|
||||||
if (typeof t[key + "_Base64"] !== "undefined") {
|
if (typeof t[key + "_Base64"] !== "undefined" && isImageItem(key)) {
|
||||||
tdv.innerHTML = "";
|
tdv.innerHTML = "";
|
||||||
var img = document.createElement("img");
|
var img = document.createElement("img");
|
||||||
img.src = t[key + "_Base64"];
|
img.src = t[key + "_Base64"];
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
var settingItems = {
|
var settingItems = {
|
||||||
appinstaller: getSettingsItem("appinstaller.html", getLibRes("appinstaller.exe", 300)),
|
appinstaller: getSettingsItem("appinstaller.html", getLibRes("appinstaller.exe", 300)),
|
||||||
manager: getSettingsItem("manager.html", getStringRes("MANAGER_APPTITLE")),
|
manager: getSettingsItem("manager.html", getStringRes("MANAGER_APPTITLE")),
|
||||||
|
reader: getSettingsItem("reader.html", getStringRes("READER_APPTITLE")),
|
||||||
settings: getSettingsItem("settings.html", getLibRes("settings.exe", 200)),
|
settings: getSettingsItem("settings.html", getLibRes("settings.exe", 200)),
|
||||||
};
|
};
|
||||||
Object.defineProperty(global, "settingPages", {
|
Object.defineProperty(global, "settingPages", {
|
||||||
|
|||||||
56
shared/html/settings/reader.html
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>Package Manager Settings</title>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<script type="text/javascript" src="../js/module.js"></script>
|
||||||
|
<script type="text/javascript" src="../js/polyfill-ie.js"></script>
|
||||||
|
<link rel="stylesheet" href="../libs/winjs/2.0/css/ui-light.css" id="winjs-style">
|
||||||
|
<script type="text/javascript" src="../libs/winjs/1.0/js/base.js"></script>
|
||||||
|
<script type="text/javascript" src="../libs/winjs/1.0/js/ui.js"></script>
|
||||||
|
<script type="text/javascript" src="../js/color.js"></script>
|
||||||
|
<script type="text/javascript" src="../js/promise.js"></script>
|
||||||
|
<script type="text/javascript" src="../js/bridge.js"></script>
|
||||||
|
<script type="text/javascript" src="../js/dpimodes.js"></script>
|
||||||
|
<script type="text/javascript" src="../js/resources.js"></script>
|
||||||
|
<script type="text/javascript" src="../js/animation.js"></script>
|
||||||
|
<link rel="stylesheet" href="../fonts/fonts.css">
|
||||||
|
<script type="text/javascript" src="../js/event.js"></script>
|
||||||
|
<script type="text/javascript" src="../js/tileback.js"></script>
|
||||||
|
<script type="text/javascript" src="../js/load.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="../libs/msgbox/contentdlg.css">
|
||||||
|
<script type="text/javascript" src="../libs/msgbox/contentdlg.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="../libs/msgbox/msgbox.css">
|
||||||
|
<script type="text/javascript" src="../libs/msgbox/msgbox.js"></script>
|
||||||
|
<script type="text/javascript" src="../js/init.js"></script>
|
||||||
|
<script type="text/javascript" src="initsame.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="page.css">
|
||||||
|
<script type="text/javascript" src="reader/preinit.js"></script>
|
||||||
|
<script type="text/javascript" src="reader/items.js"></script>
|
||||||
|
<script type="text/javascript" src="reader/init.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="settingpage" class="pagecontainer full">
|
||||||
|
<div class="page full guide">
|
||||||
|
<aside class="left win-ui-dark">
|
||||||
|
<header aria-label="Header content" role="banner" class="titlebanner" id="pagebanner" style="height: 120px;">
|
||||||
|
<button id="back" class="win-backbutton pagetitlewb-backbutton" onclick="Bridge.Frame.callEvent ('InvokeBackPage')" style="margin-left: 20px; transform: scale(0.72);"></button>
|
||||||
|
<h2 class="titlearea win-type-ellipsis" id="apptitle" style="">
|
||||||
|
<span class="pagetitlewb-title" id="apptitlestr" style="margin-left: 10px; margin-right: 20px;" data-res-resxml="READER_APPTITLE"></span>
|
||||||
|
</h2>
|
||||||
|
</header>
|
||||||
|
<nav class="container">
|
||||||
|
<ul class="list">
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
</aside>
|
||||||
|
<iframe class="main right" defer loading="lazy" async></iframe>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
158
shared/html/settings/reader/appitems.html
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>App Installer Settings</title>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<script type="text/javascript" src="../../js/module.js"></script>
|
||||||
|
<script type="text/javascript" src="../../js/polyfill-ie.js"></script>
|
||||||
|
<link rel="stylesheet" href="../../libs/winjs/2.0/css/ui-light.css" id="winjs-style">
|
||||||
|
<script type="text/javascript" src="../../libs/winjs/1.0/js/base.js"></script>
|
||||||
|
<script type="text/javascript" src="../../libs/winjs/1.0/js/ui.js"></script>
|
||||||
|
<script type="text/javascript" src="../../js/color.js"></script>
|
||||||
|
<script type="text/javascript" src="../../js/promise.js"></script>
|
||||||
|
<script type="text/javascript" src="../../js/bridge.js"></script>
|
||||||
|
<script type="text/javascript" src="../../js/dpimodes.js"></script>
|
||||||
|
<script type="text/javascript" src="../../js/resources.js"></script>
|
||||||
|
<script type="text/javascript" src="../../js/animation.js"></script>
|
||||||
|
<link rel="stylesheet" href="../../fonts/fonts.css">
|
||||||
|
<script type="text/javascript" src="../../js/event.js"></script>
|
||||||
|
<script type="text/javascript" src="../../js/tileback.js"></script>
|
||||||
|
<script type="text/javascript" src="../../js/load.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="../../libs/msgbox/contentdlg.css">
|
||||||
|
<script type="text/javascript" src="../../libs/msgbox/contentdlg.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="../../libs/msgbox/msgbox.css">
|
||||||
|
<script type="text/javascript" src="../../libs/msgbox/msgbox.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="../../libs/toggle/toggle.css">
|
||||||
|
<script type="text/javascript" src="../../libs/toggle/toggle.js"></script>
|
||||||
|
<script type="text/javascript" src="../../js/init.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="../page.css">
|
||||||
|
<link rel="stylesheet" type="text/css" href="../subpage.css">
|
||||||
|
<script type="text/javascript" src="preinit.js"></script>
|
||||||
|
<script type="text/javascript" src="initsame.js"></script>
|
||||||
|
<script>
|
||||||
|
try {
|
||||||
|
window.parent.setItemHighlight("appitems");
|
||||||
|
} catch (e) {}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="pagecontainer full pagesection">
|
||||||
|
<div class="section padding">
|
||||||
|
<div class="bottom-compensate">
|
||||||
|
<h2 id="page-title" data-res-resxml="READER_SETTINGS_APPITEMS"></h2>
|
||||||
|
<div class="win-settings-section">
|
||||||
|
<p data-res-resxml="READER_SETTINGS_APPITEMS_DESC"></p>
|
||||||
|
<style>
|
||||||
|
table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
table th,
|
||||||
|
table td {
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<table style="max-width: 100%;">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th></th>
|
||||||
|
<th data-res-resxml="READER_SETTINGS_APPITEMS_ITEM"></th>
|
||||||
|
<th data-res-resxml="READER_SETTINGS_APPITEMS_DESCRIPTION"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="appitem-list"></tbody>
|
||||||
|
</table>
|
||||||
|
<script>
|
||||||
|
(function() {
|
||||||
|
"use strict";
|
||||||
|
var appItemList = document.getElementById("appitem-list");
|
||||||
|
var ini = Bridge.External.Config.GetConfig();
|
||||||
|
var appitemset = ini.getSection("PackageReader:AppMetadatas");
|
||||||
|
var appitems = [
|
||||||
|
"Id",
|
||||||
|
"StartPage",
|
||||||
|
"EntryPoint",
|
||||||
|
"Executable",
|
||||||
|
"BackgroundColor",
|
||||||
|
"DisplayName",
|
||||||
|
"Description",
|
||||||
|
"ShortName",
|
||||||
|
"ForegroundText",
|
||||||
|
"SmallLogo",
|
||||||
|
"Square30x30Logo",
|
||||||
|
"Square44x44Logo",
|
||||||
|
"Square70x70Logo",
|
||||||
|
"Square71x71Logo",
|
||||||
|
"Logo",
|
||||||
|
"Square150x150Logo",
|
||||||
|
"WideLogo",
|
||||||
|
"Wide310x150Logo",
|
||||||
|
"Square310x310Logo",
|
||||||
|
"Tall150x310Logo",
|
||||||
|
"LockScreenLogo",
|
||||||
|
"LockScreenNotification",
|
||||||
|
"DefaultSize",
|
||||||
|
"AppListEntry",
|
||||||
|
"VisualGroup",
|
||||||
|
"MinWidth",
|
||||||
|
];
|
||||||
|
var defaultItems = [
|
||||||
|
"Id",
|
||||||
|
"DisplayName",
|
||||||
|
"BackgroundColor",
|
||||||
|
"ForegroundText",
|
||||||
|
"ShortName",
|
||||||
|
"Square44x44Logo",
|
||||||
|
"SmallLogo"
|
||||||
|
];
|
||||||
|
for (var i = 0; i < appitems.length; i++) {
|
||||||
|
var item = appitems[i];
|
||||||
|
var isenable = appitemset.getKey(item).value;
|
||||||
|
if (isenable === null || isenable === void 0 || isenable === "") {
|
||||||
|
isenable = defaultItems.indexOf(item) >= 0;
|
||||||
|
}
|
||||||
|
var dispItem = stringRes("APPMETADATA_" + item);
|
||||||
|
var tr = document.createElement("tr");
|
||||||
|
var tdCheck = document.createElement("td");
|
||||||
|
var tdItem = document.createElement("td");
|
||||||
|
var tdDesc = document.createElement("td");
|
||||||
|
tr.appendChild(tdCheck);
|
||||||
|
tr.appendChild(tdItem);
|
||||||
|
tr.appendChild(tdDesc);
|
||||||
|
var checkbox = document.createElement("input");
|
||||||
|
tdCheck.appendChild(checkbox);
|
||||||
|
checkbox.type = "checkbox";
|
||||||
|
checkbox.checked = isenable;
|
||||||
|
checkbox.id = "appitem_" + item;
|
||||||
|
checkbox.setAttribute("data-metadata", item);
|
||||||
|
var label = document.createElement("label");
|
||||||
|
tdItem.appendChild(label);
|
||||||
|
label.setAttribute("for", checkbox.id);
|
||||||
|
label.style.fontWeight = "normal";
|
||||||
|
label.textContent = item;
|
||||||
|
label.title = item;
|
||||||
|
var labelDesc = document.createElement("label");
|
||||||
|
tdDesc.appendChild(labelDesc);
|
||||||
|
labelDesc.textContent = dispItem;
|
||||||
|
labelDesc.title = dispItem;
|
||||||
|
labelDesc.setAttribute("for", checkbox.id);
|
||||||
|
labelDesc.style.fontWeight = "normal";
|
||||||
|
appItemList.appendChild(tr);
|
||||||
|
checkbox.onchange = function() {
|
||||||
|
appitemset.getKey(this.getAttribute("data-metadata")).value = this.checked;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
192
shared/html/settings/reader/general.html
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>App Installer Settings</title>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<script type="text/javascript" src="../../js/module.js"></script>
|
||||||
|
<script type="text/javascript" src="../../js/polyfill-ie.js"></script>
|
||||||
|
<link rel="stylesheet" href="../../libs/winjs/2.0/css/ui-light.css" id="winjs-style">
|
||||||
|
<script type="text/javascript" src="../../libs/winjs/1.0/js/base.js"></script>
|
||||||
|
<script type="text/javascript" src="../../libs/winjs/1.0/js/ui.js"></script>
|
||||||
|
<script type="text/javascript" src="../../js/color.js"></script>
|
||||||
|
<script type="text/javascript" src="../../js/promise.js"></script>
|
||||||
|
<script type="text/javascript" src="../../js/bridge.js"></script>
|
||||||
|
<script type="text/javascript" src="../../js/dpimodes.js"></script>
|
||||||
|
<script type="text/javascript" src="../../js/resources.js"></script>
|
||||||
|
<script type="text/javascript" src="../../js/animation.js"></script>
|
||||||
|
<link rel="stylesheet" href="../../fonts/fonts.css">
|
||||||
|
<script type="text/javascript" src="../../js/event.js"></script>
|
||||||
|
<script type="text/javascript" src="../../js/tileback.js"></script>
|
||||||
|
<script type="text/javascript" src="../../js/load.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="../../libs/msgbox/contentdlg.css">
|
||||||
|
<script type="text/javascript" src="../../libs/msgbox/contentdlg.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="../../libs/msgbox/msgbox.css">
|
||||||
|
<script type="text/javascript" src="../../libs/msgbox/msgbox.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="../../libs/toggle/toggle.css">
|
||||||
|
<script type="text/javascript" src="../../libs/toggle/toggle.js"></script>
|
||||||
|
<script type="text/javascript" src="../../js/init.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="../page.css">
|
||||||
|
<link rel="stylesheet" type="text/css" href="../subpage.css">
|
||||||
|
<script type="text/javascript" src="preinit.js"></script>
|
||||||
|
<script type="text/javascript" src="initsame.js"></script>
|
||||||
|
<script>
|
||||||
|
try {
|
||||||
|
window.parent.setItemHighlight("general");
|
||||||
|
} catch (e) {}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="pagecontainer full pagesection">
|
||||||
|
<div class="section padding">
|
||||||
|
<div class="bottom-compensate">
|
||||||
|
<h2 id="page-title" data-res-fromfile="publicRes (101)"></h2>
|
||||||
|
<div class="win-settings-section">
|
||||||
|
<br>
|
||||||
|
<label class="win-label" for="save-wnd-size" id="save-wnd-size-label" data-res-fromfile="publicRes (125)"></label>
|
||||||
|
<script>
|
||||||
|
(function() {
|
||||||
|
"use strict";
|
||||||
|
var label = document.getElementById("save-wnd-size-label");
|
||||||
|
var toggle = new Toggle();
|
||||||
|
toggle.create();
|
||||||
|
toggle.parent = label.parentNode;
|
||||||
|
toggle.showlabel = true;
|
||||||
|
var winjsres = Bridge.External.WinJsStringRes;
|
||||||
|
toggle.setStatusText(winjsres.getString("ms-resource://Microsoft.WinJS.1.0/ui/on"), winjsres.getString("ms-resource://Microsoft.WinJS.1.0/ui/off"));
|
||||||
|
toggle.inputId = "save-wnd-size";
|
||||||
|
var ini = Bridge.External.Config.GetConfig();
|
||||||
|
toggle.addEventListener("change", function() {
|
||||||
|
ini.set("Settings", "PackageReader:SavePosAndSizeBeforeCancel", toggle.checked);
|
||||||
|
});
|
||||||
|
toggle.checked = parseBool(ini.getSection("Settings").getKey("PackageReader:SavePosAndSizeBeforeCancel").value);
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
<div class="win-settings-section">
|
||||||
|
<br>
|
||||||
|
<label class="win-label" for="default-wndwidth" data-res-fromfile="publicRes(126)"></label><br>
|
||||||
|
<input type="number" id="default-wndwidth" inputmode="numeric"><br><br>
|
||||||
|
<label class="win-label" for="default-wndheight" data-res-fromfile="publicRes(127)"></label><br>
|
||||||
|
<input type="number" id="default-wndheight" inputmode="numeric">
|
||||||
|
<script>
|
||||||
|
(function() {
|
||||||
|
"use strict";
|
||||||
|
var ini = Bridge.External.Config.GetConfig();
|
||||||
|
var defWndWInput = document.getElementById("default-wndwidth");
|
||||||
|
var defWndHInput = document.getElementById("default-wndheight");
|
||||||
|
var setsect = ini.getSection("Settings");
|
||||||
|
var defwk = setsect.getKey("PackageReader:DefaultWidth");
|
||||||
|
var defhk = setsect.getKey("PackageReader:DefaultHeight");
|
||||||
|
defWndWInput.value = defwk.value;
|
||||||
|
defWndHInput.value = defhk.value;
|
||||||
|
var eventutil = Windows.UI.Event.Util;
|
||||||
|
|
||||||
|
function inputDefaultWidthChangeEvent(e) {
|
||||||
|
defwk.value = parseInt(defWndWInput.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function inputDefaultHeightChangeEvent(e) {
|
||||||
|
defhk.value = parseInt(defWndHInput.value);
|
||||||
|
}
|
||||||
|
var debounced_idwc = debounce(inputDefaultWidthChangeEvent, 500);
|
||||||
|
var debounced_idhc = debounce(inputDefaultHeightChangeEvent, 500);
|
||||||
|
eventutil.addEvent(defWndWInput, "input", debounced_idwc);
|
||||||
|
eventutil.addEvent(defWndWInput, "propertychange", debounced_idwc);
|
||||||
|
eventutil.addEvent(defWndWInput, "change", debounced_idwc);
|
||||||
|
eventutil.addEvent(defWndHInput, "input", debounced_idhc);
|
||||||
|
eventutil.addEvent(defWndHInput, "propertychange", debounced_idhc);
|
||||||
|
eventutil.addEvent(defWndHInput, "change", debounced_idhc);
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
<div class="win-settings-section">
|
||||||
|
<br>
|
||||||
|
<label class="win-label" for="min-wndwidth" data-res-fromfile="publicRes (128)"></label><br>
|
||||||
|
<input type="number" id="min-wndwidth" inputmode="numeric"><br><br>
|
||||||
|
<label class="win-label" for="min-wndheight" data-res-fromfile="publicRes (129)"></label><br>
|
||||||
|
<input type="number" id="min-wndheight" inputmode="numeric">
|
||||||
|
<script>
|
||||||
|
(function() {
|
||||||
|
"use strict";
|
||||||
|
var ini = Bridge.External.Config.GetConfig();
|
||||||
|
var minWndWInput = document.getElementById("min-wndwidth");
|
||||||
|
var minWndHInput = document.getElementById("min-wndheight");
|
||||||
|
var setsect = ini.getSection("Settings");
|
||||||
|
var minwk = setsect.getKey("PackageReader:MinimumWidth");
|
||||||
|
var minhk = setsect.getKey("PackageReader:MinimumHeight");
|
||||||
|
minWndWInput.value = minwk.value;
|
||||||
|
minWndHInput.value = minhk.value;
|
||||||
|
var eventutil = Windows.UI.Event.Util;
|
||||||
|
|
||||||
|
function inputDefaultWidthChangeEvent(e) {
|
||||||
|
minwk.value = parseInt(minWndWInput.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function inputDefaultHeightChangeEvent(e) {
|
||||||
|
minhk.value = parseInt(minWndHInput.value);
|
||||||
|
}
|
||||||
|
var debounced_idwc = debounce(inputDefaultWidthChangeEvent, 500);
|
||||||
|
var debounced_idhc = debounce(inputDefaultHeightChangeEvent, 500);
|
||||||
|
eventutil.addEvent(minWndWInput, "input", debounced_idwc);
|
||||||
|
eventutil.addEvent(minWndWInput, "propertychange", debounced_idwc);
|
||||||
|
eventutil.addEvent(minWndWInput, "change", debounced_idwc);
|
||||||
|
eventutil.addEvent(minWndHInput, "input", debounced_idhc);
|
||||||
|
eventutil.addEvent(minWndHInput, "propertychange", debounced_idhc);
|
||||||
|
eventutil.addEvent(minWndHInput, "change", debounced_idhc);
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
<div class="win-settings-section">
|
||||||
|
<br>
|
||||||
|
<label class="win-label" for="enable-usepri" id="enable-usepri-label" data-res-resxml="READER_SETTINGS_USEPRI"></label>
|
||||||
|
<script>
|
||||||
|
(function() {
|
||||||
|
"use strict";
|
||||||
|
var label = document.getElementById("enable-usepri-label");
|
||||||
|
var toggle = new Toggle();
|
||||||
|
toggle.create();
|
||||||
|
toggle.parent = label.parentNode;
|
||||||
|
toggle.showlabel = true;
|
||||||
|
var winjsres = Bridge.External.WinJsStringRes;
|
||||||
|
toggle.setStatusText(winjsres.getString("ms-resource://Microsoft.WinJS.1.0/ui/on"), winjsres.getString("ms-resource://Microsoft.WinJS.1.0/ui/off"));
|
||||||
|
toggle.inputId = "enable-usepri";
|
||||||
|
var ini = Bridge.External.Config.GetConfig();
|
||||||
|
toggle.addEventListener("change", function() {
|
||||||
|
ini.set("Settings", "PackageReader:DefaultParsingPriFile", toggle.checked);
|
||||||
|
});
|
||||||
|
toggle.checked = parseBool(ini.getSection("Settings").getKey("PackageReader:DefaultParsingPriFile").value);
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
<div class="win-settings-section">
|
||||||
|
<br>
|
||||||
|
<label class="win-label" for="enable-acquire" id="enable-acquire-label" data-res-resxml="READER_SETTINGS_ENABLEACQUIRE"></label>
|
||||||
|
<script>
|
||||||
|
(function() {
|
||||||
|
"use strict";
|
||||||
|
var label = document.getElementById("enable-acquire-label");
|
||||||
|
var toggle = new Toggle();
|
||||||
|
toggle.create();
|
||||||
|
toggle.parent = label.parentNode;
|
||||||
|
toggle.showlabel = true;
|
||||||
|
var winjsres = Bridge.External.WinJsStringRes;
|
||||||
|
toggle.setStatusText(winjsres.getString("ms-resource://Microsoft.WinJS.1.0/ui/on"), winjsres.getString("ms-resource://Microsoft.WinJS.1.0/ui/off"));
|
||||||
|
toggle.inputId = "enable-acquire";
|
||||||
|
var ini = Bridge.External.Config.GetConfig();
|
||||||
|
toggle.addEventListener("change", function() {
|
||||||
|
ini.set("Settings", "PackageReader:EnableAcquire", toggle.checked);
|
||||||
|
});
|
||||||
|
toggle.checked = parseBool(ini.getSection("Settings").getKey("PackageReader:EnableAcquire").value);
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
62
shared/html/settings/reader/guide.html
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>App Installer Settings</title>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<script type="text/javascript" src="../../js/module.js"></script>
|
||||||
|
<script type="text/javascript" src="../../js/polyfill-ie.js"></script>
|
||||||
|
<link rel="stylesheet" href="../../libs/winjs/2.0/css/ui-light.css" id="winjs-style">
|
||||||
|
<script type="text/javascript" src="../../libs/winjs/1.0/js/base.js"></script>
|
||||||
|
<script type="text/javascript" src="../../libs/winjs/1.0/js/ui.js"></script>
|
||||||
|
<script type="text/javascript" src="../../js/color.js"></script>
|
||||||
|
<script type="text/javascript" src="../../js/promise.js"></script>
|
||||||
|
<script type="text/javascript" src="../../js/bridge.js"></script>
|
||||||
|
<script type="text/javascript" src="../../js/dpimodes.js"></script>
|
||||||
|
<script type="text/javascript" src="../../js/resources.js"></script>
|
||||||
|
<script type="text/javascript" src="../../js/animation.js"></script>
|
||||||
|
<link rel="stylesheet" href="../../fonts/fonts.css">
|
||||||
|
<script type="text/javascript" src="../../js/event.js"></script>
|
||||||
|
<script type="text/javascript" src="../../js/tileback.js"></script>
|
||||||
|
<script type="text/javascript" src="../../js/load.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="../../libs/msgbox/contentdlg.css">
|
||||||
|
<script type="text/javascript" src="../../libs/msgbox/contentdlg.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="../../libs/msgbox/msgbox.css">
|
||||||
|
<script type="text/javascript" src="../../libs/msgbox/msgbox.js"></script>
|
||||||
|
<script type="text/javascript" src="../../js/init.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="../page.css">
|
||||||
|
<link rel="stylesheet" type="text/css" href="../subpage.css">
|
||||||
|
<script type="text/javascript" src="preinit.js"></script>
|
||||||
|
<script type="text/javascript" src="initsame.js"></script>
|
||||||
|
<script>
|
||||||
|
try {
|
||||||
|
window.parent.setItemHighlight("guide");
|
||||||
|
} catch (e) {}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="pagecontainer full pagesection">
|
||||||
|
<div class="section padding">
|
||||||
|
<div class="bottom-compensate">
|
||||||
|
<h2 id="guide-title"></h2>
|
||||||
|
<p id="guide-desc" style="white-space: pre-wrap;"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
(function() {
|
||||||
|
"use strict";
|
||||||
|
var res = Bridge.Resources;
|
||||||
|
var stru = Bridge.String;
|
||||||
|
var title = document.getElementById("guide-title");
|
||||||
|
title.textContent = stru.format(res.byname("IDS_TITLEFORMAT"), stringRes("READER_APPTITLE"));
|
||||||
|
var text = document.getElementById("guide-desc");
|
||||||
|
text.textContent = res.byname("IDS_GUIDETEXT_COMMON");
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
96
shared/html/settings/reader/init.js
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
(function(global) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
function ready(e) {
|
||||||
|
var page = document.querySelector("#settingpage");
|
||||||
|
var guide = page.querySelector(".page.guide");
|
||||||
|
var slide = guide.querySelector("aside");
|
||||||
|
setTimeout(function() {
|
||||||
|
var barcolor = visual["BackgroundColor"];
|
||||||
|
slide.style.backgroundColor = barcolor;
|
||||||
|
slide.style.color = Color.getSuitableForegroundTextColor(Color.parse(barcolor), [Color.Const.white, Color.Const.black]).stringify();
|
||||||
|
}, 50);
|
||||||
|
var content = guide.querySelector(".main");
|
||||||
|
var list = slide.querySelector("ul");
|
||||||
|
var backbtn = slide.querySelector("#back");
|
||||||
|
var title = slide.querySelector("#apptitle");
|
||||||
|
list.innerHTML = "";
|
||||||
|
var items = pages;
|
||||||
|
var tags = Object.keys(items);
|
||||||
|
var eventutil = Windows.UI.Event.Util;
|
||||||
|
for (var i = 0; i < tags.length; i++) {
|
||||||
|
var tag = tags[i];
|
||||||
|
var item = items[tag];
|
||||||
|
var li = document.createElement("li");
|
||||||
|
li.setAttribute("data-page", item.page);
|
||||||
|
li.setAttribute("data-tag", item.tag);
|
||||||
|
li.innerHTML = item.title;
|
||||||
|
eventutil.addEvent(li, "click", function() {
|
||||||
|
if (li.hasAttribute("data-require-disabled")) return;
|
||||||
|
content.style.display = "none";
|
||||||
|
for (var j = 0; j < list.children.length; j++) {
|
||||||
|
var child = list.children[j];
|
||||||
|
if (child.classList.contains("selected"))
|
||||||
|
child.classList.remove("selected");
|
||||||
|
}
|
||||||
|
content.src = this.getAttribute("data-page");
|
||||||
|
setTimeout(function() {
|
||||||
|
content.style.display = "";
|
||||||
|
Windows.UI.Animation.runAsync(content, [Windows.UI.Animation.Keyframes.Flyout.toLeft, Windows.UI.Animation.Keyframes.Opacity.visible]);
|
||||||
|
}, 0);
|
||||||
|
this.classList.add("selected");
|
||||||
|
});
|
||||||
|
list.appendChild(li);
|
||||||
|
}
|
||||||
|
content.src = guidePage.page;
|
||||||
|
/*for (var i = 0; i < list.children.length; i++) {
|
||||||
|
var child = list.children[i];
|
||||||
|
child.click();
|
||||||
|
break;
|
||||||
|
}*/
|
||||||
|
var jumppage = "";
|
||||||
|
try { var args = cmdargs; if (args.length > 1) jumppage = args[1]; } catch (e) {}
|
||||||
|
if (jumppage && jumppage.length > 0 && !Bridge.External.jump2) {
|
||||||
|
for (var i = 0; i < list.children.length; i++) {
|
||||||
|
var child = list.children[i];
|
||||||
|
if (Bridge.NString.equals(child.getAttribute("data-tag"), jumppage)) {
|
||||||
|
Bridge.External.jump2 = true;
|
||||||
|
setTimeout(function(thisnode) {
|
||||||
|
thisnode.click();
|
||||||
|
}, 0, child)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
global.setDisabledForOperation = function(disabled) {
|
||||||
|
var list = document.querySelector("#settingpage .guide aside ul");
|
||||||
|
for (var i = 0; i < list.children.length; i++) {
|
||||||
|
var child = list.children[i];
|
||||||
|
if (disabled) {
|
||||||
|
child.setAttribute("data-require-disabled", "true");
|
||||||
|
} else {
|
||||||
|
child.removeAttribute("data-require-disabled");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (disabled) {
|
||||||
|
backbtn.disabled = true;
|
||||||
|
title.style.marginLeft = backbtn.style.marginLeft;
|
||||||
|
} else {
|
||||||
|
backbtn.disabled = false;
|
||||||
|
title.style.marginLeft = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
global.setItemHighlight = function(tag) {
|
||||||
|
var list = document.querySelector("#settingpage .guide aside ul");
|
||||||
|
for (var i = 0; i < list.children.length; i++) {
|
||||||
|
var child = list.children[i];
|
||||||
|
if (Bridge.NString.equals(child.getAttribute("data-tag"), tag)) {
|
||||||
|
if (!child.classList.contains("selected")) child.classList.add("selected");
|
||||||
|
} else {
|
||||||
|
if (child.classList.contains("selected")) child.classList.remove("selected");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OnLoad.add(ready);
|
||||||
|
})(this);
|
||||||
21
shared/html/settings/reader/initsame.js
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
(function(global) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
function ready(e) {
|
||||||
|
Windows.UI.DPI.mode = 1
|
||||||
|
var pagesection = document.querySelector(".pagesection");
|
||||||
|
if (pagesection) {
|
||||||
|
var backcolor = slideback;
|
||||||
|
setTimeout(function() {
|
||||||
|
var h2style = document.getElementById("h2-style");
|
||||||
|
if (!h2style) {
|
||||||
|
h2style = document.createElement("style");
|
||||||
|
h2style.id = "h2-style";
|
||||||
|
}
|
||||||
|
h2style.innerHTML = ".main h2 { color: " + Color.getSuitableForegroundTextColor(Color.parse("#F3F3F3"), [Color.parse(backcolor), Color.Const.black]).RGBA.stringify() + " }";
|
||||||
|
document.head.appendChild(h2style);
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OnLoad.add(ready);
|
||||||
|
})(this);
|
||||||
25
shared/html/settings/reader/items.js
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
(function(global) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
function getPage(tag, page, display) {
|
||||||
|
return {
|
||||||
|
tag: tag,
|
||||||
|
page: page,
|
||||||
|
title: display
|
||||||
|
};
|
||||||
|
}
|
||||||
|
var pages = {
|
||||||
|
general: getPage("general", "reader/general.html", getPublicRes(101)),
|
||||||
|
appitems: getPage("appitems", "reader/appitems.html", stringRes("READER_SETTINGS_APPITEMS")),
|
||||||
|
};
|
||||||
|
Object.defineProperty(global, "pages", {
|
||||||
|
get: function() {
|
||||||
|
return pages;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(global, "guidePage", {
|
||||||
|
get: function() {
|
||||||
|
return getPage("guide", "reader/guide.html", "guide");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})(this);
|
||||||
30
shared/html/settings/reader/preinit.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
(function(global) {
|
||||||
|
var storage = Bridge.External.Storage;
|
||||||
|
var path = storage.path;
|
||||||
|
var root = path.getDir(path.program);
|
||||||
|
var exepath = path.combine(root, "settings.exe");
|
||||||
|
var id = "Reader";
|
||||||
|
var ve = Bridge.External.VisualElements.get(id);
|
||||||
|
var slideback = ve["BackgroundColor"];
|
||||||
|
global.slideback = slideback;
|
||||||
|
global.exepath = exepath;
|
||||||
|
global.visual = ve;
|
||||||
|
var strutil = Bridge.External.String;
|
||||||
|
var nstrutil = Bridge.NString;
|
||||||
|
var boolTrue = ["true", "1", "yes", "on", "y", "t", "zhen", "真"];
|
||||||
|
var boolFalse = ["false", "0", "no", "off", "n", "f", "jia", "假"];
|
||||||
|
global.parseBool = function(str) {
|
||||||
|
str = "" + str;
|
||||||
|
for (var i = 0; i < boolTrue.length; i++) {
|
||||||
|
if (nstrutil.equals(str, boolTrue[i])) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (var i = 0; i < boolFalse.length; i++) {
|
||||||
|
if (nstrutil.equals(str, boolFalse[i])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
})(this);
|
||||||
BIN
shared/icons/32_reader.ico
Normal file
|
After Width: | Height: | Size: 358 KiB |
17
shared/license/LICENSE.SharpZipLib
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
Copyright © 2000-2018 SharpZipLib Contributors
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||||
|
software and associated documentation files (the "Software"), to deal in the Software
|
||||||
|
without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||||
|
publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||||
|
to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all copies or
|
||||||
|
substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||||
|
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||||
|
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||||
|
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
NOTICE
|
|
||||||
|
|
||||||
This product includes software developed by third parties.
|
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
PriTools (PriFormat)
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
|
|
||||||
This product includes code derived from the PriTools project
|
|
||||||
developed by chausner.
|
|
||||||
|
|
||||||
Original Project:
|
|
||||||
Name: PriTools
|
|
||||||
Author: chausner
|
|
||||||
Project Homepage: https://github.com/chausner/PriTools
|
|
||||||
Source Repository: https://github.com/chausner/PriTools/tree/master
|
|
||||||
License: Apache License, Version 2.0
|
|
||||||
License File: LICENSE.PriTools.chausner
|
|
||||||
|
|
||||||
The original PriFormat project has been modified in this product, including:
|
|
||||||
- Renamed from "PriFormat" to "PriFileFormat"
|
|
||||||
- Adapted to support Microsoft .NET Framework 4.6
|
|
||||||
- Added support for the COM IStream interface
|
|
||||||
- Modified resource cleanup and disposal logic
|
|
||||||
- Changed namespaces and internal structure
|
|
||||||
|
|
||||||
These modifications were made by the authors of this product.
|
|
||||||
The original copyright and license notices
|
|
||||||
are retained in accordance with the Apache License, Version 2.0.
|
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
pugixml
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
|
|
||||||
This product includes pugixml, which is licensed under the MIT License.
|
|
||||||
|
|
||||||
License File:
|
|
||||||
LICENSE.pugixml
|
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
RapidJSON
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
|
|
||||||
This product includes RapidJSON, which is licensed under the MIT License.
|
|
||||||
|
|
||||||
License File:
|
|
||||||
LICENSE.RapidJSON
|
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
markdown.js
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
|
|
||||||
This product includes markdown.js (also known as markdown-js).
|
|
||||||
|
|
||||||
Original Project:
|
|
||||||
Name: markdown.js
|
|
||||||
Source Repository: https://github.com/evilstreak/markdown-js
|
|
||||||
License: MIT License
|
|
||||||
License File: LICENSE.markdown.js
|
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
WinJS
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
|
|
||||||
This product includes Microsoft WinJS (Windows Library for JavaScript).
|
|
||||||
|
|
||||||
Original Project:
|
|
||||||
Name: WinJS
|
|
||||||
Author: Microsoft Corporation
|
|
||||||
Project Homepage: https://github.com/winjs/winjs
|
|
||||||
License: MIT License
|
|
||||||
License File: LICENSE.WinJS
|
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
|
|
||||||
End of notices.
|
|
||||||
@@ -77,6 +77,7 @@ text-align: center;
|
|||||||
<li>markdown.js (MIT License) - <a href="https://github.com/evilstreak/markdown-js" target="_blank">https://github.com/evilstreak/markdown-js</a></li>
|
<li>markdown.js (MIT License) - <a href="https://github.com/evilstreak/markdown-js" target="_blank">https://github.com/evilstreak/markdown-js</a></li>
|
||||||
<li>CodeMirror (MIT License) - <a href="https://codemirror.net/" target="_blank">https://codemirror.net/</a></li>
|
<li>CodeMirror (MIT License) - <a href="https://codemirror.net/" target="_blank">https://codemirror.net/</a></li>
|
||||||
<li>Json.NET (MIT License) - <a href="https://www.newtonsoft.com/json" target="_blank">https://www.newtonsoft.com/json</a></li>
|
<li>Json.NET (MIT License) - <a href="https://www.newtonsoft.com/json" target="_blank">https://www.newtonsoft.com/json</a></li>
|
||||||
|
<li>SharpZipLib (MIT License) - <a href="https://icsharpcode.github.io/SharpZipLib/" target="_blank">https://icsharpcode.github.io/SharpZipLib/</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h2>四、免责声明</h2>
|
<h2>四、免责声明</h2>
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ text-align: center;
|
|||||||
<li>markdown.js (MIT License) - <a href="https://github.com/evilstreak/markdown-js" target="_blank">https://github.com/evilstreak/markdown-js</a></li>
|
<li>markdown.js (MIT License) - <a href="https://github.com/evilstreak/markdown-js" target="_blank">https://github.com/evilstreak/markdown-js</a></li>
|
||||||
<li>CodeMirror (MIT License) - <a href="https://codemirror.net/" target="_blank">https://codemirror.net/</a></li>
|
<li>CodeMirror (MIT License) - <a href="https://codemirror.net/" target="_blank">https://codemirror.net/</a></li>
|
||||||
<li>Json.NET (MIT License) - <a href="https://www.newtonsoft.com/json" target="_blank">https://www.newtonsoft.com/json</a></li>
|
<li>Json.NET (MIT License) - <a href="https://www.newtonsoft.com/json" target="_blank">https://www.newtonsoft.com/json</a></li>
|
||||||
|
<li>SharpZipLib (MIT License) - <a href="https://icsharpcode.github.io/SharpZipLib/" target="_blank">https://icsharpcode.github.io/SharpZipLib/</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h2>4. Disclaimer</h2>
|
<h2>4. Disclaimer</h2>
|
||||||
|
|||||||