70 Commits

Author SHA1 Message Date
Bruce
8a44ae0ebd Update the read of publisher id. 2026-04-14 16:48:39 +08:00
Bruce
9fbcbdd7e9 Make used room smaller. 2026-04-14 16:32:45 +08:00
Bruce
686e08199c Streamlined the libraries. 2026-04-14 16:09:13 +08:00
Bruce
3b790c3503 Remove Build Files. 2026-04-12 23:02:50 +08:00
Bruce
055b459d8b Merge branch 'master' of https://github.com/modernw/App-Installer-For-Windows-8.x-Reset.git 2026-04-12 23:00:14 +08:00
Bruce
bc6ea5a8b0 Update build files for ARM. 2026-04-12 23:00:10 +08:00
modernw
448168e4d6 Revise required runtime libraries in README
Updated required runtime libraries for x86/ARM.
2026-04-12 18:32:14 +08:00
Bruce
fc9aafd7ef Update the solution for Arm Build update. 2026-04-12 16:29:16 +08:00
Bruce
be922b9a0c Update the configures for building. 2026-04-12 12:50:18 +08:00
Bruce
89a05d6d15 Change the configures of building. 2026-04-12 11:48:58 +08:00
Bruce
7e10c34627 Update styles. 2026-04-12 11:25:03 +08:00
Bruce
32a48c5e41 Update manager 2026-04-11 23:27:59 +08:00
Bruce
ed0920b21b Fix a bug. 2026-04-11 22:42:04 +08:00
Bruce
5378e3d54b Update locale string. 2026-04-11 22:31:25 +08:00
Bruce
87beb7af51 Update reader 2026-04-11 20:53:10 +08:00
Bruce
4993fd9968 Update changes. 2026-04-11 20:46:51 +08:00
Bruce
1df420c437 Fix the configures of projects. 2026-04-11 20:33:32 +08:00
Bruce
994a53a00b Merge branch 'master' of https://github.com/modernw/App-Installer-For-Windows-8.x-Reset.git 2026-04-11 20:21:32 +08:00
Bruce
179ae49d20 Update locale strings. 2026-04-11 20:21:27 +08:00
modernw
c0dac1ac7f Merge pull request #2 from bingtangxh/master
Add x86 build configs
2026-04-11 18:04:54 +08:00
modernw
687e18b80c Merge branch 'master' into master 2026-04-11 17:55:00 +08:00
Bruce
598007f177 2026-04-11 16:27:33 +08:00
Bruce
7552ffed35 Fix the obtain of locale resource. (Capability Names) 2026-04-11 16:17:03 +08:00
Bruce
8227689e6a Update configures. 2026-04-11 14:25:37 +08:00
Bruce
d170a9196d Update the build configure. 2026-04-11 13:52:09 +08:00
Bruce
f5edaf2f23 Merge branch 'master' of https://github.com/modernw/App-Installer-For-Windows-8.x-Reset.git 2026-04-10 23:13:00 +08:00
Bruce
1ef31d54c8 Update version. 2026-04-10 23:12:54 +08:00
冰糖XH
0cabf43e17 Merge branch 'modernw:master' into master 2026-04-10 23:01:59 +08:00
modernw
f98c57ef3a Update .NET Framework version in README 2026-04-10 20:25:07 +08:00
modernw
84f89f3464 Update README with x86 runtime library note
Added note about x86 runtime library installation requirements.
2026-04-10 20:24:35 +08:00
modernw
f36351c009 Update README.md 2026-04-10 18:27:11 +08:00
Bruce
f44589009c Merge branch 'master' of https://github.com/modernw/App-Installer-For-Windows-8.x-Reset.git 2026-04-10 17:58:37 +08:00
Bruce
868fb8b3e8 Change the version of WinJS 1.0. 2026-04-10 17:58:31 +08:00
modernw
e1d89a022e Update README.md 2026-04-10 15:29:54 +08:00
Bruce
10aa419e98 Merge branch 'master' of https://github.com/modernw/App-Installer-For-Windows-8.x-Reset.git 2026-04-10 15:28:49 +08:00
Bruce
db20b3bc4e Remove Tools for fork conveniently. 2026-04-10 15:28:46 +08:00
modernw
de33c438b6 Update download link for Runtime Libraries 2026-04-10 15:26:01 +08:00
modernw
1f9635255e Update README.md 2026-04-10 15:22:15 +08:00
modernw
3329058840 Update README.md 2026-04-10 15:18:20 +08:00
Bruce
ee5854c5a1 Merge branch 'master' of https://github.com/modernw/App-Installer-For-Windows-8.x-Reset.git 2026-04-10 15:17:07 +08:00
Bruce
471ce85cdf Pack as a zip file. 2026-04-10 15:17:02 +08:00
modernw
f28e3fe24c Update README with download links for runtime and dependencies
Added links to download runtime libraries and dependencies for Metro apps.
2026-04-10 15:16:23 +08:00
Bruce
169815e88a Update. 2026-04-10 15:10:39 +08:00
Bruce
2c6391804e Update style. 2026-04-10 14:18:04 +08:00
Bruce
fa65d40f3e Update font use. 2026-04-10 14:13:24 +08:00
Bruce
2fd73eab85 Merge branch 'master' of https://github.com/modernw/App-Installer-For-Windows-8.x-Reset.git 2026-04-10 14:08:22 +08:00
modernw
9111c019ff Update README.md 2026-04-10 14:00:51 +08:00
Bruce
200262d3ca Fix bugs. 2026-04-10 13:58:15 +08:00
Bruce
0f7c4be17e Revert "update."
This reverts commit c28c09973e.
2026-04-10 12:16:59 +08:00
Bruce
ded9ea9293 try to fix bugs. 2026-04-10 12:16:12 +08:00
冰糖XH
b131251a3b Merge branch 'modernw:master' into master 2026-04-10 10:55:58 +08:00
Bruce
f563f97f12 Try to fix bugs. 2026-04-10 10:50:22 +08:00
Bruce
19757502ae fix bugs. 2026-04-09 22:16:47 +08:00
Bruce
c28c09973e update. 2026-04-09 21:37:00 +08:00
Bruce
8dd01a67e9 Merge branch 'master' of https://github.com/modernw/App-Installer-For-Windows-8.x-Reset.git 2026-04-09 21:36:48 +08:00
Bruce
84a28db8cf Update locale resources. 2026-04-09 18:04:40 +08:00
modernw
b315782df6 Add special thanks section to README
Added a section for special thanks and contributor acknowledgment.
2026-04-09 15:39:16 +08:00
Bruce
9ba3b875da Update special thanks. 2026-04-09 14:10:57 +08:00
Bruce
9ae2e886bd Update special thanks. 2026-04-09 14:09:58 +08:00
Bruce
0926da3f27 Update license. 2026-04-09 13:34:09 +08:00
Bruce
4355ce4d13 Update help text. 2026-04-09 12:57:35 +08:00
Bruce
90d16151f4 pkgcli: add the confirm before remove. 2026-04-09 12:30:14 +08:00
Bruce
4bddb96052 Pkgcli: add the confirm before install. 2026-04-09 12:29:46 +08:00
Bruce
368efeb2f0 Update pkgcli. 2026-04-09 12:07:44 +08:00
Bruce
8e8a0453c4 Update PkgCLI. 2026-04-08 23:42:55 +08:00
Bruce
e58b47926c Canceled the settings of console input encoding. 2026-04-08 23:39:09 +08:00
Bruce
6d40668c1a Update version. 2026-04-08 23:35:14 +08:00
Bruce
71c8d76593 Fix bugs.
Update PkgCLI.
2026-04-08 23:32:11 +08:00
冰糖XH
76ce97370f Add x86 build configs; update .sln VS version
Update AppInstallerReset.sln to Visual Studio 17 and normalize project configuration/platform mappings. Add Debug|x86 and Release|x86 PropertyGroup entries to Bridge, DataUtils, Launch, ModernNotice, PriFileFormat, PrivateInit, Update and WAShell .csproj files to produce x86 outputs (bin\x86\...), set PlatformTarget to x86, LangVersion=7.3, and configure debug/optimization/define settings. These changes enable building x86 configurations and align projects with the updated solution environment.
2026-04-07 17:42:41 +08:00
Bruce
c4eaa4ad45 Change the styles of ContentDialog. 2026-04-06 20:43:20 +08:00
445 changed files with 5408 additions and 147117 deletions

7
.gitignore vendored
View File

@@ -249,4 +249,9 @@ ModelManifest.xml
# Arm Build Files
package.zip
ArmPackage.zip
ArmPackage.zip
ArmBuild.ps1
arm_build.bat
ARM_PIE.pfx
UpgradeLog.htm

View File

@@ -81,273 +81,200 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PkgCLI", "PkgCLI\PkgCLI.csp
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|ARM = Debug|ARM
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|ARM = Release|ARM
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A7753282-AA16-43D9-8ACA-7065239DD702}.Debug|Any CPU.ActiveCfg = Debug|Win32
{A7753282-AA16-43D9-8ACA-7065239DD702}.Debug|ARM.ActiveCfg = Debug|ARM
{A7753282-AA16-43D9-8ACA-7065239DD702}.Debug|ARM.Build.0 = Debug|ARM
{A7753282-AA16-43D9-8ACA-7065239DD702}.Debug|x86.ActiveCfg = Debug|Win32
{A7753282-AA16-43D9-8ACA-7065239DD702}.Debug|x86.Build.0 = Debug|Win32
{A7753282-AA16-43D9-8ACA-7065239DD702}.Release|Any CPU.ActiveCfg = Release|Win32
{A7753282-AA16-43D9-8ACA-7065239DD702}.Release|ARM.ActiveCfg = Release|ARM
{A7753282-AA16-43D9-8ACA-7065239DD702}.Release|ARM.Build.0 = Release|ARM
{A7753282-AA16-43D9-8ACA-7065239DD702}.Release|x86.ActiveCfg = Release|Win32
{A7753282-AA16-43D9-8ACA-7065239DD702}.Release|x86.Build.0 = Release|Win32
{8EAC0230-4990-4E41-8E0F-D641D1561396}.Debug|Any CPU.ActiveCfg = Debug|Win32
{8EAC0230-4990-4E41-8E0F-D641D1561396}.Debug|ARM.ActiveCfg = Debug|ARM
{8EAC0230-4990-4E41-8E0F-D641D1561396}.Debug|ARM.Build.0 = Debug|ARM
{8EAC0230-4990-4E41-8E0F-D641D1561396}.Debug|x86.ActiveCfg = Debug|Win32
{8EAC0230-4990-4E41-8E0F-D641D1561396}.Debug|x86.Build.0 = Debug|Win32
{8EAC0230-4990-4E41-8E0F-D641D1561396}.Release|Any CPU.ActiveCfg = Release|Win32
{8EAC0230-4990-4E41-8E0F-D641D1561396}.Release|ARM.ActiveCfg = Release|ARM
{8EAC0230-4990-4E41-8E0F-D641D1561396}.Release|ARM.Build.0 = Release|ARM
{8EAC0230-4990-4E41-8E0F-D641D1561396}.Release|x86.ActiveCfg = Release|Win32
{8EAC0230-4990-4E41-8E0F-D641D1561396}.Release|x86.Build.0 = Release|Win32
{798ED492-EECE-457D-8FD8-129DA93CE126}.Debug|Any CPU.ActiveCfg = Debug|Win32
{798ED492-EECE-457D-8FD8-129DA93CE126}.Debug|ARM.ActiveCfg = Debug|ARM
{798ED492-EECE-457D-8FD8-129DA93CE126}.Debug|ARM.Build.0 = Debug|ARM
{798ED492-EECE-457D-8FD8-129DA93CE126}.Debug|x86.ActiveCfg = Debug|Win32
{798ED492-EECE-457D-8FD8-129DA93CE126}.Debug|x86.Build.0 = Debug|Win32
{798ED492-EECE-457D-8FD8-129DA93CE126}.Release|Any CPU.ActiveCfg = Release|Win32
{798ED492-EECE-457D-8FD8-129DA93CE126}.Release|ARM.ActiveCfg = Release|ARM
{798ED492-EECE-457D-8FD8-129DA93CE126}.Release|ARM.Build.0 = Release|ARM
{798ED492-EECE-457D-8FD8-129DA93CE126}.Release|x86.ActiveCfg = Release|Win32
{798ED492-EECE-457D-8FD8-129DA93CE126}.Release|x86.Build.0 = Release|Win32
{EF4012D4-EF08-499C-B803-177739350B2D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EF4012D4-EF08-499C-B803-177739350B2D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EF4012D4-EF08-499C-B803-177739350B2D}.Debug|ARM.ActiveCfg = Debug|Any CPU
{EF4012D4-EF08-499C-B803-177739350B2D}.Debug|ARM.Build.0 = Debug|Any CPU
{EF4012D4-EF08-499C-B803-177739350B2D}.Debug|x86.ActiveCfg = Debug|Any CPU
{EF4012D4-EF08-499C-B803-177739350B2D}.Debug|x86.Build.0 = Debug|Any CPU
{EF4012D4-EF08-499C-B803-177739350B2D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EF4012D4-EF08-499C-B803-177739350B2D}.Release|Any CPU.Build.0 = Release|Any CPU
{EF4012D4-EF08-499C-B803-177739350B2D}.Release|ARM.ActiveCfg = Release|Any CPU
{EF4012D4-EF08-499C-B803-177739350B2D}.Release|ARM.Build.0 = Release|Any CPU
{EF4012D4-EF08-499C-B803-177739350B2D}.Release|x86.ActiveCfg = Release|Any CPU
{EF4012D4-EF08-499C-B803-177739350B2D}.Release|x86.Build.0 = Release|Any CPU
{E04CCAB9-35DB-495C-A279-5B483C707CD0}.Debug|Any CPU.ActiveCfg = Debug|Win32
{EF4012D4-EF08-499C-B803-177739350B2D}.Release|x86.ActiveCfg = Release|x86
{EF4012D4-EF08-499C-B803-177739350B2D}.Release|x86.Build.0 = Release|x86
{E04CCAB9-35DB-495C-A279-5B483C707CD0}.Debug|ARM.ActiveCfg = Debug|ARM
{E04CCAB9-35DB-495C-A279-5B483C707CD0}.Debug|ARM.Build.0 = Debug|ARM
{E04CCAB9-35DB-495C-A279-5B483C707CD0}.Debug|x86.ActiveCfg = Debug|Win32
{E04CCAB9-35DB-495C-A279-5B483C707CD0}.Debug|x86.Build.0 = Debug|Win32
{E04CCAB9-35DB-495C-A279-5B483C707CD0}.Release|Any CPU.ActiveCfg = Release|Win32
{E04CCAB9-35DB-495C-A279-5B483C707CD0}.Release|ARM.ActiveCfg = Release|ARM
{E04CCAB9-35DB-495C-A279-5B483C707CD0}.Release|ARM.Build.0 = Release|ARM
{E04CCAB9-35DB-495C-A279-5B483C707CD0}.Release|x86.ActiveCfg = Release|Win32
{E04CCAB9-35DB-495C-A279-5B483C707CD0}.Release|x86.Build.0 = Release|Win32
{F0C84812-0CDF-4AA0-A0F8-F37AC833F39B}.Debug|Any CPU.ActiveCfg = Debug|Win32
{F0C84812-0CDF-4AA0-A0F8-F37AC833F39B}.Debug|ARM.ActiveCfg = Debug|ARM
{F0C84812-0CDF-4AA0-A0F8-F37AC833F39B}.Debug|ARM.Build.0 = Debug|ARM
{F0C84812-0CDF-4AA0-A0F8-F37AC833F39B}.Debug|x86.ActiveCfg = Debug|Win32
{F0C84812-0CDF-4AA0-A0F8-F37AC833F39B}.Debug|x86.Build.0 = Debug|Win32
{F0C84812-0CDF-4AA0-A0F8-F37AC833F39B}.Release|Any CPU.ActiveCfg = Release|Win32
{F0C84812-0CDF-4AA0-A0F8-F37AC833F39B}.Release|ARM.ActiveCfg = Release|ARM
{F0C84812-0CDF-4AA0-A0F8-F37AC833F39B}.Release|ARM.Build.0 = Release|ARM
{F0C84812-0CDF-4AA0-A0F8-F37AC833F39B}.Release|x86.ActiveCfg = Release|Win32
{F0C84812-0CDF-4AA0-A0F8-F37AC833F39B}.Release|x86.Build.0 = Release|Win32
{AD25497F-A15F-4DFF-AC7A-B8ABF5F411D6}.Debug|Any CPU.ActiveCfg = Debug|Win32
{AD25497F-A15F-4DFF-AC7A-B8ABF5F411D6}.Debug|ARM.ActiveCfg = Debug|ARM
{AD25497F-A15F-4DFF-AC7A-B8ABF5F411D6}.Debug|ARM.Build.0 = Debug|ARM
{AD25497F-A15F-4DFF-AC7A-B8ABF5F411D6}.Debug|x86.ActiveCfg = Debug|Win32
{AD25497F-A15F-4DFF-AC7A-B8ABF5F411D6}.Debug|x86.Build.0 = Debug|Win32
{AD25497F-A15F-4DFF-AC7A-B8ABF5F411D6}.Release|Any CPU.ActiveCfg = Release|Win32
{AD25497F-A15F-4DFF-AC7A-B8ABF5F411D6}.Release|ARM.ActiveCfg = Release|ARM
{AD25497F-A15F-4DFF-AC7A-B8ABF5F411D6}.Release|ARM.Build.0 = Release|ARM
{AD25497F-A15F-4DFF-AC7A-B8ABF5F411D6}.Release|x86.ActiveCfg = Release|Win32
{AD25497F-A15F-4DFF-AC7A-B8ABF5F411D6}.Release|x86.Build.0 = Release|Win32
{3AE2A022-ED83-41F1-948A-12A7593CBD00}.Debug|Any CPU.ActiveCfg = Debug|Win32
{3AE2A022-ED83-41F1-948A-12A7593CBD00}.Debug|ARM.ActiveCfg = Debug|ARM
{3AE2A022-ED83-41F1-948A-12A7593CBD00}.Debug|ARM.Build.0 = Debug|ARM
{3AE2A022-ED83-41F1-948A-12A7593CBD00}.Debug|x86.ActiveCfg = Debug|Win32
{3AE2A022-ED83-41F1-948A-12A7593CBD00}.Debug|x86.Build.0 = Debug|Win32
{3AE2A022-ED83-41F1-948A-12A7593CBD00}.Release|Any CPU.ActiveCfg = Release|Win32
{3AE2A022-ED83-41F1-948A-12A7593CBD00}.Release|ARM.ActiveCfg = Release|ARM
{3AE2A022-ED83-41F1-948A-12A7593CBD00}.Release|ARM.Build.0 = Release|ARM
{3AE2A022-ED83-41F1-948A-12A7593CBD00}.Release|x86.ActiveCfg = Release|Win32
{3AE2A022-ED83-41F1-948A-12A7593CBD00}.Release|x86.Build.0 = Release|Win32
{18E0189B-F3F1-4CB2-A3AF-5606ADD5E279}.Debug|Any CPU.ActiveCfg = Debug|Win32
{18E0189B-F3F1-4CB2-A3AF-5606ADD5E279}.Debug|ARM.ActiveCfg = Debug|ARM
{18E0189B-F3F1-4CB2-A3AF-5606ADD5E279}.Debug|ARM.Build.0 = Debug|ARM
{18E0189B-F3F1-4CB2-A3AF-5606ADD5E279}.Debug|x86.ActiveCfg = Debug|Win32
{18E0189B-F3F1-4CB2-A3AF-5606ADD5E279}.Debug|x86.Build.0 = Debug|Win32
{18E0189B-F3F1-4CB2-A3AF-5606ADD5E279}.Release|Any CPU.ActiveCfg = Release|Win32
{18E0189B-F3F1-4CB2-A3AF-5606ADD5E279}.Release|ARM.ActiveCfg = Release|ARM
{18E0189B-F3F1-4CB2-A3AF-5606ADD5E279}.Release|ARM.Build.0 = Release|ARM
{18E0189B-F3F1-4CB2-A3AF-5606ADD5E279}.Release|x86.ActiveCfg = Release|Win32
{18E0189B-F3F1-4CB2-A3AF-5606ADD5E279}.Release|x86.Build.0 = Release|Win32
{7A05E943-6E0A-4F57-8BD7-BE90F44DCAD7}.Debug|Any CPU.ActiveCfg = Debug|Win32
{7A05E943-6E0A-4F57-8BD7-BE90F44DCAD7}.Debug|ARM.ActiveCfg = Debug|ARM
{7A05E943-6E0A-4F57-8BD7-BE90F44DCAD7}.Debug|ARM.Build.0 = Debug|ARM
{7A05E943-6E0A-4F57-8BD7-BE90F44DCAD7}.Debug|x86.ActiveCfg = Debug|Win32
{7A05E943-6E0A-4F57-8BD7-BE90F44DCAD7}.Debug|x86.Build.0 = Debug|Win32
{7A05E943-6E0A-4F57-8BD7-BE90F44DCAD7}.Release|Any CPU.ActiveCfg = Release|Win32
{7A05E943-6E0A-4F57-8BD7-BE90F44DCAD7}.Release|ARM.ActiveCfg = Release|ARM
{7A05E943-6E0A-4F57-8BD7-BE90F44DCAD7}.Release|ARM.Build.0 = Release|ARM
{7A05E943-6E0A-4F57-8BD7-BE90F44DCAD7}.Release|x86.ActiveCfg = Release|Win32
{7A05E943-6E0A-4F57-8BD7-BE90F44DCAD7}.Release|x86.Build.0 = Release|Win32
{33D91B58-1981-4A3C-B4D1-86EE406CDE12}.Debug|Any CPU.ActiveCfg = Debug|Win32
{33D91B58-1981-4A3C-B4D1-86EE406CDE12}.Debug|ARM.ActiveCfg = Debug|ARM
{33D91B58-1981-4A3C-B4D1-86EE406CDE12}.Debug|ARM.Build.0 = Debug|ARM
{33D91B58-1981-4A3C-B4D1-86EE406CDE12}.Debug|x86.ActiveCfg = Debug|Win32
{33D91B58-1981-4A3C-B4D1-86EE406CDE12}.Debug|x86.Build.0 = Debug|Win32
{33D91B58-1981-4A3C-B4D1-86EE406CDE12}.Release|Any CPU.ActiveCfg = Release|Win32
{33D91B58-1981-4A3C-B4D1-86EE406CDE12}.Release|ARM.ActiveCfg = Release|ARM
{33D91B58-1981-4A3C-B4D1-86EE406CDE12}.Release|ARM.Build.0 = Release|ARM
{33D91B58-1981-4A3C-B4D1-86EE406CDE12}.Release|x86.ActiveCfg = Release|Win32
{33D91B58-1981-4A3C-B4D1-86EE406CDE12}.Release|x86.Build.0 = Release|Win32
{512BF866-1AA0-4169-A7D6-D2776B5D731E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{512BF866-1AA0-4169-A7D6-D2776B5D731E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{512BF866-1AA0-4169-A7D6-D2776B5D731E}.Debug|ARM.ActiveCfg = Debug|Any CPU
{512BF866-1AA0-4169-A7D6-D2776B5D731E}.Debug|ARM.Build.0 = Debug|Any CPU
{512BF866-1AA0-4169-A7D6-D2776B5D731E}.Debug|x86.ActiveCfg = Debug|Any CPU
{512BF866-1AA0-4169-A7D6-D2776B5D731E}.Debug|x86.Build.0 = Debug|Any CPU
{512BF866-1AA0-4169-A7D6-D2776B5D731E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{512BF866-1AA0-4169-A7D6-D2776B5D731E}.Release|Any CPU.Build.0 = Release|Any CPU
{512BF866-1AA0-4169-A7D6-D2776B5D731E}.Release|ARM.ActiveCfg = Release|Any CPU
{512BF866-1AA0-4169-A7D6-D2776B5D731E}.Release|ARM.Build.0 = Release|Any CPU
{512BF866-1AA0-4169-A7D6-D2776B5D731E}.Release|x86.ActiveCfg = Release|Any CPU
{512BF866-1AA0-4169-A7D6-D2776B5D731E}.Release|x86.Build.0 = Release|Any CPU
{8E708D9A-6325-4AA9-B5A5-D1B5ECA8EEF7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8E708D9A-6325-4AA9-B5A5-D1B5ECA8EEF7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{512BF866-1AA0-4169-A7D6-D2776B5D731E}.Release|x86.ActiveCfg = Release|x86
{512BF866-1AA0-4169-A7D6-D2776B5D731E}.Release|x86.Build.0 = Release|x86
{8E708D9A-6325-4AA9-B5A5-D1B5ECA8EEF7}.Debug|ARM.ActiveCfg = Debug|Any CPU
{8E708D9A-6325-4AA9-B5A5-D1B5ECA8EEF7}.Debug|ARM.Build.0 = Debug|Any CPU
{8E708D9A-6325-4AA9-B5A5-D1B5ECA8EEF7}.Debug|x86.ActiveCfg = Debug|Any CPU
{8E708D9A-6325-4AA9-B5A5-D1B5ECA8EEF7}.Debug|x86.Build.0 = Debug|Any CPU
{8E708D9A-6325-4AA9-B5A5-D1B5ECA8EEF7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8E708D9A-6325-4AA9-B5A5-D1B5ECA8EEF7}.Release|Any CPU.Build.0 = Release|Any CPU
{8E708D9A-6325-4AA9-B5A5-D1B5ECA8EEF7}.Release|ARM.ActiveCfg = Release|Any CPU
{8E708D9A-6325-4AA9-B5A5-D1B5ECA8EEF7}.Release|ARM.Build.0 = Release|Any CPU
{8E708D9A-6325-4AA9-B5A5-D1B5ECA8EEF7}.Release|x86.ActiveCfg = Release|Any CPU
{8E708D9A-6325-4AA9-B5A5-D1B5ECA8EEF7}.Release|x86.Build.0 = Release|Any CPU
{BD681A4F-EB60-4BB8-90B5-65968FC7DA59}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BD681A4F-EB60-4BB8-90B5-65968FC7DA59}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8E708D9A-6325-4AA9-B5A5-D1B5ECA8EEF7}.Release|x86.ActiveCfg = Release|x86
{8E708D9A-6325-4AA9-B5A5-D1B5ECA8EEF7}.Release|x86.Build.0 = Release|x86
{BD681A4F-EB60-4BB8-90B5-65968FC7DA59}.Debug|ARM.ActiveCfg = Debug|Any CPU
{BD681A4F-EB60-4BB8-90B5-65968FC7DA59}.Debug|ARM.Build.0 = Debug|Any CPU
{BD681A4F-EB60-4BB8-90B5-65968FC7DA59}.Debug|x86.ActiveCfg = Debug|Any CPU
{BD681A4F-EB60-4BB8-90B5-65968FC7DA59}.Debug|x86.Build.0 = Debug|Any CPU
{BD681A4F-EB60-4BB8-90B5-65968FC7DA59}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BD681A4F-EB60-4BB8-90B5-65968FC7DA59}.Release|Any CPU.Build.0 = Release|Any CPU
{BD681A4F-EB60-4BB8-90B5-65968FC7DA59}.Release|ARM.ActiveCfg = Release|Any CPU
{BD681A4F-EB60-4BB8-90B5-65968FC7DA59}.Release|ARM.Build.0 = Release|Any CPU
{BD681A4F-EB60-4BB8-90B5-65968FC7DA59}.Release|x86.ActiveCfg = Release|Any CPU
{BD681A4F-EB60-4BB8-90B5-65968FC7DA59}.Release|x86.Build.0 = Release|Any CPU
{FFD3FD52-37A8-4F43-883C-DE8D996CB0E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FFD3FD52-37A8-4F43-883C-DE8D996CB0E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BD681A4F-EB60-4BB8-90B5-65968FC7DA59}.Release|x86.ActiveCfg = Release|x86
{BD681A4F-EB60-4BB8-90B5-65968FC7DA59}.Release|x86.Build.0 = Release|x86
{FFD3FD52-37A8-4F43-883C-DE8D996CB0E0}.Debug|ARM.ActiveCfg = Debug|Any CPU
{FFD3FD52-37A8-4F43-883C-DE8D996CB0E0}.Debug|ARM.Build.0 = Debug|Any CPU
{FFD3FD52-37A8-4F43-883C-DE8D996CB0E0}.Debug|x86.ActiveCfg = Debug|Any CPU
{FFD3FD52-37A8-4F43-883C-DE8D996CB0E0}.Debug|x86.Build.0 = Debug|Any CPU
{FFD3FD52-37A8-4F43-883C-DE8D996CB0E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FFD3FD52-37A8-4F43-883C-DE8D996CB0E0}.Release|Any CPU.Build.0 = Release|Any CPU
{FFD3FD52-37A8-4F43-883C-DE8D996CB0E0}.Release|ARM.ActiveCfg = Release|Any CPU
{FFD3FD52-37A8-4F43-883C-DE8D996CB0E0}.Release|ARM.Build.0 = Release|Any CPU
{FFD3FD52-37A8-4F43-883C-DE8D996CB0E0}.Release|x86.ActiveCfg = Release|Any CPU
{FFD3FD52-37A8-4F43-883C-DE8D996CB0E0}.Release|x86.Build.0 = Release|Any CPU
{3C2F5446-33F0-41D5-813A-64A94AA474AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3C2F5446-33F0-41D5-813A-64A94AA474AF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FFD3FD52-37A8-4F43-883C-DE8D996CB0E0}.Release|x86.ActiveCfg = Release|x86
{FFD3FD52-37A8-4F43-883C-DE8D996CB0E0}.Release|x86.Build.0 = Release|x86
{3C2F5446-33F0-41D5-813A-64A94AA474AF}.Debug|ARM.ActiveCfg = Debug|Any CPU
{3C2F5446-33F0-41D5-813A-64A94AA474AF}.Debug|ARM.Build.0 = Debug|Any CPU
{3C2F5446-33F0-41D5-813A-64A94AA474AF}.Debug|x86.ActiveCfg = Debug|Any CPU
{3C2F5446-33F0-41D5-813A-64A94AA474AF}.Debug|x86.Build.0 = Debug|Any CPU
{3C2F5446-33F0-41D5-813A-64A94AA474AF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3C2F5446-33F0-41D5-813A-64A94AA474AF}.Release|Any CPU.Build.0 = Release|Any CPU
{3C2F5446-33F0-41D5-813A-64A94AA474AF}.Release|ARM.ActiveCfg = Release|Any CPU
{3C2F5446-33F0-41D5-813A-64A94AA474AF}.Release|ARM.Build.0 = Release|Any CPU
{3C2F5446-33F0-41D5-813A-64A94AA474AF}.Release|x86.ActiveCfg = Release|Any CPU
{4EC16578-EFBF-41E6-8D7F-976E3646DD1D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4EC16578-EFBF-41E6-8D7F-976E3646DD1D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3C2F5446-33F0-41D5-813A-64A94AA474AF}.Release|x86.ActiveCfg = Release|x86
{3C2F5446-33F0-41D5-813A-64A94AA474AF}.Release|x86.Build.0 = Release|x86
{4EC16578-EFBF-41E6-8D7F-976E3646DD1D}.Debug|ARM.ActiveCfg = Debug|Any CPU
{4EC16578-EFBF-41E6-8D7F-976E3646DD1D}.Debug|ARM.Build.0 = Debug|Any CPU
{4EC16578-EFBF-41E6-8D7F-976E3646DD1D}.Debug|x86.ActiveCfg = Debug|Any CPU
{4EC16578-EFBF-41E6-8D7F-976E3646DD1D}.Debug|x86.Build.0 = Debug|Any CPU
{4EC16578-EFBF-41E6-8D7F-976E3646DD1D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4EC16578-EFBF-41E6-8D7F-976E3646DD1D}.Release|Any CPU.Build.0 = Release|Any CPU
{4EC16578-EFBF-41E6-8D7F-976E3646DD1D}.Release|ARM.ActiveCfg = Release|Any CPU
{4EC16578-EFBF-41E6-8D7F-976E3646DD1D}.Release|ARM.Build.0 = Release|Any CPU
{4EC16578-EFBF-41E6-8D7F-976E3646DD1D}.Release|x86.ActiveCfg = Release|Any CPU
{4EC16578-EFBF-41E6-8D7F-976E3646DD1D}.Release|x86.Build.0 = Release|Any CPU
{DC074727-72E4-43C5-BAAF-E0D548104797}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DC074727-72E4-43C5-BAAF-E0D548104797}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4EC16578-EFBF-41E6-8D7F-976E3646DD1D}.Release|x86.ActiveCfg = Release|x86
{4EC16578-EFBF-41E6-8D7F-976E3646DD1D}.Release|x86.Build.0 = Release|x86
{DC074727-72E4-43C5-BAAF-E0D548104797}.Debug|ARM.ActiveCfg = Debug|Any CPU
{DC074727-72E4-43C5-BAAF-E0D548104797}.Debug|ARM.Build.0 = Debug|Any CPU
{DC074727-72E4-43C5-BAAF-E0D548104797}.Debug|x86.ActiveCfg = Debug|x86
{DC074727-72E4-43C5-BAAF-E0D548104797}.Debug|x86.Build.0 = Debug|x86
{DC074727-72E4-43C5-BAAF-E0D548104797}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DC074727-72E4-43C5-BAAF-E0D548104797}.Release|Any CPU.Build.0 = Release|Any CPU
{DC074727-72E4-43C5-BAAF-E0D548104797}.Release|ARM.ActiveCfg = Release|Any CPU
{DC074727-72E4-43C5-BAAF-E0D548104797}.Release|ARM.Build.0 = Release|Any CPU
{DC074727-72E4-43C5-BAAF-E0D548104797}.Release|x86.ActiveCfg = Release|x86
{DC074727-72E4-43C5-BAAF-E0D548104797}.Release|x86.Build.0 = Release|x86
{E4CA78A9-9408-4F5F-ADD6-730FD501FF8E}.Debug|Any CPU.ActiveCfg = Debug|Win32
{E4CA78A9-9408-4F5F-ADD6-730FD501FF8E}.Debug|ARM.ActiveCfg = Debug|ARM
{E4CA78A9-9408-4F5F-ADD6-730FD501FF8E}.Debug|ARM.Build.0 = Debug|ARM
{E4CA78A9-9408-4F5F-ADD6-730FD501FF8E}.Debug|x86.ActiveCfg = Debug|Win32
{E4CA78A9-9408-4F5F-ADD6-730FD501FF8E}.Debug|x86.Build.0 = Debug|Win32
{E4CA78A9-9408-4F5F-ADD6-730FD501FF8E}.Release|Any CPU.ActiveCfg = Release|Win32
{E4CA78A9-9408-4F5F-ADD6-730FD501FF8E}.Release|ARM.ActiveCfg = Release|ARM
{E4CA78A9-9408-4F5F-ADD6-730FD501FF8E}.Release|ARM.Build.0 = Release|ARM
{E4CA78A9-9408-4F5F-ADD6-730FD501FF8E}.Release|x86.ActiveCfg = Release|Win32
{E4CA78A9-9408-4F5F-ADD6-730FD501FF8E}.Release|x86.Build.0 = Release|Win32
{C5587B6E-19C4-4484-AA97-5C20FBB07E43}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C5587B6E-19C4-4484-AA97-5C20FBB07E43}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C5587B6E-19C4-4484-AA97-5C20FBB07E43}.Debug|ARM.ActiveCfg = Debug|Any CPU
{C5587B6E-19C4-4484-AA97-5C20FBB07E43}.Debug|ARM.Build.0 = Debug|Any CPU
{C5587B6E-19C4-4484-AA97-5C20FBB07E43}.Debug|x86.ActiveCfg = Debug|Any CPU
{C5587B6E-19C4-4484-AA97-5C20FBB07E43}.Debug|x86.Build.0 = Debug|Any CPU
{C5587B6E-19C4-4484-AA97-5C20FBB07E43}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C5587B6E-19C4-4484-AA97-5C20FBB07E43}.Release|Any CPU.Build.0 = Release|Any CPU
{C5587B6E-19C4-4484-AA97-5C20FBB07E43}.Release|ARM.ActiveCfg = Release|Any CPU
{C5587B6E-19C4-4484-AA97-5C20FBB07E43}.Release|ARM.Build.0 = Release|Any CPU
{C5587B6E-19C4-4484-AA97-5C20FBB07E43}.Release|x86.ActiveCfg = Release|Any CPU
{C5587B6E-19C4-4484-AA97-5C20FBB07E43}.Release|x86.Build.0 = Release|Any CPU
{F0288B24-7B84-42A5-9A92-2E16A012E4DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F0288B24-7B84-42A5-9A92-2E16A012E4DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C5587B6E-19C4-4484-AA97-5C20FBB07E43}.Release|x86.ActiveCfg = Release|x86
{C5587B6E-19C4-4484-AA97-5C20FBB07E43}.Release|x86.Build.0 = Release|x86
{F0288B24-7B84-42A5-9A92-2E16A012E4DE}.Debug|ARM.ActiveCfg = Debug|Any CPU
{F0288B24-7B84-42A5-9A92-2E16A012E4DE}.Debug|ARM.Build.0 = Debug|Any CPU
{F0288B24-7B84-42A5-9A92-2E16A012E4DE}.Debug|x86.ActiveCfg = Debug|Any CPU
{F0288B24-7B84-42A5-9A92-2E16A012E4DE}.Debug|x86.Build.0 = Debug|Any CPU
{F0288B24-7B84-42A5-9A92-2E16A012E4DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F0288B24-7B84-42A5-9A92-2E16A012E4DE}.Release|Any CPU.Build.0 = Release|Any CPU
{F0288B24-7B84-42A5-9A92-2E16A012E4DE}.Debug|x86.ActiveCfg = Debug|x86
{F0288B24-7B84-42A5-9A92-2E16A012E4DE}.Debug|x86.Build.0 = Debug|x86
{F0288B24-7B84-42A5-9A92-2E16A012E4DE}.Release|ARM.ActiveCfg = Release|Any CPU
{F0288B24-7B84-42A5-9A92-2E16A012E4DE}.Release|ARM.Build.0 = Release|Any CPU
{F0288B24-7B84-42A5-9A92-2E16A012E4DE}.Release|x86.ActiveCfg = Release|Any CPU
{F0288B24-7B84-42A5-9A92-2E16A012E4DE}.Release|x86.Build.0 = Release|Any CPU
{26B3C19D-6182-4DB5-8B69-EE098A0FD3BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{26B3C19D-6182-4DB5-8B69-EE098A0FD3BB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F0288B24-7B84-42A5-9A92-2E16A012E4DE}.Release|x86.ActiveCfg = Release|x86
{F0288B24-7B84-42A5-9A92-2E16A012E4DE}.Release|x86.Build.0 = Release|x86
{26B3C19D-6182-4DB5-8B69-EE098A0FD3BB}.Debug|ARM.ActiveCfg = Debug|Any CPU
{26B3C19D-6182-4DB5-8B69-EE098A0FD3BB}.Debug|ARM.Build.0 = Debug|Any CPU
{26B3C19D-6182-4DB5-8B69-EE098A0FD3BB}.Debug|x86.ActiveCfg = Debug|x86
{26B3C19D-6182-4DB5-8B69-EE098A0FD3BB}.Debug|x86.Build.0 = Debug|x86
{26B3C19D-6182-4DB5-8B69-EE098A0FD3BB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{26B3C19D-6182-4DB5-8B69-EE098A0FD3BB}.Release|Any CPU.Build.0 = Release|Any CPU
{26B3C19D-6182-4DB5-8B69-EE098A0FD3BB}.Release|ARM.ActiveCfg = Release|Any CPU
{26B3C19D-6182-4DB5-8B69-EE098A0FD3BB}.Release|ARM.Build.0 = Release|Any CPU
{26B3C19D-6182-4DB5-8B69-EE098A0FD3BB}.Release|x86.ActiveCfg = Release|x86
{26B3C19D-6182-4DB5-8B69-EE098A0FD3BB}.Release|x86.Build.0 = Release|x86
{B1DF139F-CEF1-404F-8255-31EF4BF0EC4C}.Debug|Any CPU.ActiveCfg = Debug|Win32
{B1DF139F-CEF1-404F-8255-31EF4BF0EC4C}.Debug|ARM.ActiveCfg = Debug|ARM
{B1DF139F-CEF1-404F-8255-31EF4BF0EC4C}.Debug|ARM.Build.0 = Debug|ARM
{B1DF139F-CEF1-404F-8255-31EF4BF0EC4C}.Debug|x86.ActiveCfg = Debug|Win32
{B1DF139F-CEF1-404F-8255-31EF4BF0EC4C}.Debug|x86.Build.0 = Debug|Win32
{B1DF139F-CEF1-404F-8255-31EF4BF0EC4C}.Release|Any CPU.ActiveCfg = Release|Win32
{B1DF139F-CEF1-404F-8255-31EF4BF0EC4C}.Release|ARM.ActiveCfg = Release|ARM
{B1DF139F-CEF1-404F-8255-31EF4BF0EC4C}.Release|ARM.Build.0 = Release|ARM
{B1DF139F-CEF1-404F-8255-31EF4BF0EC4C}.Release|x86.ActiveCfg = Release|Win32
{B1DF139F-CEF1-404F-8255-31EF4BF0EC4C}.Release|x86.Build.0 = Release|Win32
{8D333AF6-E901-4301-B3EE-923088E81062}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8D333AF6-E901-4301-B3EE-923088E81062}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8D333AF6-E901-4301-B3EE-923088E81062}.Debug|ARM.ActiveCfg = Debug|Any CPU
{8D333AF6-E901-4301-B3EE-923088E81062}.Debug|ARM.Build.0 = Debug|Any CPU
{8D333AF6-E901-4301-B3EE-923088E81062}.Debug|x86.ActiveCfg = Debug|x86
{8D333AF6-E901-4301-B3EE-923088E81062}.Debug|x86.Build.0 = Debug|x86
{8D333AF6-E901-4301-B3EE-923088E81062}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8D333AF6-E901-4301-B3EE-923088E81062}.Release|Any CPU.Build.0 = Release|Any CPU
{8D333AF6-E901-4301-B3EE-923088E81062}.Release|ARM.ActiveCfg = Release|Any CPU
{8D333AF6-E901-4301-B3EE-923088E81062}.Release|ARM.Build.0 = Release|Any CPU
{8D333AF6-E901-4301-B3EE-923088E81062}.Release|x86.ActiveCfg = Release|x86

View File

@@ -178,6 +178,7 @@ namespace AppxPackage
}
public string Publisher { get { return StringValue (1); } }
public string ResourceId { get { return StringValue (4); } }
public string PublisherId => PublisherIdHelper.GetPublisherId (Publisher);
public DataUtils.Version Version
{
get
@@ -197,7 +198,9 @@ namespace AppxPackage
publisher = Publisher,
resource_id = ResourceId,
architecture = ProcessArchitecture.Select (e => (int)e).ToList (),
version = Version.BuildJSON ()
version = Version.BuildJSON (),
publisher_id = PublisherId,
_publisher_id = "Note: The publisher id obtained may be inaccurate."
};
}
}
@@ -348,8 +351,18 @@ namespace AppxPackage
{
get
{
string value;
if (!TryGetValue (key, out value))
string value = null;
var isfind = false;
foreach (var kv in this)
{
if (kv.Key?.Trim ()?.ToLowerInvariant () == key?.Trim ()?.ToLowerInvariant ())
{
value = kv.Value;
isfind = true;
break;
}
}
if (!isfind)
{
value = string.Empty;
base [key] = value;
@@ -370,8 +383,18 @@ namespace AppxPackage
}
public string At (string key)
{
string value;
if (!TryGetValue (key, out value)) throw new KeyNotFoundException ($"PRBaseApplication.At: key \"{key}\" not found");
string value = null;
var isfind = false;
foreach (var kv in this)
{
if (kv.Key?.Trim ()?.ToLowerInvariant () == key?.Trim ()?.ToLowerInvariant ())
{
value = kv.Value;
isfind = true;
break;
}
}
if (!isfind) throw new KeyNotFoundException ($"MRApplication: cannot find key \"{key}\"");
if (!EnablePri ()) return value;
if (PriFileHelper.IsMsResourcePrefix (value))
{
@@ -383,8 +406,18 @@ namespace AppxPackage
}
public string NewAt (string key, bool toPriString)
{
string value;
if (!TryGetValue (key, out value))
string value = null;
var isfind = false;
foreach (var kv in this)
{
if (kv.Key?.Trim ()?.ToLowerInvariant () == key?.Trim ()?.ToLowerInvariant ())
{
value = kv.Value;
isfind = true;
break;
}
}
if (!isfind)
{
value = string.Empty;
base [key] = value;

View File

@@ -13,6 +13,7 @@ using ICSharpCode.SharpZipLib;
using System.IO;
using System.Xml;
using ICSharpCode.SharpZipLib.Zip;
using System.Security.Cryptography;
//using PriFormat;
namespace AppxPackage
{
@@ -108,6 +109,47 @@ namespace AppxPackage
return ret;
}
}
[ComVisible (true)]
internal static class PublisherIdHelper
{
// Base32 编码表 (Crockford 变体,去掉 I L O U 避免混淆)
private const string Base32Chars = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
/// <summary>
/// 从证书的可分辨名称 (Distinguished Name) 计算出对应的 Publisher ID。
/// </summary>
/// <param name="distinguishedName">
/// 证书 DN 字符串,例如 "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US"
/// </param>
/// <returns>13 位小写字母数字组成的 Publisher ID</returns>
/// <exception cref="ArgumentNullException">distinguishedName 为 null 时抛出</exception>
public static string GetPublisherId (string distinguishedName)
{
if (distinguishedName == null)
throw new ArgumentNullException (nameof (distinguishedName));
byte [] dnBytes = Encoding.Unicode.GetBytes (distinguishedName);
byte [] hash;
using (var sha256 = SHA256.Create ())
{
hash = sha256.ComputeHash (dnBytes);
}
byte [] first8Bytes = new byte [8];
Array.Copy (hash, 0, first8Bytes, 0, 8);
var binaryBuilder = new StringBuilder (64);
for (int i = 0; i < first8Bytes.Length; i++)
{
binaryBuilder.Append (Convert.ToString (first8Bytes [i], 2).PadLeft (8, '0'));
}
string binaryString = binaryBuilder.ToString ().PadRight (65, '0');
var resultBuilder = new StringBuilder (13);
for (int i = 0; i < 65; i += 5)
{
string fiveBits = binaryString.Substring (i, 5);
int index = Convert.ToInt32 (fiveBits, 2);
resultBuilder.Append (Base32Chars [index]);
}
return resultBuilder.ToString ().ToLowerInvariant ();
}
}
internal class PriAllValuesReader: IDisposable
{
public PackageReader pr = null;
@@ -491,6 +533,7 @@ namespace AppxPackage
}
public string Publisher { get { return StringValue (1); } }
public string ResourceId { get { return StringValue (4); } }
public string PublisherId => PublisherIdHelper.GetPublisherId (Publisher);
public DataUtils.Version Version
{
get
@@ -519,7 +562,9 @@ namespace AppxPackage
resource_id = ResourceId,
architecture = ProcessArchitecture.Select (e => (int)e).ToList (),
version = Version.BuildJSON (),
realver = RealVersion.BuildJSON ()
realver = RealVersion.BuildJSON (),
publisher_id = PublisherId,
_publisher_id = "Note: The publisher id obtained may be inaccurate."
};
}
}
@@ -741,8 +786,18 @@ namespace AppxPackage
{
get
{
string value;
if (!TryGetValue (key, out value))
string value = null;
var isfind = false;
foreach (var kv in this)
{
if (kv.Key?.Trim ()?.ToLowerInvariant () == key?.Trim ()?.ToLowerInvariant ())
{
value = kv.Value;
isfind = true;
break;
}
}
if (!isfind)
{
value = string.Empty;
base [key] = value;
@@ -763,8 +818,18 @@ namespace AppxPackage
}
public string At (string key)
{
string value;
if (!TryGetValue (key, out value)) throw new KeyNotFoundException ($"PRBaseApplication.At: key \"{key}\" not found");
string value = null;
var isfind = false;
foreach (var kv in this)
{
if (kv.Key?.Trim ()?.ToLowerInvariant () == key?.Trim ()?.ToLowerInvariant ())
{
value = kv.Value;
isfind = true;
break;
}
}
if (!isfind) throw new KeyNotFoundException ($"MRApplication: cannot find key \"{key}\"");
if (!EnablePri ()) return value;
if (PriFileHelper.IsMsResourcePrefix (value))
{
@@ -776,8 +841,18 @@ namespace AppxPackage
}
public string NewAt (string key, bool toPriString)
{
string value;
if (!TryGetValue (key, out value))
string value = null;
var isfind = false;
foreach (var kv in this)
{
if (kv.Key?.Trim ()?.ToLowerInvariant () == key?.Trim ()?.ToLowerInvariant ())
{
value = kv.Value;
isfind = true;
break;
}
}
if (!isfind)
{
value = string.Empty;
base [key] = value;
@@ -1780,6 +1855,759 @@ namespace AppxPackage
UsePri = parsePri;
}
}
public bool SaveJsonFileCS (string savefilepath)
{
try
{
#region
using (var fs = File.Create (savefilepath))
{
using (var zos = new ZipOutputStream (fs))
{
zos.SetLevel (9);
bool parsePri = UsePri;
bool usePri = EnablePri;
try
{
UsePri = false;
EnablePri = false;
object packageInfo = null;
#region file
var typestr = "unknown";
switch (Type)
{
case PackageType.Appx: typestr = "appx"; break;
case PackageType.Bundle: typestr = "bundle"; break;
default:
case PackageType.Unknown: typestr = "unknown"; break;
}
var rolestr = "unknown";
switch (Role)
{
case PackageRole.Application: rolestr = "application"; break;
case PackageRole.Framework: rolestr = "framework"; break;
case PackageRole.Resource: rolestr = "resource"; break;
default:
case PackageRole.Unknown: rolestr = "unknown"; break;
}
var pkgfile = new {
path = FilePath,
valid = IsValid,
type = typestr,
role = rolestr
};
#endregion
#region id
var id = Identity;
var pkgid = new {
name = id.Name,
publisher = id.Publisher,
version = id.Version.ToString (),
realVersion = id.RealVersion.ToString (),
architecture = id.ProcessArchitecture.Select (e => {
switch (e)
{
case Architecture.ARM: return "arm";
case Architecture.ARM64: return "arm64";
case Architecture.Neutral: return "neutral";
case Architecture.x64: return "x64";
case Architecture.x86: return "x86";
default:
case Architecture.Unknown: return "unknown";
}
}).ToList (),
familyName = id.FamilyName,
fullName = id.FullName,
resourceId = id.ResourceId,
publisherId = id.PublisherId,
_publisherId = "Note: The publisher id obtained may be inaccurate."
};
#endregion
#region prerequistes
var preq = Prerequisites;
var pkgpreq = new {
osMinVersion = preq.OSMinVersion.ToString (),
osMaxVersionTested = preq.OSMaxVersionTested.ToString (),
osMinVersionDescription = preq.OSMinVersionDescription,
osMaxVersionTestedDescription = preq.OSMaxVersionDescription
};
#endregion
#region resources
var res = Resources;
var pkgres = new {
languages = res.Languages,
scales = res.Scales,
dxFeatureLevels = res.DXFeatures.Select (d => {
switch (d)
{
case DXFeatureLevel.Level9: return 9;
case DXFeatureLevel.Level10: return 10;
case DXFeatureLevel.Level11: return 11;
case DXFeatureLevel.Level12: return 12;
default:
case DXFeatureLevel.Unspecified: return -1;
}
}).ToList ()
};
#endregion
#region capabilities
var caps = Capabilities;
var pkgcaps = new {
capabilities = caps.Capabilities,
deviceCapabilities = caps.DeviceCapabilities
};
#endregion
#region dependencies
var deps = Dependencies;
var pkgdeps = Dependencies.Select (d => new {
name = d.Name,
publisher = d.Publisher,
minVersion = d.Version.ToString ()
}).ToList ();
#endregion
using (var priAllRes = new PriAllValuesReader (this))
{
priAllRes.Init ();
#region prop
var prop = Properties;
var dispname = prop.DisplayName;
var dispNameDict = new Dictionary<string, string> ();
if (PriFileHelper.IsMsResourcePrefix (dispname))
dispNameDict = priAllRes.LocaleResourceAllValues (dispname);
dispNameDict ["root"] = dispname;
var desc = prop.Description;
var descDict = new Dictionary<string, string> ();
if (PriFileHelper.IsMsResourcePrefix (desc))
descDict = priAllRes.LocaleResourceAllValues (desc);
descDict ["root"] = desc;
var disppub = prop.Publisher;
var dispPubDict = new Dictionary<string, string> ();
if (PriFileHelper.IsMsResourcePrefix (disppub))
dispPubDict = priAllRes.LocaleResourceAllValues (disppub);
dispPubDict ["root"] = disppub;
var logoList = priAllRes.FileResourceAllValues (prop.Logo, zos)
.Select (kv => {
string contrast = "";
switch (kv.Key.Contrast)
{
case PriResourceKey.PriContrast.None: contrast = ""; break;
case PriResourceKey.PriContrast.Black: contrast = "black"; break;
case PriResourceKey.PriContrast.White: contrast = "white"; break;
case PriResourceKey.PriContrast.High: contrast = "high"; break;
case PriResourceKey.PriContrast.Low: contrast = "low"; break;
}
if (kv.Key.IsTargetSize)
{
return new {
targetSize = kv.Key.Value,
contrast = contrast,
name = kv.Value
};
}
else if (kv.Key.IsScale)
{
return new {
scale = kv.Key.Value,
contrast = contrast,
name = kv.Value
};
}
else if (kv.Key.IsString)
{
return new {
language = kv.Key.Value,
name = kv.Value
};
}
else
{
return (dynamic)null; // 不满足条件时返回 null
}
})
.Where (item => item != null) // 过滤掉 null
.ToList ();
var pkgprop = new {
displayName = dispNameDict,
publisherDisplayName = dispPubDict,
description = descDict,
logo = logoList,
framework = prop.Framework,
resourcePackage = prop.ResourcePackage
};
#endregion
#region apps
var apps = Applications;
var pkgapps = new List<object> ();
foreach (var app in apps)
{
dynamic obj = new ExpandoObject ();
var dict = (IDictionary<string, object>)obj;
foreach (var kv in app)
{
if (Utils.AppFileProperties.Contains (kv.Key, StringComparer.OrdinalIgnoreCase))
{
dict [Utils.PascalToCamel (kv.Key)] = priAllRes.FileResourceAllValues (kv.Value, zos)
.Select (skv => {
string contrast = "";
switch (skv.Key.Contrast)
{
case PriResourceKey.PriContrast.None: contrast = ""; break;
case PriResourceKey.PriContrast.Black: contrast = "black"; break;
case PriResourceKey.PriContrast.White: contrast = "white"; break;
case PriResourceKey.PriContrast.High: contrast = "high"; break;
case PriResourceKey.PriContrast.Low: contrast = "low"; break;
}
if (skv.Key.IsTargetSize)
{
return new {
targetSize = skv.Key.Value,
contrast = contrast,
name = skv.Value
};
}
else if (skv.Key.IsScale)
{
return new {
scale = skv.Key.Value,
contrast = contrast,
name = skv.Value
};
}
else if (skv.Key.IsString)
{
return new {
language = skv.Key.Value,
name = skv.Value
};
}
else
{
return (dynamic)null; // 不满足条件时返回 null
}
}).Where (item => item != null).ToList ();
}
else
{
if (PriFileHelper.IsMsResourcePrefix (kv.Value))
{
var itemDict = new Dictionary<string, string> ();
itemDict = priAllRes.LocaleResourceAllValues (kv.Value);
itemDict ["root"] = kv.Value;
dict [Utils.PascalToCamel (kv.Key)] = itemDict;
}
else
{
dict [Utils.PascalToCamel (kv.Key)] = kv.Value;
}
}
}
pkgapps.Add (obj);
}
#endregion
packageInfo = new {
file = pkgfile,
identity = pkgid,
properties = pkgprop,
resources = pkgres,
prerequisites = pkgpreq,
applications = pkgapps,
capabilities = pkgcaps,
dependencies = pkgdeps
};
}
var jsonstr = Newtonsoft.Json.JsonConvert.SerializeObject (packageInfo, Newtonsoft.Json.Formatting.None);
var ze = new ZipEntry ("info.json");
ze.DateTime = DateTime.Now;
zos.PutNextEntry (ze);
var bytes = Encoding.UTF8.GetBytes (jsonstr);
zos.Write (bytes, 0, bytes.Length);
zos.CloseEntry ();
return true;
}
finally
{
EnablePri = usePri;
UsePri = parsePri;
}
}
}
#endregion
}
catch (Exception ex)
{
throw ex;
return false;
}
}
public bool SaveXmlFileCS (string savefilepath)
{
try
{
#region
using (var fs = File.Create (savefilepath))
{
using (var zos = new ZipOutputStream (fs))
{
zos.SetLevel (9);
bool parsePri = UsePri;
bool usePri = EnablePri;
try
{
UsePri = false;
EnablePri = false;
var xml = new XmlDocument ();
var decl = xml.CreateXmlDeclaration ("1.0", "utf-8", "yes");
xml.AppendChild (decl);
var root = xml.CreateElement ("Package");
xml.AppendChild (root);
#region file
var typestr = "unknown";
switch (Type)
{
case PackageType.Appx: typestr = "appx"; break;
case PackageType.Bundle: typestr = "bundle"; break;
default:
case PackageType.Unknown: typestr = "unknown"; break;
}
var rolestr = "unknown";
switch (Role)
{
case PackageRole.Application: rolestr = "application"; break;
case PackageRole.Framework: rolestr = "framework"; break;
case PackageRole.Resource: rolestr = "resource"; break;
default:
case PackageRole.Unknown: rolestr = "unknown"; break;
}
{
var nodefile = xml.CreateElement ("File");
var nodefilepath = xml.CreateElement ("Path");
nodefilepath.InnerText = FilePath;
var nodefilevalid = xml.CreateElement ("Valid");
nodefilevalid.InnerText = IsValid ? "true" : "false";
var nodefiletype = xml.CreateElement ("Type");
nodefiletype.InnerText = typestr;
var nodefilerole = xml.CreateElement ("Role");
nodefilerole.InnerText = rolestr;
nodefile.AppendChild (nodefilepath);
nodefile.AppendChild (nodefilevalid);
nodefile.AppendChild (nodefiletype);
nodefile.AppendChild (nodefilerole);
root.AppendChild (nodefile);
}
#endregion
#region id
var id = Identity;
{
var nodeid = xml.CreateElement ("Identity");
var nodeidname = xml.CreateElement ("Name");
nodeidname.InnerText = id.Name;
var nodeidpub = xml.CreateElement ("Publisher");
nodeidpub.InnerText = id.Publisher;
var nodeidver = xml.CreateElement ("Version");
nodeidver.InnerText = id.Version.ToString ();
var nodeidrealver = xml.CreateElement ("RealVersion");
nodeidrealver.InnerText = id.RealVersion.ToString ();
var nodeidarchs = xml.CreateElement ("ProcessorArchitectures");
foreach (var a in id.ProcessArchitecture)
{
var astr = "";
switch (a)
{
case Architecture.ARM: astr = "arm"; break;
case Architecture.ARM64: astr = "arm64"; break;
case Architecture.Neutral: astr = "neutral"; break;
case Architecture.x64: astr = "x64"; break;
case Architecture.x86: astr = "x86"; break;
default:
case Architecture.Unknown: astr = "unknown"; break;
}
var nodeidarch = xml.CreateElement ("ProcessorArchitecture");
nodeidarch.SetAttribute ("Value", astr);
nodeidarchs.AppendChild (nodeidarch);
}
var nodeidfamily = xml.CreateElement ("FamilyName");
nodeidfamily.InnerText = id.FamilyName;
var nodeidfull = xml.CreateElement ("FullName");
nodeidfull.InnerText = id.FullName;
var nodeidresid = xml.CreateElement ("ResourceId");
nodeidresid.InnerText = id.ResourceId;
nodeid.AppendChild (nodeidname);
nodeid.AppendChild (nodeidpub);
nodeid.AppendChild (nodeidver);
nodeid.AppendChild (nodeidrealver);
nodeid.AppendChild (nodeidarchs);
nodeid.AppendChild (nodeidfamily);
nodeid.AppendChild (nodeidfamily);
nodeid.AppendChild (nodeidresid);
var nodeidpublid = xml.CreateElement ("PublisherId");
nodeidpublid.InnerText = id.PublisherId;
nodeidpublid.SetAttribute ("Description", "Note: The publisher id obtained may be inaccurate.");
nodeid.AppendChild (nodeidpublid);
root.AppendChild (nodeid);
}
#endregion
using (var priAllRes = new PriAllValuesReader (this))
{
priAllRes.Init ();
#region prop
var prop = Properties;
var dispname = prop.DisplayName;
var dispNameDict = new Dictionary<string, string> ();
if (PriFileHelper.IsMsResourcePrefix (dispname))
dispNameDict = priAllRes.LocaleResourceAllValues (dispname);
dispNameDict ["root"] = dispname;
var desc = prop.Description;
var descDict = new Dictionary<string, string> ();
if (PriFileHelper.IsMsResourcePrefix (desc))
descDict = priAllRes.LocaleResourceAllValues (desc);
descDict ["root"] = desc;
var disppub = prop.Publisher;
var dispPubDict = new Dictionary<string, string> ();
if (PriFileHelper.IsMsResourcePrefix (disppub))
dispPubDict = priAllRes.LocaleResourceAllValues (disppub);
dispPubDict ["root"] = disppub;
{
var nodeprop = xml.CreateElement ("Properties");
var nodepropname = xml.CreateElement ("DisplayName");
foreach (var kv in dispNameDict)
{
var nodelocale = xml.CreateElement ("LocaleResource");
nodelocale.SetAttribute ("Lang", kv.Key);
nodelocale.InnerText = kv.Value;
nodepropname.AppendChild (nodelocale);
}
var nodeproppub = xml.CreateElement ("PublisherDisplayName");
foreach (var kv in dispPubDict)
{
var nodelocale = xml.CreateElement ("LocaleResource");
nodelocale.SetAttribute ("Lang", kv.Key);
nodelocale.InnerText = kv.Value;
nodeproppub.AppendChild (nodelocale);
}
var nodepropdesc = xml.CreateElement ("Description");
foreach (var kv in descDict)
{
var nodelocale = xml.CreateElement ("LocaleResource");
nodelocale.SetAttribute ("Lang", kv.Key);
nodelocale.InnerText = kv.Value;
nodepropdesc.AppendChild (nodelocale);
}
var nodeproplogo = xml.CreateElement ("Logo");
foreach (var kv in priAllRes.FileResourceAllValues (prop.Logo, zos))
{
#region logo
var key = kv.Key;
var value = kv.Value;
var nodefile = xml.CreateElement ("File");
var attrName = xml.CreateAttribute ("Name");
attrName.Value = value;
nodefile.Attributes.Append (attrName);
if (key.Contrast != PriResourceKey.PriContrast.None)
{
string contrast = "";
switch (key.Contrast)
{
case PriResourceKey.PriContrast.Black: contrast = "black"; break;
case PriResourceKey.PriContrast.White: contrast = "white"; break;
case PriResourceKey.PriContrast.High: contrast = "high"; break;
case PriResourceKey.PriContrast.Low: contrast = "low"; break;
}
var attrContrast = xml.CreateAttribute ("Contrast");
attrContrast.Value = contrast;
nodefile.Attributes.Append (attrContrast);
}
if (key.IsTargetSize)
{
var attr = xml.CreateAttribute ("TargetSize");
attr.Value = key.Value.ToString ();
nodefile.Attributes.Append (attr);
}
else if (key.IsScale)
{
var attr = xml.CreateAttribute ("Scale");
attr.Value = key.Value.ToString ();
nodefile.Attributes.Append (attr);
}
else if (key.IsString)
{
var attr = xml.CreateAttribute ("Language");
attr.Value = key.Value.ToString ();
nodefile.Attributes.Append (attr);
}
nodeproplogo.AppendChild (nodefile);
#endregion
}
var nodepropfrw = xml.CreateElement ("Framework");
nodepropfrw.InnerText = prop.Framework ? "true" : "false";
var nodepropres = xml.CreateElement ("ResourcePackage");
nodepropres.InnerText = prop.ResourcePackage ? "true" : "false";
nodeprop.AppendChild (nodepropname);
nodeprop.AppendChild (nodeproppub);
nodeprop.AppendChild (nodepropdesc);
nodeprop.AppendChild (nodeproplogo);
nodeprop.AppendChild (nodepropfrw);
nodeprop.AppendChild (nodepropres);
root.AppendChild (nodeprop);
}
#endregion
#region apps
// Applications 节点
XmlElement nodeApplications = xml.CreateElement ("Applications");
foreach (var app in Applications)
{
XmlElement nodeApp = xml.CreateElement ("Application");
// AppUserModelId 作为属性
string aumidObj = app ["AppUserModelId"];
if (aumidObj == null || aumidObj.Trim ().Length == 0) aumidObj = app ["AppUserModelID"];
nodeApp.SetAttribute ("AppUserModelId", aumidObj);
foreach (var kv in app)
{
string key = kv.Key;
string value = kv.Value;
// 跳过 AppUserModelId因为已经作为属性
if (string.Equals (key, "AppUserModelId", StringComparison.OrdinalIgnoreCase))
continue;
XmlElement nodeProp = xml.CreateElement (key);
// 文件资源类型
if (Utils.AppFileProperties.Contains (key, StringComparer.OrdinalIgnoreCase))
{
foreach (var skv in priAllRes.FileResourceAllValues (value, zos))
{
var fileKey = skv.Key;
var fileValue = skv.Value;
XmlElement nodeFile = xml.CreateElement ("File");
// Name 必有
XmlAttribute attrName = xml.CreateAttribute ("Name");
attrName.Value = fileValue;
nodeFile.Attributes.Append (attrName);
// Contrast 可选
if (fileKey.Contrast != PriResourceKey.PriContrast.None)
{
string contrast = "";
switch (fileKey.Contrast)
{
case PriResourceKey.PriContrast.Black: contrast = "black"; break;
case PriResourceKey.PriContrast.White: contrast = "white"; break;
case PriResourceKey.PriContrast.High: contrast = "high"; break;
case PriResourceKey.PriContrast.Low: contrast = "low"; break;
}
if (!string.IsNullOrEmpty (contrast))
{
XmlAttribute attrContrast = xml.CreateAttribute ("Contrast");
attrContrast.Value = contrast;
nodeFile.Attributes.Append (attrContrast);
}
}
// TargetSize
if (fileKey.IsTargetSize)
{
XmlAttribute attrTS = xml.CreateAttribute ("TargetSize");
attrTS.Value = fileKey.Value.ToString ();
nodeFile.Attributes.Append (attrTS);
}
// Scale
else if (fileKey.IsScale)
{
XmlAttribute attrS = xml.CreateAttribute ("Scale");
attrS.Value = fileKey.Value.ToString ();
nodeFile.Attributes.Append (attrS);
}
// Language
else if (fileKey.IsString)
{
XmlAttribute attrL = xml.CreateAttribute ("Lang");
attrL.Value = fileKey.Value.ToString ();
nodeFile.Attributes.Append (attrL);
}
nodeProp.AppendChild (nodeFile);
}
}
// 多语言资源
else if (PriFileHelper.IsMsResourcePrefix (value))
{
Dictionary<string, string> localeDict = priAllRes.LocaleResourceAllValues (value);
localeDict ["root"] = value.ToString ();
foreach (KeyValuePair<string, string> lkv in localeDict)
{
XmlElement nodeLocale = xml.CreateElement ("LocaleResource");
nodeLocale.SetAttribute ("Lang", lkv.Key);
nodeLocale.InnerText = lkv.Value;
nodeProp.AppendChild (nodeLocale);
}
}
else
{
nodeProp.InnerText = value.ToString ();
}
nodeApp.AppendChild (nodeProp);
}
nodeApplications.AppendChild (nodeApp);
}
root.AppendChild (nodeApplications);
#endregion
}
#region prerequistes
var preq = Prerequisites;
{
var nodepreq = xml.CreateElement ("Prerequisites");
var nodeosmin = xml.CreateElement ("OSMinVersion");
nodeosmin.InnerText = preq.OSMinVersion.ToString ();
nodeosmin.SetAttribute ("Description", preq.OSMinVersionDescription);
var nodeosmaxt = xml.CreateElement ("OSMaxVersionTested");
nodeosmaxt.InnerText = preq.OSMaxVersionTested.ToString ();
nodeosmaxt.SetAttribute ("Description", preq.OSMaxVersionDescription);
nodepreq.AppendChild (nodeosmin);
nodepreq.AppendChild (nodeosmaxt);
root.AppendChild (nodepreq);
}
#endregion
#region resources
XmlElement nodeResources = xml.CreateElement ("Resources");
var res = Resources;
if (res.Languages != null)
{
foreach (var lang in res.Languages)
{
XmlElement nodeRes = xml.CreateElement ("Resource");
XmlAttribute attrLang = xml.CreateAttribute ("Language");
attrLang.Value = lang;
nodeRes.Attributes.Append (attrLang);
nodeResources.AppendChild (nodeRes);
}
}
if (res.Scales != null)
{
foreach (var scale in res.Scales)
{
XmlElement nodeRes = xml.CreateElement ("Resource");
XmlAttribute attrScale = xml.CreateAttribute ("Scale");
attrScale.Value = scale.ToString ();
nodeRes.Attributes.Append (attrScale);
nodeResources.AppendChild (nodeRes);
}
}
if (res.DXFeatures != null)
{
foreach (var d in res.DXFeatures)
{
int level = -1;
switch (d)
{
case DXFeatureLevel.Level9: level = 9; break;
case DXFeatureLevel.Level10: level = 10; break;
case DXFeatureLevel.Level11: level = 11; break;
case DXFeatureLevel.Level12: level = 12; break;
case DXFeatureLevel.Unspecified:
default: level = -1; break;
}
XmlElement nodeRes = xml.CreateElement ("Resource");
XmlAttribute attrDX = xml.CreateAttribute ("DXFeatureLevel");
attrDX.Value = level.ToString ();
nodeRes.Attributes.Append (attrDX);
nodeResources.AppendChild (nodeRes);
}
}
root.AppendChild (nodeResources);
#endregion
#region capabilities
XmlElement nodeCapabilities = xml.CreateElement ("Capabilities");
var caps = Capabilities;
if (caps.Capabilities != null)
{
foreach (var cap in caps.Capabilities)
{
XmlElement nodeCap = xml.CreateElement ("Capability");
XmlAttribute attrName = xml.CreateAttribute ("Name");
attrName.Value = cap;
nodeCap.Attributes.Append (attrName);
nodeCapabilities.AppendChild (nodeCap);
}
}
if (caps.DeviceCapabilities != null)
{
foreach (var devCap in caps.DeviceCapabilities)
{
XmlElement nodeDevCap = xml.CreateElement ("DeviceCapability");
XmlAttribute attrName = xml.CreateAttribute ("Name");
attrName.Value = devCap;
nodeDevCap.Attributes.Append (attrName);
nodeCapabilities.AppendChild (nodeDevCap);
}
}
root.AppendChild (nodeCapabilities);
#endregion
#region dependencies
XmlElement nodeDependencies = xml.CreateElement ("Dependencies");
var deps = Dependencies;
if (deps != null)
{
foreach (var dep in deps)
{
XmlElement nodeDep = xml.CreateElement ("Dependency");
XmlAttribute attrName = xml.CreateAttribute ("Name");
attrName.Value = dep.Name ?? "";
nodeDep.Attributes.Append (attrName);
XmlAttribute attrPublisher = xml.CreateAttribute ("Publisher");
attrPublisher.Value = dep.Publisher ?? "";
nodeDep.Attributes.Append (attrPublisher);
XmlAttribute attrMinVersion = xml.CreateAttribute ("MinVersion");
attrMinVersion.Value = dep.Version != null ? dep.Version.ToString () : "";
nodeDep.Attributes.Append (attrMinVersion);
nodeDependencies.AppendChild (nodeDep);
}
}
root.AppendChild (nodeDependencies);
#endregion
var ze = new ZipEntry ("info.xml");
ze.DateTime = DateTime.Now;
zos.PutNextEntry (ze);
byte [] bytes;
using (var ms = new MemoryStream ())
{
var settings = new XmlWriterSettings {
Encoding = Encoding.UTF8,
Indent = true,
OmitXmlDeclaration = false
};
using (var writer = XmlWriter.Create (ms, settings))
{
xml.Save (writer);
}
bytes = ms.ToArray ();
}
zos.Write (bytes, 0, bytes.Length);
zos.CloseEntry ();
return true;
}
finally
{
EnablePri = usePri;
UsePri = parsePri;
}
}
}
#endregion
}
catch (Exception ex)
{
throw ex;
return false;
}
}
public void SaveJsonFile (string savefilepath, object resolve, object reject)
{
try
@@ -1843,7 +2671,9 @@ namespace AppxPackage
}).ToList (),
familyName = id.FamilyName,
fullName = id.FullName,
resourceId = id.ResourceId
resourceId = id.ResourceId,
publisherId = id.PublisherId,
_publisherId = "Note: The publisher id obtained may be inaccurate."
};
#endregion
#region prerequistes
@@ -2060,7 +2890,7 @@ namespace AppxPackage
}
catch (Exception ex)
{
if (reject != null) JSHelper.CallJS (reject, ex);
if (reject != null) JSHelper.CallJS (reject, new DataUtils._I_Exception (ex));
}
}
public void SaveJsonFileAsync (string savefilepath, object resolve, object reject)
@@ -2172,6 +3002,10 @@ namespace AppxPackage
nodeid.AppendChild (nodeidfamily);
nodeid.AppendChild (nodeidfamily);
nodeid.AppendChild (nodeidresid);
var nodeidpublid = xml.CreateElement ("PublisherId");
nodeidpublid.InnerText = id.PublisherId;
nodeidpublid.SetAttribute ("Description", "Note: The publisher id obtained may be inaccurate.");
nodeid.AppendChild (nodeidpublid);
root.AppendChild (nodeid);
}
#endregion
@@ -2531,7 +3365,7 @@ namespace AppxPackage
}
catch (Exception ex)
{
if (reject != null) JSHelper.CallJS (reject, ex);
if (reject != null) JSHelper.CallJS (reject, new DataUtils._I_Exception (ex));
}
}
public void SaveXmlFileAsync (string savefilepath, object resolve, object reject)

View File

@@ -1,62 +0,0 @@
# ArmBuild.ps1
$ErrorActionPreference = "Stop"
$root = Split-Path -Parent $MyInvocation.MyCommand.Path
$staging = Join-Path $root "_staging"
$outZip = Join-Path $root "ArmPackage.zip"
$packageFolderName = "Desktop App Installer"
$destRoot = Join-Path $staging $packageFolderName
function Copy-Binaries-ToDest($src, $dest)
{
if (!(Test-Path $src)) { return }
Get-ChildItem $src -File | Where-Object {
$_.Extension -in ".exe", ".dll"
} | ForEach-Object {
Copy-Item -Path $_.FullName -Destination $dest -Force
}
}
Write-Host "Preparing staging..."
# 清理旧的 staging
if (Test-Path $staging) { Remove-Item $staging -Recurse -Force }
New-Item $destRoot -ItemType Directory | Out-Null
# ① 先放 Release
Copy-Binaries-ToDest (Join-Path $root "Release") $destRoot
# ② 再放 ARM\Release覆盖同名
Copy-Binaries-ToDest (Join-Path $root "ARM\Release") $destRoot
# ③ shared 全部铺到 Desktop App Installer 里
$shared = Join-Path $root "shared"
if (Test-Path $shared) {
Get-ChildItem $shared -Recurse | ForEach-Object {
$relativePath = $_.FullName.Substring($shared.Length).TrimStart('\')
$destinationPath = Join-Path $destRoot $relativePath
if ($_.PSIsContainer) {
if (!(Test-Path $destinationPath)) {
New-Item -Path $destinationPath -ItemType Directory | Out-Null
}
} else {
$parentDir = Split-Path $destinationPath -Parent
if (!(Test-Path $parentDir)) {
New-Item -Path $parentDir -ItemType Directory | Out-Null
}
Copy-Item -Path $_.FullName -Destination $destinationPath -Force
}
}
}
Write-Host "Creating ZIP..."
if (Test-Path $outZip) { Remove-Item $outZip -Force }
# 压缩 _staging 下的 Desktop App Installer 文件夹
Compress-Archive -Path $destRoot -DestinationPath $outZip -CompressionLevel Optimal
# 清理 staging
Remove-Item $staging -Recurse -Force
Write-Host "Done: $outZip"

View File

@@ -32,6 +32,24 @@
<PropertyGroup>
<ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<LangVersion>default</LangVersion>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>..\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<LangVersion>default</LangVersion>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.13.0.4\lib\net40\Newtonsoft.Json.dll</HintPath>

View File

@@ -797,6 +797,14 @@ namespace Bridge
}
public void UpdateApplicationItems (object items)
{
lock (_I_PackageReader._cacheCleanupLock)
{
try
{
_I_PackageReader._cache?.Clear ();
}
catch { }
}
var stritems = JsArrayToList (items).Select (e => e?.ToString ()).ToList ();
PackageReader.UpdateApplicationItems (stritems);
}

View File

@@ -29,6 +29,24 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<LangVersion>default</LangVersion>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>..\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<LangVersion>default</LangVersion>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.13.0.4\lib\net40\Newtonsoft.Json.dll</HintPath>

66
FindWinJS.ps1 Normal file
View File

@@ -0,0 +1,66 @@
<#
.SYNOPSIS
查找 HTML 文件中引用了 "winjs" 的 link 或 script 标签行。
.DESCRIPTION
递归搜索指定目录下的所有 .html / .htm 文件,输出包含 "winjs" 字符串(不区分大小写)
的 <link href="..."> 或 <script src="..."> 标签所在的行。
.PARAMETER Path
要搜索的文件夹路径。默认为当前目录。
.EXAMPLE
.\Find-WinJSElements.ps1 -Path "C:\Projects\Web"
.EXAMPLE
.\Find-WinJSElements.ps1
#>
param(
[Parameter(Mandatory=$false)]
[string]$Path = "."
)
# 检查路径是否存在
if (-not (Test-Path -LiteralPath $Path -PathType Container)) {
Write-Error "指定的路径不存在或不是文件夹: $Path"
exit 1
}
# 正则表达式:匹配包含 "winjs" 的 link href 或 script src 标签
# 使用 (?i) 表示不区分大小写
$pattern = '(?i)<(link[^>]*?href\s*=\s*["''][^"'']*winjs[^"'']*["''][^>]*?)>|(script[^>]*?src\s*=\s*["''][^"'']*winjs[^"'']*["''][^>]*?)>'
Write-Host "正在搜索文件夹: $((Resolve-Path -LiteralPath $Path).Path)" -ForegroundColor Cyan
Write-Host "匹配模式: 包含 'winjs' 的 <link href> 或 <script src> 标签`n"
# 获取所有 .html 和 .htm 文件(不区分大小写)
$files = Get-ChildItem -LiteralPath $Path -Recurse -Include "*.html","*.htm" -File
if ($files.Count -eq 0) {
Write-Host "未找到 HTML 文件。" -ForegroundColor Yellow
exit
}
$foundAny = $false
foreach ($file in $files) {
# 使用 Select-String 按行搜索,-CaseSensitive:$false 已隐含在 (?i) 中
$matches = Select-String -LiteralPath $file.FullName -Pattern $pattern -AllMatches
if ($matches) {
$foundAny = $true
Write-Host "`n文件: $($file.FullName)" -ForegroundColor Green
foreach ($match in $matches) {
# 输出行号和行内容(去除首尾空白)
$line = $match.Line.Trim()
Write-Host "$($match.LineNumber): $line"
}
}
}
if (-not $foundAny) {
Write-Host "`n未找到包含 'winjs' 的 link/script 元素。" -ForegroundColor Yellow
} else {
Write-Host "`n搜索完成。" -ForegroundColor Cyan
}

215
LICENSE
View File

@@ -1,21 +1,202 @@
MIT License
Copyright (c) 2025 Windows Modern
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
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:
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
1. Definitions.
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.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -13,7 +13,7 @@
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>x86</PlatformTarget>
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
@@ -34,6 +34,24 @@
<PropertyGroup>
<ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>..\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />

View File

@@ -62,7 +62,7 @@ namespace Launch
}
string appUserModelId = args [0];
string argumentLine = BuildCommandLine (args, 1);
AppxPackage.PackageManager.ActiveApp (appUserModelId, string.IsNullOrEmpty (argumentLine) ? null : argumentLine);
AppxPackage.PackageManager.ActiveApp (appUserModelId, argumentLine);
}
}
}

View File

@@ -41,7 +41,6 @@
this.Name = "ManagerShell";
this.PageScale = 125;
this.Text = "Form1";
this.WindowIcon = ((System.Drawing.Icon)(resources.GetObject("$this.WindowIcon")));
this.Load += new System.EventHandler(this.ManagerShell_Load);
this.Resize += new System.EventHandler(this.ManagerShell_Resize);
this.ResumeLayout(false);

View File

@@ -28,6 +28,20 @@ namespace Manager
InitSize ();
Text = Bridge.ResXmlStore.StringRes.Get ("MANAGER_APPTITLE");
this.Load += Form_Load;
try
{
if (this is WAShell.ModernForm)
{
this.WindowIcon = new Icon (Path.Combine (AppDomain.CurrentDomain.BaseDirectory, "icons\\32_manager.ico"));
}
}
catch
{
if (this is WAShell.ModernForm)
{
this.WindowIcon = this.Icon;
}
}
}
private void InitSize ()
{

File diff suppressed because it is too large Load Diff

View File

@@ -115,10 +115,10 @@
this.label1.AutoSize = true;
this.tableLayoutPanel1.SetColumnSpan(this.label1, 5);
this.label1.Dock = System.Windows.Forms.DockStyle.Fill;
this.label1.Font = new System.Drawing.Font("微软雅黑 Light", 20F);
this.label1.Font = new System.Drawing.Font("Segoe UI", 19.8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label1.Location = new System.Drawing.Point(27, 24);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(727, 45);
this.label1.Size = new System.Drawing.Size(727, 46);
this.label1.TabIndex = 0;
this.label1.Text = "Create Desktop Shortcut";
//
@@ -127,7 +127,7 @@
this.label2.AutoSize = true;
this.tableLayoutPanel1.SetColumnSpan(this.label2, 5);
this.label2.Dock = System.Windows.Forms.DockStyle.Fill;
this.label2.Location = new System.Drawing.Point(27, 79);
this.label2.Location = new System.Drawing.Point(27, 80);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(727, 60);
this.label2.TabIndex = 1;
@@ -147,7 +147,7 @@
this.tableLayoutPanel2.Controls.Add(this.label7, 0, 8);
this.tableLayoutPanel2.Controls.Add(this.customIconDisplay, 0, 9);
this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel2.Location = new System.Drawing.Point(27, 152);
this.tableLayoutPanel2.Location = new System.Drawing.Point(27, 153);
this.tableLayoutPanel2.Name = "tableLayoutPanel2";
this.tableLayoutPanel2.RowCount = 10;
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
@@ -160,7 +160,7 @@
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 39F));
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 18F));
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 13F));
this.tableLayoutPanel2.Size = new System.Drawing.Size(235, 324);
this.tableLayoutPanel2.Size = new System.Drawing.Size(235, 323);
this.tableLayoutPanel2.TabIndex = 2;
//
// label3
@@ -251,7 +251,7 @@
this.customIconDisplay.Dock = System.Windows.Forms.DockStyle.Fill;
this.customIconDisplay.Location = new System.Drawing.Point(3, 230);
this.customIconDisplay.Name = "customIconDisplay";
this.customIconDisplay.Size = new System.Drawing.Size(229, 91);
this.customIconDisplay.Size = new System.Drawing.Size(229, 90);
this.customIconDisplay.TabIndex = 7;
this.customIconDisplay.TabStop = false;
//
@@ -273,7 +273,7 @@
this.tableLayoutPanel3.Controls.Add(this.label12, 0, 9);
this.tableLayoutPanel3.Controls.Add(this.shortcutNameInput, 0, 10);
this.tableLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel3.Location = new System.Drawing.Point(273, 152);
this.tableLayoutPanel3.Location = new System.Drawing.Point(273, 153);
this.tableLayoutPanel3.Name = "tableLayoutPanel3";
this.tableLayoutPanel3.RowCount = 11;
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle());
@@ -287,7 +287,7 @@
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 32F));
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 18F));
this.tableLayoutPanel3.Size = new System.Drawing.Size(235, 324);
this.tableLayoutPanel3.Size = new System.Drawing.Size(235, 323);
this.tableLayoutPanel3.TabIndex = 3;
//
// label5
@@ -476,14 +476,14 @@
this.tableLayoutPanel4.Controls.Add(this.imageSizeList, 0, 1);
this.tableLayoutPanel4.Controls.Add(this.imagesPreview, 0, 3);
this.tableLayoutPanel4.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel4.Location = new System.Drawing.Point(519, 152);
this.tableLayoutPanel4.Location = new System.Drawing.Point(519, 153);
this.tableLayoutPanel4.Name = "tableLayoutPanel4";
this.tableLayoutPanel4.RowCount = 4;
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel4.Size = new System.Drawing.Size(235, 324);
this.tableLayoutPanel4.Size = new System.Drawing.Size(235, 323);
this.tableLayoutPanel4.TabIndex = 4;
//
// label8
@@ -500,7 +500,7 @@
//
this.label9.AutoSize = true;
this.label9.Dock = System.Windows.Forms.DockStyle.Fill;
this.label9.Location = new System.Drawing.Point(3, 162);
this.label9.Location = new System.Drawing.Point(3, 161);
this.label9.Name = "label9";
this.label9.Size = new System.Drawing.Size(229, 20);
this.label9.TabIndex = 1;
@@ -516,7 +516,7 @@
this.imageSizeList.Location = new System.Drawing.Point(3, 23);
this.imageSizeList.Name = "imageSizeList";
this.imageSizeList.RowTemplate.Height = 27;
this.imageSizeList.Size = new System.Drawing.Size(229, 136);
this.imageSizeList.Size = new System.Drawing.Size(229, 135);
this.imageSizeList.TabIndex = 2;
this.imageSizeList.CellDoubleClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.imageSizeList_CellDoubleClick);
//
@@ -536,7 +536,7 @@
this.imagesPreview.AutoScroll = true;
this.imagesPreview.Dock = System.Windows.Forms.DockStyle.Fill;
this.imagesPreview.FlowDirection = System.Windows.Forms.FlowDirection.TopDown;
this.imagesPreview.Location = new System.Drawing.Point(3, 185);
this.imagesPreview.Location = new System.Drawing.Point(3, 184);
this.imagesPreview.Name = "imagesPreview";
this.imagesPreview.Size = new System.Drawing.Size(229, 136);
this.imagesPreview.TabIndex = 3;

View File

@@ -31,6 +31,24 @@
<WarningLevel>4</WarningLevel>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<LangVersion>default</LangVersion>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>..\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<LangVersion>default</LangVersion>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />

13
NOTICE.TXT Normal file
View File

@@ -0,0 +1,13 @@
Copyright (c) 2025-2026 Windows Modern
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

230
PkgCLI/CliParsing.cs Normal file
View File

@@ -0,0 +1,230 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PkgCLI
{
public class NormalizeStringComparer: IEqualityComparer<string>
{
public bool Equals (string x, string y) => Polyfill.NEquals (x, y);
public int GetHashCode (string obj) => obj.NNormalize ().GetHashCode ();
}
public class NormalizeCharacterComparer: IEqualityComparer<char>
{
public bool Equals (char x, char y) => char.ToLowerInvariant (x) == char.ToLowerInvariant (y);
public int GetHashCode (char obj) => char.ToLowerInvariant (obj).GetHashCode ();
}
public class StringNSet: HashSet<string>
{
public StringNSet () : base (new NormalizeStringComparer ()) { }
public StringNSet (IEnumerable<string> list) : base (list, new NormalizeStringComparer ()) { }
}
public class CharNSet: HashSet<char>
{
public CharNSet () : base (new NormalizeCharacterComparer ()) { }
public CharNSet (IEnumerable<char> list) : base (list, new NormalizeCharacterComparer ()) { }
}
public static class CliParsingConst
{
public static readonly char [] defaultPrefixs = new char [] { '/', '-' };
public static readonly char [] defaultPostfixs = new char [] { '=', ':' };
public static readonly string [] emptyStringArray = new string [] { };
}
public class CmdParamName: IEquatable<CmdParamName>, IComparable<CmdParamName>, IDisposable
{
private string _id = "";
private string _name = "";
/// <summary>
/// 命令唯一标识,但不作为命令名,仅用于内部识别。命令 ID 可以作为命令名或别名。
/// </summary>
public string Id { get { return _id.NNormalize (); } set { _id = value; } }
/// <summary>
/// 命令名,唯一。命令名不能与别名重复。首字符不能为前缀中的字符,尾字符不能为后缀中的字符。
/// </summary>
public string Name { get { return _name.NNormalize (); } set { _name = value; } }
/// <summary>
/// 命令别名,唯一。不能与命令名重复。首字符不能为前缀中的字符,尾字符不能为后缀中的字符。
/// </summary>
/// </summary>
public StringNSet Aliases { get; private set; } = new StringNSet ();
/// <summary>
/// 命令前缀,为一个字符,标点符号。不能为命令名或别名的首字符。
/// </summary>
public CharNSet Prefixs { get; set; } = new CharNSet (CliParsingConst.defaultPrefixs);
/// <summary>
/// 命令后缀,为一个字符,标点符号。不能为命令名或别名的尾字符。
/// </summary>
public CharNSet Postfixs { get; set; } = new CharNSet (CliParsingConst.defaultPostfixs);
public bool Equals (CmdParamName other)
{
if (other == null) return false;
if (ReferenceEquals (this, other)) return true;
return string.Equals (this.Id, other.Id, StringComparison.Ordinal);
}
public int CompareTo (CmdParamName other)
{
if (other == null) return 1;
if (ReferenceEquals (this, other)) return 0;
return string.Compare (this.Id, other.Id, StringComparison.Ordinal);
}
public override bool Equals (object obj) => Equals (obj as CmdParamName);
public override int GetHashCode () => this.Id?.GetHashCode () ?? 0;
public bool ParamContains (string param)
{
var ret = Name.NEquals (param);
if (!ret)
{
foreach (var alias in Aliases)
{
if (alias.NEquals (param)) return true;
}
}
return ret;
}
public void Dispose ()
{
Aliases?.Clear ();
Prefixs?.Clear ();
}
public CmdParamName (string id, string name, IEnumerable<string> aliases, IEnumerable<char> prefixs, IEnumerable<char> postfixs)
{
Id = id;
Name = name;
Aliases = new StringNSet (aliases);
Prefixs = new CharNSet (prefixs);
Postfixs = new CharNSet (postfixs);
}
public CmdParamName (string name, IEnumerable<string> aliases) : this (name, name, aliases, CliParsingConst.defaultPrefixs, CliParsingConst.defaultPostfixs) { }
public CmdParamName (string name) : this (name, CliParsingConst.emptyStringArray) { }
public CmdParamName () { }
}
public class CommandParam: IEquatable<string>
{
private string _id = "";
public string Id { get { return _id.NNormalize (); } set { _id = value; } }
public string Value = "";
public bool Equals (string other)
{
return (_id ?? "").NEquals (other);
}
public override bool Equals (object obj)
{
if (obj is string) return Equals (obj as string);
else if (obj is CommandParam) return Equals ((obj as CommandParam).Id);
else return base.Equals (obj);
}
public override int GetHashCode ()
{
return Id.GetHashCode ();
}
}
public class CliParsing: IDisposable
{
public HashSet<CmdParamName> Params { get; set; } = new HashSet<CmdParamName> ();
public void Dispose ()
{
Params = null;
}
public List<CommandParam> Parse (string [] args)
{
var ret = new List<CommandParam> ();
CommandParam last = new CommandParam ();
for (long i = 0; i < args.LongLength; i++)
{
var arg = args [i]?.Trim () ?? "";
var item = args [i]?.NNormalize () ?? "";
if (string.IsNullOrWhiteSpace (item)) continue;
var first = item [0];
bool isfind = false;
foreach (var param in Params)
{
if (param.Prefixs.Contains (first))
{
var minser = param.Postfixs.Select (e => {
var index = item.IndexOf (e);
return index == -1 ? int.MaxValue : index;
}).Min ();
string paramPart, postfixPart;
if (minser == int.MaxValue)
{
paramPart = arg.Substring (1);
postfixPart = "";
}
else
{
paramPart = arg.Substring (1, minser - 1);
postfixPart = arg.Substring (minser + 1);
}
if (param.ParamContains (paramPart))
{
isfind = true;
var cmdParam = new CommandParam ();
cmdParam.Id = param.Id;
if (!string.IsNullOrEmpty (postfixPart))
cmdParam.Value = postfixPart;
last = cmdParam;
ret.Add (cmdParam);
break;
}
}
}
if (!isfind)
{
var valueparam = new CommandParam ();
valueparam.Value = arg;
ret.Add (valueparam);
}
}
return ret;
}
}
public static class CliPasingUtils
{
public static bool ParamContains (this List<CommandParam> cpl, string id)
{
foreach (var i in cpl)
{
if (i.Id.NEquals (id)) return true;
}
return false;
}
public static bool ParamContains (this List<CommandParam> cpl, CmdParamName param)
{
foreach (var i in cpl)
{
if (i.Id.NEquals (param.Id)) return true;
}
return false;
}
public static bool ParamsContainsOr (this List<CommandParam> cpl, params string [] ids)
{
foreach (var i in cpl)
{
foreach (var j in ids)
{
if (i.Id.NEquals (j)) return true;
}
}
return false;
}
public static bool ParamsContainsAnd (this List<CommandParam> cpl, params string [] ids)
{
if (ids == null || ids.Length == 0) return true;
foreach (var id in ids)
{
if (!ParamContains (cpl, id)) return false;
}
return true;
}
public static CommandParam GetFromId (this List <CommandParam> cpl, string id)
{
foreach (var c in cpl)
{
if (c.Id.NEquals (id)) return c;
}
return null;
}
}
}

View File

@@ -50,6 +50,10 @@
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.13.0.4\lib\net40\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
@@ -59,19 +63,29 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="CliParsing.cs" />
<Compile Include="Polyfill.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Text.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AppxPackage\AppxPackage.csproj">
<Project>{bd681a4f-eb60-4bb8-90b5-65968fc7da59}</Project>
<Name>AppxPackage</Name>
</ProjectReference>
<ProjectReference Include="..\DataUtils\DataUtils.csproj">
<Project>{ffd3fd52-37a8-4f43-883c-de8d996cb0e0}</Project>
<Name>DataUtils</Name>
</ProjectReference>
<ProjectReference Include="..\PrivateInit\PrivateInit.csproj">
<Project>{8e708d9a-6325-4aa9-b5a5-d1b5eca8eef7}</Project>
<Name>PrivateInit</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- 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.

991
PkgCLI/Polyfill.cs Normal file
View File

@@ -0,0 +1,991 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using AppxPackage;
using AppxPackage.Info;
using Newtonsoft.Json;
namespace PkgCLI
{
public static class Polyfill
{
static public bool NEquals (this string s1, string s2)
{
if (string.IsNullOrWhiteSpace (s1) && string.IsNullOrWhiteSpace (s2)) return true;
else return s1?.Trim ()?.ToLowerInvariant () == s2?.Trim ()?.ToLowerInvariant ();
}
static public string NNormalize (this string s1)
{
return s1?.Trim ()?.ToLowerInvariant ();
}
static public string Join<T> (this IEnumerable<T> ie, string divide = ", ")
{
var ret = "";
for (var i = 0; i < ie.Count (); i++)
{
if (i != 0) ret += divide;
var item = ie.ElementAt (i);
if (item == null) ret += "(null)";
else ret += item.ToString ();
}
return ret;
}
/// <summary>
/// 将对象通过指定的选择器转换为目标类型。
/// 类似于 LINQ 的 Select但适用于单一对象。
/// </summary>
/// <typeparam name="T">目标类型</typeparam>
/// <param name="obj">源对象</param>
/// <param name="selector">转换委托,输入源对象,输出目标对象</param>
/// <returns>转换后的结果</returns>
public static T ToOther<T> (this object obj, Func<object, T> selector)
{
if (selector == null)
throw new ArgumentNullException (nameof (selector));
return selector (obj);
}
/// <summary>
/// 将字典格式化为对齐的文本,每个键值对一行,分隔符垂直对齐。
/// </summary>
/// <param name="dict">要格式化的字典</param>
/// <param name="separator">分隔符(如 ":", "="),默认为 ":"</param>
/// <param name="indent">每行前的缩进字符串,默认为空</param>
/// <param name="sortKeys">是否按键名排序(不区分大小写),默认为 false</param>
/// <returns>格式化后的字符串,例如:
/// Name : Alice
/// Age : 30
/// </returns>
public static string FormatDictionaryAligned (
this IDictionary<string, string> dict,
string separator = ":",
string indent = "",
bool sortKeys = false)
{
if (dict == null || dict.Count == 0)
return string.Empty;
var keys = sortKeys
? dict.Keys.OrderBy (k => k, StringComparer.OrdinalIgnoreCase).ToList ()
: dict.Keys.ToList ();
int maxKeyLength = keys.Max (k => k.Length);
var sb = new StringBuilder ();
foreach (string key in keys)
{
string value = dict [key] ?? string.Empty;
sb.AppendLine ($"{indent}{key.PadRight (maxKeyLength)} {separator} {value}");
}
return sb.ToString ().TrimEnd (Environment.NewLine.ToCharArray ());
}
public static string Format (this string format, params object [] args)
{
return String.Format (format, args);
}
public static string Format (this string format, object args)
{
return String.Format (format, args);
}
}
public static class PackageReaderExt
{
static public object GetJsonObjectForCli (this PackageReader pr)
{
var id = pr.Identity;
var prop = pr.Properties;
var pre = pr.Prerequisites;
var apps = pr.Applications;
var caps = pr.Capabilities;
var deps = pr.Dependencies;
dynamic obj = new {
valid = pr.IsValid,
type = pr.Type.ToOther (e => {
switch ((AppxPackage.Info.PackageType)e)
{
case AppxPackage.Info.PackageType.Appx: return "appx";
case AppxPackage.Info.PackageType.Bundle: return "bundle";
default:
case AppxPackage.Info.PackageType.Unknown: return "unknown";
}
}),
role = pr.Role.ToOther (o => {
switch ((AppxPackage.Info.PackageRole)o)
{
case AppxPackage.Info.PackageRole.Application: return "application";
case AppxPackage.Info.PackageRole.Framework: return "framework";
case AppxPackage.Info.PackageRole.Resource: return "resource";
default:
case AppxPackage.Info.PackageRole.Unknown: return "unknown";
}
}),
identity = new {
name = id.Name,
publisher = id.Publisher,
version = id.Version.Expression,
realVersion = id.RealVersion.Expression,
architecture = id.ProcessArchitecture.Select (e => {
switch (e)
{
case AppxPackage.Info.Architecture.ARM: return "arm";
case AppxPackage.Info.Architecture.ARM64: return "arm64";
case AppxPackage.Info.Architecture.Neutral: return "neutral";
default:
case AppxPackage.Info.Architecture.Unknown: return "unknown";
case AppxPackage.Info.Architecture.x64: return "x64";
case AppxPackage.Info.Architecture.x86: return "x86";
}
}).ToList (),
familyName = id.FamilyName,
fullName = id.FullName,
resourceId = id.ResourceId,
publisherId = id.PublisherId,
_publisherId = "Note: The publisher id obtained may be inaccurate."
},
properties = new {
displayName = prop.DisplayName,
publisherDisplayName = prop.Publisher,
description = prop.Description,
logo = prop.Logo,
framework = prop.Framework,
resourcePackage = prop.ResourcePackage
},
prerequisite = new {
osMinVersion = pre.OSMinVersion.ToString (),
osMaxVersionTested = pre.OSMaxVersionTested.ToString (),
_osMinVersion = pre.OSMinVersionDescription,
_osMaxVersionTested = pre.OSMaxVersionDescription
},
applications = apps.Select (e => {
var dict = new Dictionary<string, string> ();
foreach (var kv in e)
{
if (kv.Key.IndexOf ("Base64") >= 0) continue;
var value = e.NewAt (kv.Key, pr.EnablePri);
if (string.IsNullOrWhiteSpace (value))
value = e.At (kv.Key);
dict [kv.Key] = value;
}
return dict;
}).ToList (),
capabilities = new {
capabilities = caps.Capabilities,
deviceCapabilities = caps.DeviceCapabilities
},
dependencies = deps.Select (e => new {
name = e.Name,
publisher = e.Publisher,
minVersion = e.Version.ToString ()
})
};
return obj;
}
/// <summary>
/// 从 PackageReader 中获取指定路径的值。
/// 支持格式:路径中可使用 '.' 或 ':' 分隔,支持索引器 '[index]',支持 '.length'。
/// 大小写不敏感,自动去除首尾空白。
/// 示例:
/// "Identity" -> 返回 Identity 字典
/// "Identity.Name" -> 返回名称
/// "Properties.Publisher" -> 返回发布者显示名称(别名)
/// "applications[0]" -> 返回第一个应用字典
/// "applications.length" -> 返回应用个数
/// "Applications[0].LogoBase64" -> 返回第一个应用的 LogoBase64
/// </summary>
public static object GetItem (this PackageReader pr, string item)
{
if (pr == null) throw new ArgumentNullException ("pr");
if (string.IsNullOrWhiteSpace (item)) return null;
string path = item.Trim ().Replace (':', '.');
object result = ResolvePath (pr, path);
return SerializeObject (result, pr, false);
}
private static object ResolvePath (object target, string path)
{
if (target == null) return null;
if (string.IsNullOrEmpty (path)) return target;
string [] segments = path.Split ('.');
object current = target;
foreach (string seg in segments)
{
if (current == null) return null;
if (seg.Contains ("[") && seg.Contains ("]"))
{
int bracketStart = seg.IndexOf ('[');
string propName = seg.Substring (0, bracketStart);
string indexStr = seg.Substring (bracketStart + 1, seg.Length - bracketStart - 2);
int index;
if (!int.TryParse (indexStr, out index))
return null;
object collection = GetPropertyValue (current, propName);
if (collection == null) return null;
current = GetIndexedValue (collection, index);
}
else if (string.Equals (seg, "length", StringComparison.OrdinalIgnoreCase) ||
string.Equals (seg, "count", StringComparison.OrdinalIgnoreCase))
{
current = GetLength (current);
}
else
{
current = GetPropertyValue (current, seg);
}
}
return current;
}
private static object GetPropertyValue (object target, string propName)
{
if (target == null) return null;
Type type = target.GetType ();
// 根对象 PackageReader 的属性名映射(不区分大小写)
if (type == typeof (PackageReader))
{
string mapped = null;
string lower = propName.ToLowerInvariant ();
switch (lower)
{
case "pkgid":
case "id":
case "identity": mapped = "Identity"; break;
case "prop":
case "properties": mapped = "Properties"; break;
case "prerequistes":
case "prerequisite":
case "prerequisites": mapped = "Prerequisites"; break;
case "res":
case "resources": mapped = "Resources"; break;
case "apps":
case "applications": mapped = "Applications"; break;
case "caps":
case "capabilities": mapped = "Capabilities"; break;
case "deps":
case "dependencies": mapped = "Dependencies"; break;
case "type": mapped = "Type"; break;
case "role": mapped = "Role"; break;
case "valid":
case "isvalid": mapped = "IsValid"; break;
case "filepath": mapped = "FilePath"; break;
}
if (mapped != null)
propName = mapped;
}
// PRProperties 别名Publisher / PublisherDisplayName 都映射到 Publisher 属性
if (type == typeof (PRProperties))
{
if (string.Equals (propName, "Publisher", StringComparison.OrdinalIgnoreCase) ||
string.Equals (propName, "PublisherDisplayName", StringComparison.OrdinalIgnoreCase))
{
propName = "Publisher";
}
}
// PRApplication 中以 Base64 结尾的属性 -> 调用 NewAtBase64
if (type == typeof (PRApplication) && propName.EndsWith ("Base64", StringComparison.OrdinalIgnoreCase))
{
string baseKey = propName.Substring (0, propName.Length - 6);
PRApplication app = (PRApplication)target;
MethodInfo method = typeof (PRApplication).GetMethod ("NewAtBase64", BindingFlags.Public | BindingFlags.Instance);
if (method != null)
{
return method.Invoke (app, new object [] { baseKey });
}
return null;
}
// PRApplication 普通属性访问(字典键,大小写不敏感)
if (type == typeof (PRApplication))
{
PRApplication app = (PRApplication)target;
// 直接使用索引器,内部已处理资源解析和大小写不敏感
return app [propName];
}
// MRApplication 同理
if (type == typeof (MRApplication))
{
MRApplication app = (MRApplication)target;
return app [propName];
}
// 反射属性(不区分大小写)
PropertyInfo prop = type.GetProperty (propName,
BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
if (prop != null)
{
return prop.GetValue (target, null);
}
// 反射字段
FieldInfo field = type.GetField (propName,
BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
if (field != null)
{
return field.GetValue (target);
}
return null;
}
private static object GetIndexedValue (object collection, int index)
{
if (collection == null) return null;
// PRApplications
PRApplications apps = collection as PRApplications;
if (apps != null)
{
if (index >= 0 && index < apps.Applications.Count)
return apps.Applications [index];
return null;
}
// IList
IList list = collection as IList;
if (list != null && index >= 0 && index < list.Count)
return list [index];
// 索引器属性
PropertyInfo indexer = collection.GetType ().GetProperty ("Item", new [] { typeof (int) });
if (indexer != null)
return indexer.GetValue (collection, new object [] { index });
return null;
}
private static int? GetLength (object obj)
{
if (obj == null) return null;
PRApplications apps = obj as PRApplications;
if (apps != null) return apps.Applications.Count;
PRDependencies deps = obj as PRDependencies;
if (deps != null) return deps.Dependencies.Count;
IList list = obj as IList;
if (list != null) return list.Count;
ICollection coll = obj as ICollection;
if (coll != null) return coll.Count;
return null;
}
private static object SerializeObject (object obj, PackageReader pr, bool filterBase64)
{
if (obj == null) return null;
Type type = obj.GetType ();
if (type.IsPrimitive || obj is string || obj is decimal || obj is Enum)
return obj;
// PRIdentity
if (type == typeof (PRIdentity))
{
PRIdentity id = (PRIdentity)obj;
return new {
name = id.Name,
publisher = id.Publisher,
version = id.Version.Expression,
realVersion = id.RealVersion.Expression,
architecture = id.ProcessArchitecture.Select (e => {
switch (e)
{
case Architecture.ARM: return "arm";
case Architecture.ARM64: return "arm64";
case Architecture.Neutral: return "neutral";
case Architecture.x64: return "x64";
case Architecture.x86: return "x86";
default: return "unknown";
}
}).ToList (),
familyName = id.FamilyName,
fullName = id.FullName,
resourceId = id.ResourceId
};
}
// PRProperties
if (type == typeof (PRProperties))
{
PRProperties prop = (PRProperties)obj;
return new {
displayName = prop.DisplayName,
publisherDisplayName = prop.Publisher,
description = prop.Description,
logo = prop.Logo,
framework = prop.Framework,
resourcePackage = prop.ResourcePackage
};
}
// PRPrerequisites
if (type == typeof (PRPrerequisites))
{
PRPrerequisites pre = (PRPrerequisites)obj;
return new {
osMinVersion = pre.OSMinVersion,
osMaxVersionTested = pre.OSMaxVersionTested,
_osMinVersion = pre.OSMinVersionDescription,
_osMaxVersionTested = pre.OSMaxVersionDescription
};
}
// PRCapabilities
if (type == typeof (PRCapabilities))
{
PRCapabilities caps = (PRCapabilities)obj;
return new {
capabilities = caps.Capabilities,
deviceCapabilities = caps.DeviceCapabilities
};
}
// PRDependencies
if (type == typeof (PRDependencies))
{
PRDependencies deps = (PRDependencies)obj;
return deps.Select (e => new {
name = e.Name,
publisher = e.Publisher,
minVersion = e.Version.ToString ()
}).ToList ();
}
// PRApplications (集合)
if (type == typeof (PRApplications))
{
PRApplications apps = (PRApplications)obj;
return apps.Select (e => SerializeObject (e, pr, filterBase64)).ToList ();
}
// PRApplication (单个应用)
if (type == typeof (PRApplication))
{
PRApplication app = (PRApplication)obj;
var dict = new Dictionary<string, string> (StringComparer.OrdinalIgnoreCase);
foreach (var kv in app)
{
if (kv.Key.IndexOf ("Base64", StringComparison.OrdinalIgnoreCase) >= 0)
continue;
string value = app.NewAt (kv.Key, pr.EnablePri);
if (string.IsNullOrWhiteSpace (value))
value = app.At (kv.Key);
dict [kv.Key] = value;
}
return dict;
}
// IDictionary
IDictionary dictObj = obj as IDictionary;
if (dictObj != null)
{
var result = new Dictionary<string, object> (StringComparer.OrdinalIgnoreCase);
foreach (DictionaryEntry entry in dictObj)
{
string key = entry.Key?.ToString ();
if (string.IsNullOrEmpty (key)) continue;
if (filterBase64 && key.EndsWith ("_Base64", StringComparison.OrdinalIgnoreCase))
continue;
result [key] = SerializeObject (entry.Value, pr, filterBase64);
}
return result;
}
// IEnumerable (非字符串)
if (!(obj is string))
{
IEnumerable enumerable = obj as IEnumerable;
if (enumerable != null)
{
var list = new List<object> ();
foreach (var item in enumerable)
list.Add (SerializeObject (item, pr, filterBase64));
return list;
}
}
// 后备:反射属性
var props = type.GetProperties (BindingFlags.Public | BindingFlags.Instance);
var propDict = new Dictionary<string, object> (StringComparer.OrdinalIgnoreCase);
foreach (var prop in props)
{
if (prop.GetIndexParameters ().Length > 0) continue;
string propName = prop.Name;
if (filterBase64 && propName.EndsWith ("Base64", StringComparison.OrdinalIgnoreCase))
continue;
object val = prop.GetValue (obj, null);
propDict [propName] = SerializeObject (val, pr, filterBase64);
}
return propDict;
}
}
public static class ManifestReaderExt
{
/// <summary>
/// 获取用于 CLI 输出的 JSON 对象(与 PackageReaderExt.GetJsonObjectForCli 结构一致)。
/// </summary>
public static object GetJsonObjectForCli (this ManifestReader mr)
{
var id = mr.Identity;
var prop = mr.Properties;
var pre = mr.Prerequisites;
var apps = mr.Applications;
var caps = mr.Capabilities;
var deps = mr.Dependencies;
var res = mr.Resources;
dynamic obj = new {
valid = mr.IsValid,
type = mr.Type.ToOther (e => {
switch ((PackageType)e)
{
case PackageType.Appx: return "appx";
case PackageType.Bundle: return "bundle";
default:
case PackageType.Unknown: return "unknown";
}
}),
role = mr.Role.ToOther (o => {
switch ((PackageRole)o)
{
case PackageRole.Application: return "application";
case PackageRole.Framework: return "framework";
case PackageRole.Resource: return "resource";
default:
case PackageRole.Unknown: return "unknown";
}
}),
identity = new {
name = id.Name,
publisher = id.Publisher,
version = id.Version.Expression,
architecture = id.ProcessArchitecture.Select (e => {
switch (e)
{
case Architecture.ARM: return "arm";
case Architecture.ARM64: return "arm64";
case Architecture.Neutral: return "neutral";
case Architecture.x64: return "x64";
case Architecture.x86: return "x86";
default: return "unknown";
}
}).ToList (),
familyName = id.FamilyName,
fullName = id.FullName,
resourceId = id.ResourceId,
publisherId = id.PublisherId,
_publisherId = "Note: The publisher id obtained may be inaccurate."
},
properties = new {
displayName = prop.DisplayName,
publisherDisplayName = prop.Publisher,
description = prop.Description,
logo = prop.Logo,
framework = prop.Framework,
resourcePackage = prop.ResourcePackage
},
prerequisite = new {
osMinVersion = pre.OSMinVersion.ToString (),
osMaxVersionTested = pre.OSMaxVersionTested.ToString (),
_osMinVersion = pre.OSMinVersionDescription,
_osMaxVersionTested = pre.OSMaxVersionDescription
},
resources = new {
languages = res.Languages,
scales = res.Scales,
dxFeatureLevels = res.DXFeatures.Select (d => {
switch (d)
{
case DXFeatureLevel.Level9: return 9;
case DXFeatureLevel.Level10: return 10;
case DXFeatureLevel.Level11: return 11;
case DXFeatureLevel.Level12: return 12;
default: return -1;
}
}).ToList ()
},
applications = apps.Select (e => {
var dict = new Dictionary<string, string> ();
foreach (var kv in e)
{
if (kv.Key.IndexOf ("Base64", StringComparison.OrdinalIgnoreCase) >= 0)
continue;
string value = e.NewAt (kv.Key, mr.EnablePri);
if (string.IsNullOrWhiteSpace (value))
value = e.At (kv.Key);
dict [kv.Key] = value;
}
return dict;
}).ToList (),
capabilities = new {
capabilities = caps.Capabilities,
deviceCapabilities = caps.DeviceCapabilities
},
dependencies = deps.Select (e => new {
name = e.Name,
publisher = e.Publisher,
minVersion = e.Version.ToString ()
})
};
return obj;
}
/// <summary>
/// 从 ManifestReader 中获取指定路径的值。
/// 支持格式:路径中可使用 '.' 或 ':' 分隔,支持索引器 '[index]',支持 '.length'。
/// 大小写不敏感,自动去除首尾空白。
/// 示例:
/// "Identity" -> 返回 Identity 字典
/// "Identity.Name" -> 返回名称
/// "Properties.Publisher" -> 返回发布者显示名称(别名)
/// "applications[0]" -> 返回第一个应用字典
/// "applications.length" -> 返回应用个数
/// "Applications[0].LogoBase64" -> 返回第一个应用的 LogoBase64
/// </summary>
public static object GetItem (this ManifestReader mr, string item)
{
if (mr == null) throw new ArgumentNullException ("mr");
if (string.IsNullOrWhiteSpace (item)) return null;
string path = item.Trim ().Replace (':', '.');
object result = ResolvePath (mr, path);
return SerializeObject (result, mr, false);
}
private static object ResolvePath (object target, string path)
{
if (target == null) return null;
if (string.IsNullOrEmpty (path)) return target;
string [] segments = path.Split ('.');
object current = target;
foreach (string seg in segments)
{
if (current == null) return null;
if (seg.Contains ("[") && seg.Contains ("]"))
{
int bracketStart = seg.IndexOf ('[');
string propName = seg.Substring (0, bracketStart);
string indexStr = seg.Substring (bracketStart + 1, seg.Length - bracketStart - 2);
int index;
if (!int.TryParse (indexStr, out index))
return null;
object collection = GetPropertyValue (current, propName);
if (collection == null) return null;
current = GetIndexedValue (collection, index);
}
else if (string.Equals (seg, "length", StringComparison.OrdinalIgnoreCase) ||
string.Equals (seg, "count", StringComparison.OrdinalIgnoreCase))
{
current = GetLength (current);
}
else
{
current = GetPropertyValue (current, seg);
}
}
return current;
}
private static object GetPropertyValue (object target, string propName)
{
if (target == null) return null;
Type type = target.GetType ();
// 根对象 ManifestReader 的属性名映射(不区分大小写)
if (type == typeof (ManifestReader))
{
string mapped = null;
string lower = propName.ToLowerInvariant ();
switch (lower)
{
case "pkgid":
case "id":
case "identity": mapped = "Identity"; break;
case "prop":
case "properties": mapped = "Properties"; break;
case "prerequistes":
case "prerequisite":
case "prerequisites": mapped = "Prerequisites"; break;
case "res":
case "resources": mapped = "Resources"; break;
case "apps":
case "applications": mapped = "Applications"; break;
case "caps":
case "capabilities": mapped = "Capabilities"; break;
case "deps":
case "dependencies": mapped = "Dependencies"; break;
case "type": mapped = "Type"; break;
case "role": mapped = "Role"; break;
case "valid":
case "isvalid": mapped = "IsValid"; break;
case "file":
case "filepath": mapped = "FilePath"; break;
case "fileroot": mapped = "FileRoot"; break;
}
if (mapped != null)
propName = mapped;
}
// MRProperties 别名Publisher / PublisherDisplayName 都映射到 Publisher 属性
if (type == typeof (MRProperties))
{
if (string.Equals (propName, "Publisher", StringComparison.OrdinalIgnoreCase) ||
string.Equals (propName, "PublisherDisplayName", StringComparison.OrdinalIgnoreCase))
{
propName = "Publisher";
}
}
// MRApplication 中以 Base64 结尾的属性 -> 调用 NewAtBase64
if (type == typeof (MRApplication) && propName.EndsWith ("Base64", StringComparison.OrdinalIgnoreCase))
{
string baseKey = propName.Substring (0, propName.Length - 6);
MRApplication app = (MRApplication)target;
MethodInfo method = typeof (MRApplication).GetMethod ("NewAtBase64", BindingFlags.Public | BindingFlags.Instance);
if (method != null)
{
return method.Invoke (app, new object [] { baseKey });
}
return null;
}
// MRApplication 普通属性访问(字典键,大小写不敏感)
if (type == typeof (MRApplication))
{
MRApplication app = (MRApplication)target;
return app [propName];
}
// 反射属性(不区分大小写)
PropertyInfo prop = type.GetProperty (propName,
BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
if (prop != null)
{
return prop.GetValue (target, null);
}
// 反射字段
FieldInfo field = type.GetField (propName,
BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
if (field != null)
{
return field.GetValue (target);
}
return null;
}
private static object GetIndexedValue (object collection, int index)
{
if (collection == null) return null;
MRApplications apps = collection as MRApplications;
if (apps != null)
{
if (index >= 0 && index < apps.Applications.Count)
return apps.Applications [index];
return null;
}
IList list = collection as IList;
if (list != null && index >= 0 && index < list.Count)
return list [index];
PropertyInfo indexer = collection.GetType ().GetProperty ("Item", new [] { typeof (int) });
if (indexer != null)
return indexer.GetValue (collection, new object [] { index });
return null;
}
private static int? GetLength (object obj)
{
if (obj == null) return null;
MRApplications apps = obj as MRApplications;
if (apps != null) return apps.Applications.Count;
MRDependencies deps = obj as MRDependencies;
if (deps != null) return deps.Dependencies.Count;
IList list = obj as IList;
if (list != null) return list.Count;
ICollection coll = obj as ICollection;
if (coll != null) return coll.Count;
return null;
}
private static object SerializeObject (object obj, ManifestReader mr, bool filterBase64)
{
if (obj == null) return null;
Type type = obj.GetType ();
if (type.IsPrimitive || obj is string || obj is decimal || obj is Enum)
return obj;
// MRIdentity
if (type == typeof (MRIdentity))
{
MRIdentity id = (MRIdentity)obj;
return new {
name = id.Name,
publisher = id.Publisher,
version = id.Version.Expression,
architecture = id.ProcessArchitecture.Select (e => {
switch (e)
{
case Architecture.ARM: return "arm";
case Architecture.ARM64: return "arm64";
case Architecture.Neutral: return "neutral";
case Architecture.x64: return "x64";
case Architecture.x86: return "x86";
default: return "unknown";
}
}).ToList (),
familyName = id.FamilyName,
fullName = id.FullName,
resourceId = id.ResourceId
};
}
// MRProperties
if (type == typeof (MRProperties))
{
MRProperties prop = (MRProperties)obj;
return new {
displayName = prop.DisplayName,
publisherDisplayName = prop.Publisher,
description = prop.Description,
logo = prop.Logo,
framework = prop.Framework,
resourcePackage = prop.ResourcePackage
};
}
// MRPrerequisites
if (type == typeof (MRPrerequisites))
{
MRPrerequisites pre = (MRPrerequisites)obj;
return new {
osMinVersion = pre.OSMinVersion,
osMaxVersionTested = pre.OSMaxVersionTested,
_osMinVersion = pre.OSMinVersionDescription,
_osMaxVersionTested = pre.OSMaxVersionDescription
};
}
// MRResources
if (type == typeof (MRResources))
{
MRResources res = (MRResources)obj;
return new {
languages = res.Languages,
scales = res.Scales,
dxFeatureLevels = res.DXFeatures.Select (d => {
switch (d)
{
case DXFeatureLevel.Level9: return 9;
case DXFeatureLevel.Level10: return 10;
case DXFeatureLevel.Level11: return 11;
case DXFeatureLevel.Level12: return 12;
default: return -1;
}
}).ToList ()
};
}
// MRCapabilities
if (type == typeof (MRCapabilities))
{
MRCapabilities caps = (MRCapabilities)obj;
return new {
capabilities = caps.Capabilities,
deviceCapabilities = caps.DeviceCapabilities
};
}
// MRDependencies
if (type == typeof (MRDependencies))
{
MRDependencies deps = (MRDependencies)obj;
return deps.Select (e => new {
name = e.Name,
publisher = e.Publisher,
minVersion = e.Version.ToString ()
}).ToList ();
}
// MRApplications (集合)
if (type == typeof (MRApplications))
{
MRApplications apps = (MRApplications)obj;
return apps.Select (e => SerializeObject (e, mr, filterBase64)).ToList ();
}
// MRApplication (单个应用)
if (type == typeof (MRApplication))
{
MRApplication app = (MRApplication)obj;
var dict = new Dictionary<string, string> (StringComparer.OrdinalIgnoreCase);
foreach (var kv in app)
{
if (kv.Key.IndexOf ("Base64", StringComparison.OrdinalIgnoreCase) >= 0)
continue;
string value = app.NewAt (kv.Key, mr.EnablePri);
if (string.IsNullOrWhiteSpace (value))
value = app.At (kv.Key);
dict [kv.Key] = value;
}
return dict;
}
// IDictionary
IDictionary dictObj = obj as IDictionary;
if (dictObj != null)
{
var result = new Dictionary<string, object> (StringComparer.OrdinalIgnoreCase);
foreach (DictionaryEntry entry in dictObj)
{
string key = entry.Key?.ToString ();
if (string.IsNullOrEmpty (key)) continue;
if (filterBase64 && key.EndsWith ("_Base64", StringComparison.OrdinalIgnoreCase))
continue;
result [key] = SerializeObject (entry.Value, mr, filterBase64);
}
return result;
}
// IEnumerable (非字符串)
if (!(obj is string))
{
IEnumerable enumerable = obj as IEnumerable;
if (enumerable != null)
{
var list = new List<object> ();
foreach (var item in enumerable)
list.Add (SerializeObject (item, mr, filterBase64));
return list;
}
}
// 后备:反射属性
var props = type.GetProperties (BindingFlags.Public | BindingFlags.Instance);
var propDict = new Dictionary<string, object> (StringComparer.OrdinalIgnoreCase);
foreach (var prop in props)
{
if (prop.GetIndexParameters ().Length > 0) continue;
string propName = prop.Name;
if (filterBase64 && propName.EndsWith ("Base64", StringComparison.OrdinalIgnoreCase))
continue;
object val = prop.GetValue (obj, null);
propDict [propName] = SerializeObject (val, mr, filterBase64);
}
return propDict;
}
}
}

View File

@@ -2,13 +2,858 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DataUtils;
using AppxPackage;
using System.IO;
using static AppxPackage.PackageManager;
using Newtonsoft.Json;
using Win32;
namespace PkgCLI
{
class Program
{
public delegate _I_HResult PackageOperation (string filePath, IEnumerable<string> depUris, DeploymentOptions options, PackageProgressCallback progress = null);
static readonly string [] helpArgs = new string [] {
"/?",
"-?",
"help",
"/help",
"-help",
"/h",
"-h"
};
public static StringResXmlDoc res = new StringResXmlDoc (Path.Combine (AppDomain.CurrentDomain.BaseDirectory, "locale\\pkgcli.xml"));
static bool IsHelpParam (string arg) => helpArgs.Contains (arg.Normalize ());
static void PrintVersion ()
{
var verFilePath = Path.Combine (AppDomain.CurrentDomain.BaseDirectory, "version");
var verFileInst = new _I_File (verFilePath);
var verstr = verFileInst.Content?.Trim () ?? "0.0.0.1";
Console.WriteLine (String.Format (res.Get ("PKGCLI_VERSION"), verstr));
}
static void PrintTotalHelp ()
{
Console.WriteLine (res.Get ("PKGCLI_TOTALHELP"));
}
public static bool IsFilePathInList (List<string> filelist, string file)
{
foreach (var f in filelist)
{
if (f.NEquals (file)) return true;
}
return false;
}
public static void AddFiles (List<string> filelist, string file)
{
if (string.IsNullOrWhiteSpace (file)) return;
if (!File.Exists (file)) file = Path.Combine (Environment.CurrentDirectory, file);
if (!File.Exists (file)) return;
var ext = Path.GetExtension (file);
if (ext.NEquals (".txt"))
{
var lines = File.ReadAllLines (file);
foreach (var l in lines)
{
if (string.IsNullOrWhiteSpace (l)) continue;
var line = l.Trim ();
if (!File.Exists (l)) line = Path.Combine (Path.GetDirectoryName (file), l);
if (!File.Exists (line)) continue;
if (!IsFilePathInList (filelist, line))
filelist.Add (line);
}
}
else if (!IsFilePathInList (filelist, file)) filelist.Add (file);
}
public static void AddNStringItems (List<string> strlist, string str)
{
var find = false;
foreach (var l in strlist)
if (l.NEquals (str))
{
find = true;
break;
}
if (!find) strlist.Add (str);
}
public static void ToFormatString (PMPackageInfo pkg, IEnumerable<string> filter)
{
if (pkg == null) return;
var labels = new List<string> ();
var values = new List<string> ();
var id = pkg.Identity;
labels.Add ("Identity:Name"); values.Add (id.Name);
labels.Add ("Identity:Publisher"); values.Add (id.Publisher);
labels.Add ("Identity:FamilyName"); values.Add (id.FamilyName);
labels.Add ("Identity:FullName"); values.Add (id.FullName);
labels.Add ("Identity:PublisherId"); values.Add (id.PublisherId);
labels.Add ("Identity:ResourceId"); values.Add (id.ResourceId);
labels.Add ("Identity:Version"); values.Add (id.Version?.ToString () ?? "");
labels.Add ("Identity:ProcessArchitecture"); values.Add (string.Join (", ", id.ProcessArchitecture));
var prop = pkg.Properties;
labels.Add ("Properties:DisplayName"); values.Add (prop.DisplayName);
labels.Add ("Properties:Description"); values.Add (prop.Description);
labels.Add ("Properties:Publisher"); values.Add (prop.Publisher);
labels.Add ("Properties:Framework"); values.Add (prop.Framework.ToString ());
labels.Add ("Properties:ResourcePackage"); values.Add (prop.ResourcePackage.ToString ());
labels.Add ("Properties:Logo"); values.Add (prop.Logo);
labels.Add ("IsBundle"); values.Add (pkg.IsBundle.ToString ());
labels.Add ("DevelopmentMode"); values.Add (pkg.DevelopmentMode.ToString ());
labels.Add ("InstallLocation"); values.Add (pkg.InstallLocation);
labels.Add ("Users"); values.Add (string.Join ("; ", pkg.Users));
Console.WriteLine ($"[{pkg.Identity.FullName}]");
var indicesToOutput = new List<int> ();
bool outputAll = (filter == null || !filter.Any ());
for (int i = 0; i < labels.Count; i++)
{
if (outputAll)
{
indicesToOutput.Add (i);
}
else
{
string label = labels [i];
foreach (string patternRaw in filter)
{
if (MatchPattern (label, patternRaw))
{
indicesToOutput.Add (i);
break;
}
}
}
}
if (indicesToOutput.Count == 0) return;
int maxLabelLen = 0;
foreach (int i in indicesToOutput)
if (labels [i].Length > maxLabelLen) maxLabelLen = labels [i].Length;
string format = "{0,-" + maxLabelLen + "} = {1}";
foreach (int i in indicesToOutput)
Console.WriteLine (format, labels [i], values [i]);
}
/// <summary>
/// 匹配模式(忽略大小写,首尾空格,支持通配符 *
/// </summary>
private static bool MatchPattern (string text, string pattern)
{
if (string.IsNullOrEmpty (pattern)) return true;
pattern = pattern.Trim ();
text = text ?? "";
if (pattern == "*") return true;
// 忽略大小写
var comparison = StringComparison.OrdinalIgnoreCase;
// 检查通配符位置
bool startsWithStar = pattern.StartsWith ("*");
bool endsWithStar = pattern.EndsWith ("*");
if (startsWithStar && endsWithStar)
{
// *middle* 包含子串
string middle = pattern.Substring (1, pattern.Length - 2);
return text.IndexOf (middle, comparison) >= 0;
}
else if (startsWithStar)
{
// *suffix 以 suffix 结尾
string suffix = pattern.Substring (1);
return text.EndsWith (suffix, comparison);
}
else if (endsWithStar)
{
// prefix* 以 prefix 开头
string prefix = pattern.Substring (0, pattern.Length - 1);
return text.StartsWith (prefix, comparison);
}
else
{
// 精确匹配(忽略大小写)
return string.Equals (text, pattern, comparison);
}
}
/// <summary>
/// 判断字符串是否为有效的包全名 (Package Full Name)
/// 格式: <IdentityName>_<Version>_<ProcessorArchitecture>_<ResourceId>_<PublisherId>
/// 其中 ResourceId 可以为空(表现为连续两个下划线)
/// </summary>
public static bool IsPackageFullName (string fullName)
{
if (string.IsNullOrWhiteSpace (fullName)) return false;
string [] parts = fullName.Split (new char [] { '_' }, StringSplitOptions.None);
if (parts.Length != 5)
return false;
if (string.IsNullOrEmpty (parts [0])) // IdentityName
return false;
if (string.IsNullOrEmpty (parts [1])) // Version
return false;
if (string.IsNullOrEmpty (parts [2])) // ProcessorArchitecture
return false;
if (string.IsNullOrEmpty (parts [4])) // PublisherId
return false;
if (!parts [1].Contains ('.')) return false;
return true;
}
/// <summary>
/// 判断字符串是否为有效的包系列名 (Package Family Name)
/// 格式: <IdentityName>_<PublisherId>
/// </summary>
public static bool IsPackageFamilyName (string familyName)
{
if (string.IsNullOrWhiteSpace (familyName)) return false;
string [] parts = familyName.Split ('_');
if (parts.Length != 2) return false;
if (string.IsNullOrEmpty (parts [0]) || string.IsNullOrEmpty (parts [1]))
return false;
return true;
}
/// <summary>
/// 从 args[startIndex..] 生成安全的命令行字符串
/// </summary>
private static string BuildCommandLine (string [] args, int startIndex)
{
if (args.Length <= startIndex) return null;
var sb = new StringBuilder ();
for (int i = startIndex; i < args.Length; i++)
{
if (i > startIndex) sb.Append (' ');
sb.Append (EscapeArgument (args [i]));
}
return sb.ToString ();
}
/// <summary>
/// 按 Win32 命令行规则转义单个参数
/// </summary>
private static string EscapeArgument (string arg)
{
if (string.IsNullOrEmpty (arg)) return "\"\"";
bool needQuotes = false;
foreach (char c in arg)
{
if (char.IsWhiteSpace (c) || c == '"')
{
needQuotes = true;
break;
}
}
if (!needQuotes) return arg;
var sb = new StringBuilder ();
sb.Append ('"');
foreach (char c in arg)
{
if (c == '"') sb.Append ("\\\"");
else sb.Append (c);
}
sb.Append ('"');
return sb.ToString ();
}
public static readonly string [] configItems = new string [] {
"AppMetadataItems"
};
public static void RefreshConfig ()
{
var conf = new InitConfig (Path.Combine (AppDomain.CurrentDomain.BaseDirectory, "config.ini"));
var sSettings = conf.GetSection ("Settings");
var kAppMetadatas = sSettings.GetKey ("PkgCLI:AppMetadataItems");
var appMd = kAppMetadatas.ReadString ("Id,BackgroundColor,DisplayName,ForegroundText,ShortName,SmallLogo,Square44x44Logo");
var appMdList = (appMd ?? "").Split (',', ';', '|');
for (var i = 0; i < appMdList.Length; i ++)
{
appMdList [i] = appMdList [i].Trim ();
}
PackageReader.UpdateApplicationItems (appMdList);
}
static void Main (string [] args)
{
var currencoding = Console.OutputEncoding;
try
{
//Console.OutputEncoding = Encoding.UTF8;
if (args.Length <= 0 || args.Length >= 1 && IsHelpParam (args [0]))
{
PrintVersion ();
PrintTotalHelp ();
return;
}
var parser = new CliParsing ();
parser.Params = new HashSet<CmdParamName> (new CmdParamName [] {
new CmdParamName ("install", new string [] { "add" }),
new CmdParamName ("register", new string [] { "reg" }),
new CmdParamName ("update", new string [] { "up" }),
new CmdParamName ("stage"),
new CmdParamName ("remove", new string [] { "uninstall" }),
new CmdParamName ("read"),
new CmdParamName ("get"),
new CmdParamName ("find"),
new CmdParamName ("active", new string [] { "launch", "start", "activate" }),
new CmdParamName ("config", new string [] { "conf" }),
new CmdParamName ("version", new string [] { "ver" }),
new CmdParamName ("help", new string [] { "?", "h" }),
new CmdParamName ("developmode", new string [] { "develop" }),
new CmdParamName ("forceappshutdown", new string [] { "forceshutdown" , "appshutdown", "forcesd", "force"}),
new CmdParamName ("installallresources", new string [] {"allresources", "allres"}),
new CmdParamName ("savexml"),
new CmdParamName ("savejson"),
new CmdParamName ("fullname"),
new CmdParamName ("filter"),
new CmdParamName ("package", new string [] { "pkg" }),
new CmdParamName ("manifest", new string [] { "mani" }),
new CmdParamName ("usepri", new string [] { "pri" }),
new CmdParamName ("item"),
new CmdParamName ("set"),
new CmdParamName ("refresh"),
new CmdParamName ("show"),
new CmdParamName ("encoding", new string [] { "en", "charset", "encode" }),
new CmdParamName ("yes", new string [] {"y", "agree"})
});
RefreshConfig ();
var cmds = parser.Parse (args);
if (cmds.ParamContains ("encoding"))
{
#region help text: encoding
if (CliPasingUtils.ParamContains (cmds, "help"))
{
PrintVersion ();
Console.WriteLine (res.Get ("PKGCLI_HELP_ENCODING"));
return;
}
#endregion
try
{
var c = cmds.GetFromId ("encoding");
var i = 0;
var isint = false;
Encoding en = null;
try { i = Convert.ToInt32 (c.Value); isint = true; } catch { isint = false; }
if (isint) en = Encoding.GetEncoding (i);
else en = Encoding.GetEncoding (c.Value);
Console.OutputEncoding = en;
}
catch (Exception ex)
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine (String.Format (res.Get ("PKGCLI_WARNING_ENCODING"), ex.GetType (), ex.Message));
Console.ResetColor ();
}
}
if (CliPasingUtils.ParamsContainsOr (cmds, "install", "register", "update", "stage"))
{
#region help text: install register, update, stage
PrintVersion ();
if (CliPasingUtils.ParamContains (cmds, "help"))
{
Console.WriteLine (res.Get ("PKGCLI_HELP_IRUS"));
return;
}
#endregion
var options = DeploymentOptions.None;
if (CliPasingUtils.ParamContains (cmds, "developmode")) options |= DeploymentOptions.DevelopmentMode;
if (CliPasingUtils.ParamContains (cmds, "forceappshutdown")) options |= DeploymentOptions.ForceAppShutdown;
if (CliPasingUtils.ParamContains (cmds, "installallresources")) options |= DeploymentOptions.InstallAllResources;
var totallist = new List<Tuple<int, string>> ();
var filelist = new List<string> ();
foreach (var f in cmds)
{
if (string.IsNullOrWhiteSpace (f.Id))
{
var file = f.Value;
AddFiles (filelist, file);
}
else
{
switch (f.Id)
{
case "install":
case "register":
case "update":
case "stage":
AddFiles (filelist, f.Value);
break;
}
}
}
foreach (var f in filelist) totallist.Add (new Tuple<int, string> (0, f));
if (cmds.ParamContains ("register") && cmds.ParamContains ("fullname"))
{
foreach (var f in cmds)
{
if (f.Id.NEquals ("fullname"))
{
if (string.IsNullOrWhiteSpace (f.Value))
{
totallist.Add (new Tuple<int, string> (1, f.Value));
}
}
}
}
PackageOperation ope = null;
if (cmds.ParamContains ("install")) ope = AddPackage;
else if (cmds.ParamContains ("register")) ope = RegisterPackage;
else if (cmds.ParamContains ("update")) ope = UpdatePackage;
else if (cmds.ParamContains ("stage")) ope = StagePackage;
for (int i = 0; i < totallist.Count; i++)
{
Console.WriteLine ();
var file = totallist [i];
Console.Write ("\r" + String.Format (res.Get ("PKGCLI_PROGRESS_OPERATION"), i + 1, totallist.Count));
var hr = new _I_HResult (0);
var tempope = ope;
if (file.Item1 == 1)
{
if (cmds.ParamContains ("register")) tempope = RegisterPackageByFullName;
}
hr = tempope (file.Item2, null, options, prog => {
var str = "\r" + String.Format (res.Get ("PKGCLI_PROGRESS_OPERATION_WITHPROGRESS"), i + 1, totallist.Count, prog, (int)((i + prog * 0.01) / totallist.Count * 100));
Console.Write (str);
});
if (hr.Failed)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.Write ("\n" + String.Format (res.Get ("PKGCLI_ERROR_IRUS_EXCEPTION"), i + 1, file.Item2, "0x" + hr.HResult.ToString ("X8"), hr.Message));
Console.ResetColor ();
}
}
Console.WriteLine ("\n" + res.Get ("PKGCLI_COMPLETE_OPERATION"));
return;
}
else if (cmds.ParamsContainsOr ("remove"))
{
#region help text: remove
if (CliPasingUtils.ParamContains (cmds, "help"))
{
PrintVersion ();
Console.WriteLine (res.Get ("PKGCLI_HELP_REMOVE"));
return;
}
#endregion
var list = new List<string> ();
foreach (var c in cmds)
{
if (string.IsNullOrWhiteSpace (c.Id) || c.Id.NEquals ("remove"))
{
if (!string.IsNullOrWhiteSpace (c.Value)) list.Add (c.Value);
}
}
var agreecmd = cmds.GetFromId ("yes");
bool? agree = null;
if (agreecmd != null) agree = true;
if (agree == null)
{
if (list.Count <= 0) agree = true;
else
{
Console.Write (String.Format (res.Get ("PKGCLI_ASK_REMOVE"), list.Count));
var userinput = Console.ReadLine ();
if (userinput.NEquals ("y") || userinput.NEquals ("yes")) agree = true;
else agree = false;
}
}
if (agree == false) throw new OperationCanceledException (res.Get ("PKGCLI_ERROR_USERABORT"));
for (int i = 0; i < list.Count; i++)
{
Console.WriteLine ();
var file = list [i];
Console.Write ("\r" + String.Format (res.Get ("PKGCLI_PROGRESS_OPERATION"), i + 1, list.Count));
var hr = RemovePackage (file, prog => {
var str = "\r" + String.Format (res.Get ("PKGCLI_PROGRESS_OPERATION_WITHPROGRESS"), i + 1, list.Count, prog, (int)((i + prog * 0.01) / list.Count * 100));
Console.Write (str);
});
if (hr.Failed)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.Write ("\n" + String.Format (res.Get ("PKGCLI_ERROR_IRUS_EXCEPTION"), i + 1, file, "0x" + hr.HResult.ToString ("X8"), hr.Message));
Console.ResetColor ();
}
}
Console.WriteLine ("\n" + res.Get ("PKGCLI_COMPLETE_OPERATION"));
return;
}
else if (cmds.ParamsContainsOr ("get"))
{
#region help text: get
if (CliPasingUtils.ParamContains (cmds, "help"))
{
PrintVersion ();
Console.WriteLine (res.Get ("PKGCLI_HELP_GET"));
return;
}
#endregion
var filter = new HashSet<string> (new NormalizeStringComparer ());
if (cmds.ParamContains ("filter"))
{
foreach (var c in cmds)
{
if (c.Id.NEmpty () || c.Id.NEquals ("filter"))
{
var items = c.Value.Split (',', ';');
foreach (var i in items) filter.Add (i);
}
}
}
var hr = GetPackages ();
if (hr.Item1.Failed)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine (String.Format (res.Get ("PKGCLI_ERROR_EXCEPTION"), "0x" + hr.Item1.HResult.ToString ("X8"), hr.Item1.Message));
Console.ResetColor ();
return;
}
foreach (var i in hr.Item2)
{
ToFormatString (i, filter);
Console.WriteLine ();
}
Console.WriteLine ("[Statistic]");
Console.WriteLine ($"Length = {hr.Item2.Count}");
return;
}
else if (cmds.ParamsContainsOr ("find"))
{
#region help text: find
if (CliPasingUtils.ParamContains (cmds, "help"))
{
PrintVersion ();
Console.WriteLine (res.Get ("PKGCLI_HELP_FIND"));
return;
}
#endregion
var names = new List<string> ();
foreach (var c in cmds)
{
if (c.Id.NEmpty ())
{
if (c.Value.NEmpty ()) continue;
names.Add (c.Value);
}
}
var filter = new HashSet<string> (new NormalizeStringComparer ());
if (cmds.ParamContains ("filter"))
{
foreach (var c in cmds)
{
if (c.Id.NEquals ("filter"))
{
var items = c.Value.Split (',', ';');
foreach (var i in items) filter.Add (i);
}
}
}
var result = new List<Tuple<string, Tuple<_I_HResult, List<PMPackageInfo>>>> ();
if (names.Count == 2)
{
result.Add (new Tuple<string, Tuple<_I_HResult, List<PMPackageInfo>>> (names [0], FindPackage (names [0], names [1])));
}
else
{
foreach (var n in names)
{
if (IsPackageFullName (n))
{
result.Add (new Tuple<string, Tuple<_I_HResult, List<PMPackageInfo>>> (n, FindPackageByFullName (n)));
}
else
{
result.Add (new Tuple<string, Tuple<_I_HResult, List<PMPackageInfo>>> (n, FindPackage (n)));
}
}
}
foreach (var r in result)
{
foreach (var l in r.Item2.Item2)
{
ToFormatString (l, filter);
Console.WriteLine ();
}
Console.WriteLine ($"[Statistic:{r.Item1}]");
Console.WriteLine ($"HResult = {"0x" + r.Item2.Item1.HResult.ToString ("X8")}");
Console.WriteLine ($"Message = {Escape.ToEscape (r.Item2.Item1.Message)}");
Console.WriteLine ($"Length = {r.Item2.Item2.Count}");
}
return;
}
else if (cmds.ParamsContainsOr ("active"))
{
#region help text: active
if (CliPasingUtils.ParamContains (cmds, "help"))
{
PrintVersion ();
Console.WriteLine (res.Get ("PKGCLI_HELP_ACTIVATE"));
return;
}
#endregion
foreach (var c in cmds)
{
if (string.IsNullOrWhiteSpace (c.Id) || c.Id.NEquals ("active"))
{
if (c.Value.NEmpty ()) continue;
var i = 0;
for (i = 0; i < args.Length; i++)
{
if (args [i].NNormalize ().IndexOf (c.Value.NNormalize ()) >= 0) break;
}
var hr = ActiveApp (c.Value, BuildCommandLine (args, i + 1));
if (hr.Succeeded) Console.WriteLine (res.Get ("PKGCLI_COMPLETE_DONE"));
else
{
Console.ForegroundColor = ConsoleColor.Red;
Console.Write (String.Format (res.Get ("PKGCLI_ERROR_EXCEPTION"), "0x" + hr.HResult.ToString ("X8"), hr.Message));
Console.ResetColor ();
}
return;
}
}
return;
}
else if (cmds.ParamsContainsOr ("read"))
{
#region help text: read
if (CliPasingUtils.ParamContains (cmds, "help"))
{
PrintVersion ();
Console.WriteLine (res.Get ("PKGCLI_HELP_READ"));
return;
}
#endregion
var filename = "";
var readtype = "";
var savename = "";
var savetype = "default";
CommandParam cmd = null;
cmd = cmds.GetFromId ("manifest");
if (cmd != null)
{
filename = cmd.Value;
readtype = "manifest";
}
cmd = cmds.GetFromId ("package");
if (cmd != null)
{
filename = cmd.Value;
readtype = "package";
}
if (string.IsNullOrWhiteSpace (filename) || !File.Exists (filename))
{
cmd = cmds.GetFromId ("");
if (cmd != null)
{
if (File.Exists (cmd.Value))
{
filename = cmd.Value;
if (string.IsNullOrWhiteSpace (readtype))
{
var ext = Path.GetExtension (cmd.Value);
if (ext.NEquals (".xml") || ext.NEquals (".appxpackage") || ext.NEquals (".msixpackage"))
readtype = "manifest";
else readtype = "package";
}
}
}
}
if (string.IsNullOrWhiteSpace (filename) || !File.Exists (filename))
{
cmd = cmds.GetFromId ("read");
if (cmd != null)
{
if (File.Exists (cmd.Value))
{
filename = cmd.Value;
if (string.IsNullOrWhiteSpace (readtype))
{
var ext = Path.GetExtension (cmd.Value);
if (ext.NEquals (".xml") || ext.NEquals (".appxpackage") || ext.NEquals (".msixpackage"))
readtype = "manifest";
else readtype = "package";
}
}
}
}
if (string.IsNullOrWhiteSpace (filename) || !File.Exists (filename)) throw new FileNotFoundException ();
cmd = cmds.GetFromId ("savexml");
if (cmd != null)
{
savename = cmd.Value;
savetype = "xml";
}
if (string.IsNullOrWhiteSpace (savename))
{
cmd = cmds.GetFromId ("savejson");
if (cmd != null)
{
savename = cmd.Value;
savetype = "json";
}
}
if (string.IsNullOrWhiteSpace (savename))
{
savetype = "ini";
}
switch (readtype)
{
default:
case "package":
{
var pr = new PackageReader (filename);
pr.UsePri = cmds.ParamContains ("usepri");
pr.EnablePri = true;
switch (savetype)
{
default:
case "default":
{
if (cmds.ParamContains ("item"))
{
object value = pr.GetItem (cmds.GetFromId ("item").Value);
if (value is string) Console.WriteLine (value as string);
else if (value is DataUtils.Version) Console.WriteLine (value.ToString ());
else Console.WriteLine (JsonConvert.SerializeObject (value, Formatting.Indented));
}
else Console.WriteLine (JsonConvert.SerializeObject (pr.GetJsonObjectForCli (), Formatting.Indented));
}
break;
case "json":
{
var res = pr.SaveJsonFileCS (savename);
if (res) Console.WriteLine ("Succeeded!");
else Console.WriteLine ("Failed.");
}
break;
case "xml":
{
var res = pr.SaveXmlFileCS (savename);
if (res) Console.WriteLine ("Succeeded!");
else Console.WriteLine ("Failed.");
}
break;
}
}
break;
case "manifest":
{
var mr = new ManifestReader (filename);
mr.UsePri = cmds.ParamContains ("usepri");
mr.EnablePri = true;
if (cmds.ParamContains ("item"))
{
object value = mr.GetItem (cmds.GetFromId ("item").Value);
if (value is string) Console.WriteLine (value as string);
else if (value is DataUtils.Version) Console.WriteLine (value.ToString ());
else Console.WriteLine (JsonConvert.SerializeObject (value, Formatting.Indented));
}
else Console.WriteLine (JsonConvert.SerializeObject (mr.GetJsonObjectForCli (), Formatting.Indented));
//Console.WriteLine (mr.BuildJsonText ());
}
break;
}
return;
}
else if (cmds.ParamsContainsOr ("config"))
{
#region help text: config
if (CliPasingUtils.ParamContains (cmds, "help"))
{
PrintVersion ();
Console.WriteLine (res.Get ("PKGCLI_HELP_CONFIG"));
return;
}
#endregion
var conf = new InitConfig (Path.Combine (AppDomain.CurrentDomain.BaseDirectory, "config.ini"));
var sSettings = conf.GetSection ("Settings");
if (cmds.ParamContains ("refresh")) RefreshConfig ();
else if (cmds.ParamContains ("set"))
{
var cmd = cmds.GetFromId ("set");
var key = cmd.Value;
if (string.IsNullOrWhiteSpace (key)) throw new InvalidOperationException (Program.res.Get ("PKGCLI_ERROR_KEYSTRINGEMPTY"));
var isfind = false;
foreach (var i in configItems)
{
if (i.NEquals (key))
{
isfind = true;
break;
}
}
if (!isfind) throw new KeyNotFoundException (String.Format (Program.res.Get("PKGCLI_ERROR_CANNOTFINDKEY"), key));
var valuelist = new List<string> ();
foreach (var c in cmds)
{
if (c.Id.NEmpty ())
{
if (string.IsNullOrWhiteSpace (c.Value)) continue;
valuelist.Add (c.Value);
}
}
var res = sSettings.GetKey ($"PkgCLI:{key.Trim ()}").Set (valuelist.Join (","));
if (res) Console.WriteLine ("Succeeded!");
else Console.WriteLine ("Failed.");
}
else if (cmds.ParamContains ("show"))
{
var cmd = cmds.GetFromId ("show");
var key = cmd.Value;
if (string.IsNullOrWhiteSpace (key))
{
var dict = new Dictionary<string, string> ();
foreach (var k in configItems)
{
var cKey = sSettings.GetKey ($"PkgCLI:{k}");
dict [k] = cKey.ReadString ("(use default)");
}
Console.WriteLine (dict.FormatDictionaryAligned ("="));
return;
}
var isfind = false;
foreach (var i in configItems)
{
if (i.NEquals (key))
{
isfind = true;
break;
}
}
if (!isfind) throw new KeyNotFoundException (String.Format (Program.res.Get ("PKGCLI_ERROR_CANNOTFINDKEY"), key));
var value = sSettings.GetKey ($"PkgCLI:{key.Trim ()}").ReadString ("(use default)");
Console.WriteLine (value);
}
return;
}
else if (cmds.ParamsContainsOr ("version"))
{
#region help text: version
if (CliPasingUtils.ParamContains (cmds, "help"))
{
PrintVersion ();
Console.WriteLine (res.Get ("PKGCLI_HELP_VERSION"));
return;
}
#endregion
PrintVersion ();
return;
}
else
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine ("Invalid args. Please use \"/help\" to get help.");
Console.ResetColor ();
}
}
catch (Exception ex)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine (String.Format (res.Get ("PKGCLI_ERROR_FINALEXCEPTION"), ex.GetType (), ex.Message, ex.StackTrace));
}
finally
{
Console.ResetColor ();
Console.OutputEncoding = currencoding;
}
}
}
}

112
PkgCLI/Text.cs Normal file
View File

@@ -0,0 +1,112 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
namespace System
{
namespace Text
{
public static class Escape
{
/// <summary>按 JSON 规范对字符串进行转义。</summary>
/// <param name="input">原始字符串。</param>
/// <returns>转义后的 JSON 字符串字面量内容(不含外围双引号)。</returns>
public static string ToEscape (string input)
{
if (input == null) throw new ArgumentNullException (nameof (input));
if (input.Length == 0) return string.Empty;
StringBuilder sb = new StringBuilder (input.Length);
foreach (char c in input)
{
switch (c)
{
case '"': sb.Append ("\\\""); break;
case '\\': sb.Append ("\\\\"); break;
case '\b': sb.Append ("\\b"); break;
case '\f': sb.Append ("\\f"); break;
case '\n': sb.Append ("\\n"); break;
case '\r': sb.Append ("\\r"); break;
case '\t': sb.Append ("\\t"); break;
default:
// 控制字符 (U+0000 - U+001F) 需转义为 \uXXXX
if (c <= 0x1F)
{
sb.Append ("\\u");
sb.Append (((int)c).ToString ("X4"));
}
else
{
sb.Append (c);
}
break;
}
}
return sb.ToString ();
}
/// <summary>按 JSON 规范反转义字符串。</summary>
/// <param name="input">转义后的 JSON 字符串内容(不含外围双引号)。</param>
/// <returns>原始字符串。</returns>
/// <exception cref="FormatException">遇到非法转义序列时抛出。</exception>
public static string Unescape (string input)
{
if (input == null) throw new ArgumentNullException (nameof (input));
if (input.Length == 0) return string.Empty;
StringBuilder sb = new StringBuilder (input.Length);
int i = 0;
while (i < input.Length)
{
char c = input [i];
if (c == '\\')
{
i++;
if (i >= input.Length)
throw new FormatException ("字符串末尾包含不完整的转义序列。");
char next = input [i];
switch (next)
{
case '"': sb.Append ('"'); break;
case '\\': sb.Append ('\\'); break;
case '/': sb.Append ('/'); break; // 允许转义斜杠
case 'b': sb.Append ('\b'); break;
case 'f': sb.Append ('\f'); break;
case 'n': sb.Append ('\n'); break;
case 'r': sb.Append ('\r'); break;
case 't': sb.Append ('\t'); break;
case 'u':
i++;
if (i + 4 > input.Length)
throw new FormatException ("\\u 转义后必须跟随 4 位十六进制数字。");
string hex = input.Substring (i, 4);
int codePoint; // 先声明变量,兼容 C# 5/6
if (!int.TryParse (hex,
NumberStyles.HexNumber,
CultureInfo.InvariantCulture,
out codePoint))
{
throw new FormatException (string.Format ("无效的 Unicode 转义序列: \\u{0}", hex));
}
sb.Append ((char)codePoint);
i += 3; // 循环末尾会再加1因此这里只增加3
break;
default:
throw new FormatException (string.Format ("未识别的转义序列: \\{0}", next));
}
}
else
{
sb.Append (c);
}
i++;
}
return sb.ToString ();
}
}
}
}

4
PkgCLI/packages.config Normal file
View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="13.0.4" targetFramework="net40" />
</packages>

View File

@@ -142,6 +142,11 @@ namespace PriFileFormat
comStream.SetSize (value);
}
}
public override void Close ()
{
comStream = null;
base.Close ();
}
~ComStreamWrapper () { comStream = null;}
}
}

View File

@@ -174,11 +174,15 @@ namespace PriFileFormat
}
~HierarchicalSchemaSection ()
{
Version = null;
foreach (var item in Items) { item.Parent = null; }
foreach (var scope in Scopes) { scope.Parent = null; }
Scopes = null;
Items = null;
try
{
Version = null;
foreach (var item in Items) { item.Parent = null; }
foreach (var scope in Scopes) { scope.Parent = null; }
Scopes = null;
Items = null;
}
catch { }
}
// Checksum computation is buggy for some files

View File

@@ -35,6 +35,25 @@
<Prefer32Bit>false</Prefer32Bit>
<RegisterForComInterop>false</RegisterForComInterop>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<LangVersion>default</LangVersion>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>..\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<LangVersion>default</LangVersion>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
@@ -48,7 +67,6 @@
<Compile Include="ByteSpan.cs" />
<Compile Include="ComStreamWrapper.cs" />
<Compile Include="DataItemSection.cs" />
<Compile Include="DataTree.cs" />
<Compile Include="DecisionInfoSection.cs" />
<Compile Include="HierarchicalSchemaSection.cs" />
<Compile Include="PriDescriptorSection.cs" />

View File

@@ -1,3 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6"/></startup></configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6"/>
</startup>
</configuration>

View File

@@ -30,6 +30,25 @@
<WarningLevel>4</WarningLevel>
<RegisterForComInterop>false</RegisterForComInterop>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<LangVersion>default</LangVersion>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>..\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<LangVersion>default</LangVersion>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />

View File

@@ -4,20 +4,29 @@
<h2>Required runtime libraries</h2>
<ul>
<li>Microsoft .NET Framework 4.5 (may be pre-installed on Windows 8.x and later)</li>
<li>Microsoft .NET Framework 4.6</li>
<li>Microsoft Visual C++ 2013 Redistributable (x86)</li>
<li>Microsoft Visual C++ 2015 Redistributable (x86)</li>
<li>Microsoft .NET Framework 4.6 (x86/ARM)</li>
<li>Microsoft Visual C++ 2013 Redistributable (x86/ARM)</li>
<li>Microsoft Visual C++ 2015 Redistributable (x86/ARM)</li>
</ul>
<h2>Download</h2>
<p>Download the latest release from the Releases section.</p>
<a href="https://github.com/modernw/App-Installer-For-Windows-8.x-Reset/releases" target="_blank"><img src="https://img.shields.io/github/v/release/modernw/App-Installer-For-Windows-8.x-Reset"></a>
<p>Note: There is no official release yet, but the test version still does not have the Pre-released label; this is for testing upgrade functionality. Once the official release is complete, previous versions will be marked as Pre-released.</p>
<p>Note 2: Ensure that .NET Framework 4.6 is installed on your computer, as the runtime libraries automatically installed by the installer may not actually be installed on your system. Therefore, after completing the installation via the installer, be sure to download and run the .NET Framework 4.6 runtime library installer again.</p>
<p>Note 3: The x86 runtime library must be installed, as the program itself is compiled for the x86 architecture. (Unless the program is compiled for the ARM architecture, in which case the ARM runtime library must be installed.)</p>
<a href="https://github.com/modernw/App-Installer-For-Windows-8.x-Reset/releases/tag/0.0.0.0" target="blank">Download Runtime Libraries</a><br>
<a href="https://github.com/modernw/App-Installer-For-Windows-8.x-Reset/releases/download/0.0.0.1/depsinstaller.zip" target="blank">Download Dependencies for Metro Apps</a>
<h2>Attention</h2>
<ul>
<li><del>This program is an x86 program, not an ARM application, not cross-platform, and cannot be used on Windows RT.</del></li>
<li>The program uses some third-party libraries and other GitHub projects, and is completed with the assistance of AI (ChatGTP). This project can be used for learning and communication purposes.</li>
<li>(Important) Internet Explorer must support TLS 1.2 (requiring the use of IE's XMLHttpRequest to retrieve update information), especially IE10. You can do this by opening the "Advanced" tab in Control Panel/Internet Explorer's "Internet Options," finding "Use TLS 1.2" and checking the box, then clicking "OK" and saving. The settings will take effect the next time you open the browser.<br><img width="300" height="395" alt="屏幕截图 2025-12-08 103450" src="https://github.com/user-attachments/assets/69ee21ca-7f47-4d56-8dde-37e5704776c1" /></li>
</ul>
<h2>Special Thanks</h2>
<a href="https://github.com/modernw/App-Installer-For-Windows-8.x-Reset/graphs/contributors">
<!-- Made with [contrib.rocks](https://contrib.rocks). -->
<img src="https://contrib.rocks/image?repo=modernw/App-Installer-For-Windows-8.x-Reset" />
</a>
<hr>
<p>(Translated by Google Translate)</p>
<picture>

View File

@@ -41,7 +41,6 @@
this.Name = "ReaderShell";
this.PageScale = 125;
this.Text = "Form1";
this.WindowIcon = ((System.Drawing.Icon)(resources.GetObject("$this.WindowIcon")));
this.Load += new System.EventHandler(this.ManagerShell_Load);
this.Resize += new System.EventHandler(this.ManagerShell_Resize);
this.ResumeLayout(false);

View File

@@ -28,6 +28,20 @@ namespace Reader
InitSize ();
Text = Bridge.ResXmlStore.StringRes.Get ("READER_APPTITLE");
this.Load += Form_Load;
try
{
if (this is WAShell.ModernForm)
{
this.WindowIcon = new Icon (Path.Combine (AppDomain.CurrentDomain.BaseDirectory, "icons\\32_reader.ico"));
}
}
catch
{
if (this is WAShell.ModernForm)
{
this.WindowIcon = this.Icon;
}
}
}
private void InitSize ()
{

File diff suppressed because it is too large Load Diff

View File

@@ -36,6 +36,24 @@
<PropertyGroup>
<ApplicationIcon>Project1.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<LangVersion>default</LangVersion>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>..\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<LangVersion>default</LangVersion>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />

Binary file not shown.

View File

@@ -0,0 +1,3 @@
The folder stores complete portions of some libraries.
Some libraries, due to their high extensibility, have unused parts. The approach taken in this case is to simplify them. However, for ease of maintenance, the complete libraries are retained.

View File

@@ -29,6 +29,25 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<WarningLevel>2</WarningLevel>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<LangVersion>default</LangVersion>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>..\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<LangVersion>default</LangVersion>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />

View File

@@ -110,7 +110,7 @@
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;HMODULE_MODE_EXE;_CRT_SECURE_NO_WARNINGS;_CRT_NON_CONFORMING_SWPRINTFS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;HMODULE_MODE_EXE;_CRT_SECURE_NO_WARNINGS;_CRT_NON_CONFORMING_SWPRINTFS;RAPIDJSON_ENDIAN=RAPIDJSON_LITTLEENDIAN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<CompileAsManaged>true</CompileAsManaged>
@@ -157,7 +157,7 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;HMODULE_MODE_EXE;_CRT_SECURE_NO_WARNINGS;_CRT_NON_CONFORMING_SWPRINTFS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;HMODULE_MODE_EXE;_CRT_SECURE_NO_WARNINGS;_CRT_NON_CONFORMING_SWPRINTFS;RAPIDJSON_ENDIAN=RAPIDJSON_LITTLEENDIAN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>

View File

@@ -1808,6 +1808,7 @@ std::vector <std::wstring> LoadFileListW (const std::wstring &filePath)
std::wstring line;
while (std::getline (file, line))
{
line = std::wnstring::trim (line);
if (!line.empty () && line.back () == L'\r') line.pop_back ();
if (!line.empty () && !std::wnstring::empty (line) && IsFileExists (line)) result.push_back (line);
auto fullFile = CombinePath (GetFileDirectoryW (filePath), line);

View File

@@ -1,5 +0,0 @@
@echo off
cd /d "%~dp0"
set SCRIPT_DIR=%~dp0
powershell -NoProfile -ExecutionPolicy Bypass -File "%SCRIPT_DIR%ArmBuild.ps1"
pause

View File

@@ -1 +0,0 @@
E:/Profiles/Bruce/Documents/visual studio 2015/Projects/priformatcli/priformatcli/priformatcli.h

1
pkgread/priformatcli.h Normal file
View File

@@ -0,0 +1 @@
E:/Profiles/Bruce/Documents/visual studio 2015/Projects/priformatcli/priformatcli/priformatcli.h

View File

@@ -269,7 +269,7 @@ std::string GetSuitableLanguageValue (const std::map <std::nstring, std::string>
if (map.empty ()) return "";
std::string ret = GetSuitableLanguageValue (map, pugi::as_utf8 (GetComputerLocaleCodeW ()));
if (ret.empty ()) ret = GetSuitableLanguageValue (map, "en-US");
if (ret.empty ()) ret = map.begin ()->second;
//if (ret.empty ()) ret = map.begin ()->second;
return ret;
}
struct xmldoc
@@ -323,7 +323,8 @@ std::wstring GetCapabilityDisplayName (const std::wstring &capname)
{
for (auto &it : g_nameToId)
{
if (it.first == searchname) return GetRCStringSW (it.second);
if (it.first == searchname)
return GetRCStringSW (it.second);
}
}
else return ret;

Binary file not shown.

View File

@@ -0,0 +1,205 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{33D91B58-1981-4A3C-B4D1-86EE406CDE12}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>priformatcli</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<CLRSupport>true</CLRSupport>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<CLRSupport>true</CLRSupport>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<CLRSupport>true</CLRSupport>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<CLRSupport>true</CLRSupport>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;PRIFORMATCLI_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;PRIFORMATCLI_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>
</AdditionalLibraryDirectories>
<AdditionalDependencies>shlwapi.lib;version.lib;dwmapi.lib;winhttp.lib;Psapi.lib;advapi32.lib;gdi32.lib;comdlg32.lib;shell32.lib;ole32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;PRIFORMATCLI_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;PRIFORMATCLI_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>
</AdditionalLibraryDirectories>
<AdditionalDependencies>shlwapi.lib;version.lib;dwmapi.lib;winhttp.lib;Psapi.lib;advapi32.lib;gdi32.lib;comdlg32.lib;shell32.lib;ole32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<Text Include="ReadMe.txt" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="localeex.h" />
<ClInclude Include="mpstr.h" />
<ClInclude Include="nstring.h" />
<ClInclude Include="prifile.h" />
<ClInclude Include="priformatcli.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="stdafx.h" />
<ClInclude Include="strcmp.h" />
<ClInclude Include="syncutil.h" />
<ClInclude Include="targetver.h" />
<ClInclude Include="themeinfo.h" />
<ClInclude Include="typestrans.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp">
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">false</CompileAsManaged>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
</PrecompiledHeader>
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged>
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">false</CompileAsManaged>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
</PrecompiledHeader>
</ClCompile>
<ClCompile Include="priformatcli.cpp" />
<ClCompile Include="stdafx.cpp" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="priformatcli.rc" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\PriFileFormat\PriFile.csproj">
<Project>{ef4012d4-ef08-499c-b803-177739350b2d}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -381,6 +381,7 @@ void DestroyPriFileInstance (PCSPRIFILE pFilePri)
if (!pFilePri) return;
try
{
#ifdef ELDER_FUNC
CreateScopedLock (g_threadlock);
auto it = g_tasklist.find (pFilePri);
if (it != g_tasklist.end ())
@@ -388,6 +389,7 @@ void DestroyPriFileInstance (PCSPRIFILE pFilePri)
it->second.bIsRunning = false;
g_tasklist.erase (it);
}
#endif
IntPtr handlePtr = IntPtr (pFilePri);
System::Runtime::InteropServices::GCHandle handle = System::Runtime::InteropServices::GCHandle::FromIntPtr (handlePtr);
PriFileInst ^inst = safe_cast <PriFileInst ^> (handle.Target);

View File

@@ -224,7 +224,7 @@ typedef class prifile
{
LPWSTR lpstr = nullptr;
reltask release ([&lpstr] () {
if (lpstr) free (lpstr);
if (lpstr) PriFormatFreeString (lpstr);
lpstr = nullptr;
});
lpstr = GetPriResource (m_hPriFile, resname.c_str ());

View File

@@ -127,6 +127,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;PRIFORMATCLI_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<WholeProgramOptimization>true</WholeProgramOptimization>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>

Binary file not shown.

Binary file not shown.

View File

@@ -418,6 +418,15 @@ public ref class _I_System
return (error == ERROR_OLD_WIN_VERSION) ? FALSE : FALSE;
}
}
property int ProcessorArchitecture
{
int get ()
{
SYSTEM_INFO si;
GetNativeSystemInfo (&si);
return si.wProcessorArchitecture;
}
}
};
public ref class _I_System2: public _I_System
{
@@ -1208,6 +1217,14 @@ public ref class MainHtmlWnd: public System::Windows::Forms::Form, public IScrip
th->Start ();
}
bool Kill (String ^filename, bool allproc, bool onlyname) { return KillProcessByFilePath (MPStringToStdW (filename), allproc, onlyname); }
bool Start (String ^filename, String ^args)
{
LPCWSTR lpArgs = (args && args->Length) ? MPStringToPtrW (args) : nullptr;
HINSTANCE result = ShellExecuteW (nullptr, L"open", MPStringToStdW (filename).c_str (), lpArgs, nullptr, SW_SHOWNORMAL);
if (reinterpret_cast <intptr_t> (result) <= 32) return false;
return true;
}
bool Open (String ^url) { return Start (url, nullptr); }
};
[ComVisible (true)]
ref class _I_ResourcePri

View File

@@ -112,7 +112,7 @@
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;HMODULE_MODE_EXE;_CRT_SECURE_NO_WARNINGS;_CRT_NON_CONFORMING_SWPRINTFS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;HMODULE_MODE_EXE;_CRT_SECURE_NO_WARNINGS;_CRT_NON_CONFORMING_SWPRINTFS;RAPIDJSON_ENDIAN=RAPIDJSON_LITTLEENDIAN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
@@ -154,7 +154,7 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;HMODULE_MODE_EXE;_CRT_SECURE_NO_WARNINGS;_CRT_NON_CONFORMING_SWPRINTFS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;HMODULE_MODE_EXE;_CRT_SECURE_NO_WARNINGS;_CRT_NON_CONFORMING_SWPRINTFS;RAPIDJSON_ENDIAN=RAPIDJSON_LITTLEENDIAN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 707 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 707 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 570 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -372,7 +372,7 @@
supportDisplay.classList.add("not-support");
supportDisplay.classList.remove("support");
}
supportDisplay.setAttribute("title", strutils.format("OS Min Version: {0}, Architecture: {1}", support.showOsminversionText, support.showArchitectureText));
supportDisplay.setAttribute("title", strutils.format(Bridge.Resources.byname("IDS_PREINSTALL_SUITCONDITION"), support.showOsminversionText, support.showArchitectureText));
var hres = Bridge.Package.installResult(this.value);
if (hres && hres.failed) {
reason.textContent = hres.message;
@@ -394,6 +394,27 @@
<p data-res-byname="IDS_FAILED_REASONNAME"></p>
<textarea class="win-textarea" readonly></textarea>
</div>
<script>
(function(global) {
var pageContainerPage = document.getElementById("page-container").querySelector(".page");
var pkgversion = pageContainerPage.querySelector(".pkgversion");
var reason = document.querySelector(".reason.installfailed");
var reasonTextArea = reason.querySelector("textarea");
var reasonLabel = reason.querySelector("p");
var eventutils = Windows.UI.Event.Util;
var eventmonitor = Windows.UI.Event.Monitor;
function resizeAndPositionEvent(e) {
reason.style.height = "";
var controlsContainer = pageContainerPage.querySelector(".controls");
var maxHeight = pageContainerPage.getBoundingClientRect().height - pkgversion.getBoundingClientRect().top - pkgversion.getBoundingClientRect().height * 2 - controlsContainer.getBoundingClientRect().height;
var suitHeight = reasonTextArea.offsetTop + reasonTextArea.scrollHeight;
reason.style.height = parseInt(Math.min(maxHeight, suitHeight)) + "px";
}
eventmonitor.observe(pkgversion, "position", resizeAndPositionEvent);
eventmonitor.observe(pageContainerPage, "resize", resizeAndPositionEvent);
})(this);
</script>
<div class="controls">
<div class="checkbox">
<input type="checkbox" id="preinst-enablelaunch" class="win-checkbox" style="margin-left: 0;">

View File

@@ -442,6 +442,8 @@
createShortcutButton.setAttribute("data-app-user-model-id", item.AppUserModelID);
createShortcutButton.textContent = strres.get("MANAGER_APP_SHORTCUTCREATE_TITLE");
createShortcutButton.style.marginRight = "10px";
appItem.setAttribute("title", item.Id);
appItem.setAttribute("aria-label", item.DisplayName || item.ShortName);
Windows.UI.Event.Util.addEvent(launchButton, "click", function(e) {
e.stopPropagation();
Package.manager.active(this.getAttribute("data-app-user-model-id"));

View File

@@ -1,8 +0,0 @@
*.txt text
*.js text
*.html text
*.md text
*.json text
*.yml text
*.css text
*.svg text

View File

@@ -1,8 +0,0 @@
/node_modules
/npm-debug.log
/test*.html
.tern-*
*~
*.swp
.idea
*.iml

View File

@@ -1,3 +0,0 @@
language: node_js
node_js:
- 0.10

View File

@@ -1,76 +0,0 @@
# How to contribute
- [Getting help](#getting-help-)
- [Submitting bug reports](#submitting-bug-reports-)
- [Contributing code](#contributing-code-)
## Getting help
Community discussion, questions, and informal bug reporting is done on the
[discuss.CodeMirror forum](http://discuss.codemirror.net).
## Submitting bug reports
The preferred way to report bugs is to use the
[GitHub issue tracker](http://github.com/codemirror/CodeMirror/issues). Before
reporting a bug, read these pointers.
**Note:** The issue tracker is for *bugs*, not requests for help. Questions
should be asked on the
[discuss.CodeMirror forum](http://discuss.codemirror.net) instead.
### Reporting bugs effectively
- CodeMirror is maintained by volunteers. They don't owe you anything, so be
polite. Reports with an indignant or belligerent tone tend to be moved to the
bottom of the pile.
- Include information about **the browser in which the problem occurred**. Even
if you tested several browsers, and the problem occurred in all of them,
mention this fact in the bug report. Also include browser version numbers and
the operating system that you're on.
- Mention which release of CodeMirror you're using. Preferably, try also with
the current development snapshot, to ensure the problem has not already been
fixed.
- Mention very precisely what went wrong. "X is broken" is not a good bug
report. What did you expect to happen? What happened instead? Describe the
exact steps a maintainer has to take to make the problem occur. We can not
fix something that we can not observe.
- If the problem can not be reproduced in any of the demos included in the
CodeMirror distribution, please provide an HTML document that demonstrates
the problem. The best way to do this is to go to
[jsbin.com](http://jsbin.com/ihunin/edit), enter it there, press save, and
include the resulting link in your bug report.
## Contributing code
- Make sure you have a [GitHub Account](https://github.com/signup/free)
- Fork [CodeMirror](https://github.com/codemirror/CodeMirror/)
([how to fork a repo](https://help.github.com/articles/fork-a-repo))
- Make your changes
- If your changes are easy to test or likely to regress, add tests.
Tests for the core go into `test/test.js`, some modes have their own
test suite under `mode/XXX/test.js`. Feel free to add new test
suites to modes that don't have one yet (be sure to link the new
tests into `test/index.html`).
- Follow the general code style of the rest of the project (see
below). Run `bin/lint` to verify that the linter is happy.
- Make sure all tests pass. Visit `test/index.html` in your browser to
run them.
- Submit a pull request
([how to create a pull request](https://help.github.com/articles/fork-a-repo))
### Coding standards
- 2 spaces per indentation level, no tabs.
- Include semicolons after statements.
- Note that the linter (`bin/lint`) which is run after each commit
complains about unused variables and functions. Prefix their names
with an underscore to muffle it.
- CodeMirror does *not* follow JSHint or JSLint prescribed style.
Patches that try to 'fix' code to pass one of these linters will be
unceremoniously discarded.

View File

@@ -1,12 +0,0 @@
# CodeMirror
[![Build Status](https://travis-ci.org/codemirror/CodeMirror.svg)](https://travis-ci.org/codemirror/CodeMirror)
[![NPM version](https://img.shields.io/npm/v/codemirror.svg)](https://www.npmjs.org/package/codemirror)
[Funding status: ![maintainer happiness](https://marijnhaverbeke.nl/fund/status_s.png)](https://marijnhaverbeke.nl/fund/)
CodeMirror is a JavaScript component that provides a code editor in
the browser. When a mode is available for the language you are coding
in, it will color your code, and optionally help with indentation.
The project page is http://codemirror.net
The manual is at http://codemirror.net/doc/manual.html
The contributing guidelines are in [CONTRIBUTING.md](https://github.com/codemirror/CodeMirror/blob/master/CONTRIBUTING.md)

View File

@@ -1,32 +0,0 @@
.CodeMirror-dialog {
position: absolute;
left: 0; right: 0;
background: white;
z-index: 15;
padding: .1em .8em;
overflow: hidden;
color: #333;
}
.CodeMirror-dialog-top {
border-bottom: 1px solid #eee;
top: 0;
}
.CodeMirror-dialog-bottom {
border-top: 1px solid #eee;
bottom: 0;
}
.CodeMirror-dialog input {
border: none;
outline: none;
background: transparent;
width: 20em;
color: inherit;
font-family: monospace;
}
.CodeMirror-dialog button {
font-size: 70%;
}

View File

@@ -1,155 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Open simple dialogs on top of an editor. Relies on dialog.css.
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
function dialogDiv(cm, template, bottom) {
var wrap = cm.getWrapperElement();
var dialog;
dialog = wrap.appendChild(document.createElement("div"));
if (bottom)
dialog.className = "CodeMirror-dialog CodeMirror-dialog-bottom";
else
dialog.className = "CodeMirror-dialog CodeMirror-dialog-top";
if (typeof template == "string") {
dialog.innerHTML = template;
} else { // Assuming it's a detached DOM element.
dialog.appendChild(template);
}
return dialog;
}
function closeNotification(cm, newVal) {
if (cm.state.currentNotificationClose)
cm.state.currentNotificationClose();
cm.state.currentNotificationClose = newVal;
}
CodeMirror.defineExtension("openDialog", function(template, callback, options) {
if (!options) options = {};
closeNotification(this, null);
var dialog = dialogDiv(this, template, options.bottom);
var closed = false, me = this;
function close(newVal) {
if (typeof newVal == 'string') {
inp.value = newVal;
} else {
if (closed) return;
closed = true;
dialog.parentNode.removeChild(dialog);
me.focus();
if (options.onClose) options.onClose(dialog);
}
}
var inp = dialog.getElementsByTagName("input")[0], button;
if (inp) {
if (options.value) {
inp.value = options.value;
inp.select();
}
if (options.onInput)
CodeMirror.on(inp, "input", function(e) { options.onInput(e, inp.value, close);});
if (options.onKeyUp)
CodeMirror.on(inp, "keyup", function(e) {options.onKeyUp(e, inp.value, close);});
CodeMirror.on(inp, "keydown", function(e) {
if (options && options.onKeyDown && options.onKeyDown(e, inp.value, close)) { return; }
if (e.keyCode == 27 || (options.closeOnEnter !== false && e.keyCode == 13)) {
inp.blur();
CodeMirror.e_stop(e);
close();
}
if (e.keyCode == 13) callback(inp.value, e);
});
if (options.closeOnBlur !== false) CodeMirror.on(inp, "blur", close);
inp.focus();
} else if (button = dialog.getElementsByTagName("button")[0]) {
CodeMirror.on(button, "click", function() {
close();
me.focus();
});
if (options.closeOnBlur !== false) CodeMirror.on(button, "blur", close);
button.focus();
}
return close;
});
CodeMirror.defineExtension("openConfirm", function(template, callbacks, options) {
closeNotification(this, null);
var dialog = dialogDiv(this, template, options && options.bottom);
var buttons = dialog.getElementsByTagName("button");
var closed = false, me = this, blurring = 1;
function close() {
if (closed) return;
closed = true;
dialog.parentNode.removeChild(dialog);
me.focus();
}
buttons[0].focus();
for (var i = 0; i < buttons.length; ++i) {
var b = buttons[i];
(function(callback) {
CodeMirror.on(b, "click", function(e) {
CodeMirror.e_preventDefault(e);
close();
if (callback) callback(me);
});
})(callbacks[i]);
CodeMirror.on(b, "blur", function() {
--blurring;
setTimeout(function() { if (blurring <= 0) close(); }, 200);
});
CodeMirror.on(b, "focus", function() { ++blurring; });
}
});
/*
* openNotification
* Opens a notification, that can be closed with an optional timer
* (default 5000ms timer) and always closes on click.
*
* If a notification is opened while another is opened, it will close the
* currently opened one and open the new one immediately.
*/
CodeMirror.defineExtension("openNotification", function(template, options) {
closeNotification(this, close);
var dialog = dialogDiv(this, template, options && options.bottom);
var closed = false, doneTimer;
var duration = options && typeof options.duration !== "undefined" ? options.duration : 5000;
function close() {
if (closed) return;
closed = true;
clearTimeout(doneTimer);
dialog.parentNode.removeChild(dialog);
}
CodeMirror.on(dialog, 'click', function(e) {
CodeMirror.e_preventDefault(e);
close();
});
if (duration)
doneTimer = setTimeout(close, duration);
return close;
});
});

View File

@@ -1,112 +0,0 @@
.CodeMirror-merge {
position: relative;
border: 1px solid #ddd;
white-space: pre;
}
.CodeMirror-merge, .CodeMirror-merge .CodeMirror {
height: 350px;
}
.CodeMirror-merge-2pane .CodeMirror-merge-pane { width: 47%; }
.CodeMirror-merge-2pane .CodeMirror-merge-gap { width: 6%; }
.CodeMirror-merge-3pane .CodeMirror-merge-pane { width: 31%; }
.CodeMirror-merge-3pane .CodeMirror-merge-gap { width: 3.5%; }
.CodeMirror-merge-pane {
display: inline-block;
white-space: normal;
vertical-align: top;
}
.CodeMirror-merge-pane-rightmost {
position: absolute;
right: 0px;
z-index: 1;
}
.CodeMirror-merge-gap {
z-index: 2;
display: inline-block;
height: 100%;
-moz-box-sizing: border-box;
box-sizing: border-box;
overflow: hidden;
border-left: 1px solid #ddd;
border-right: 1px solid #ddd;
position: relative;
background: #f8f8f8;
}
.CodeMirror-merge-scrolllock-wrap {
position: absolute;
bottom: 0; left: 50%;
}
.CodeMirror-merge-scrolllock {
position: relative;
left: -50%;
cursor: pointer;
color: #555;
line-height: 1;
}
.CodeMirror-merge-copybuttons-left, .CodeMirror-merge-copybuttons-right {
position: absolute;
left: 0; top: 0;
right: 0; bottom: 0;
line-height: 1;
}
.CodeMirror-merge-copy {
position: absolute;
cursor: pointer;
color: #44c;
}
.CodeMirror-merge-copy-reverse {
position: absolute;
cursor: pointer;
color: #44c;
}
.CodeMirror-merge-copybuttons-left .CodeMirror-merge-copy { left: 2px; }
.CodeMirror-merge-copybuttons-right .CodeMirror-merge-copy { right: 2px; }
.CodeMirror-merge-r-inserted, .CodeMirror-merge-l-inserted {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAACCAYAAACddGYaAAAAGUlEQVQI12MwuCXy3+CWyH8GBgYGJgYkAABZbAQ9ELXurwAAAABJRU5ErkJggg==);
background-position: bottom left;
background-repeat: repeat-x;
}
.CodeMirror-merge-r-deleted, .CodeMirror-merge-l-deleted {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAACCAYAAACddGYaAAAAGUlEQVQI12M4Kyb2/6yY2H8GBgYGJgYkAABURgPz6Ks7wQAAAABJRU5ErkJggg==);
background-position: bottom left;
background-repeat: repeat-x;
}
.CodeMirror-merge-r-chunk { background: #ffffe0; }
.CodeMirror-merge-r-chunk-start { border-top: 1px solid #ee8; }
.CodeMirror-merge-r-chunk-end { border-bottom: 1px solid #ee8; }
.CodeMirror-merge-r-connect { fill: #ffffe0; stroke: #ee8; stroke-width: 1px; }
.CodeMirror-merge-l-chunk { background: #eef; }
.CodeMirror-merge-l-chunk-start { border-top: 1px solid #88e; }
.CodeMirror-merge-l-chunk-end { border-bottom: 1px solid #88e; }
.CodeMirror-merge-l-connect { fill: #eef; stroke: #88e; stroke-width: 1px; }
.CodeMirror-merge-l-chunk.CodeMirror-merge-r-chunk { background: #dfd; }
.CodeMirror-merge-l-chunk-start.CodeMirror-merge-r-chunk-start { border-top: 1px solid #4e4; }
.CodeMirror-merge-l-chunk-end.CodeMirror-merge-r-chunk-end { border-bottom: 1px solid #4e4; }
.CodeMirror-merge-collapsed-widget:before {
content: "(...)";
}
.CodeMirror-merge-collapsed-widget {
cursor: pointer;
color: #88b;
background: #eef;
border: 1px solid #ddf;
font-size: 90%;
padding: 0 3px;
border-radius: 4px;
}
.CodeMirror-merge-collapsed-line .CodeMirror-gutter-elt { display: none; }

View File

@@ -1,735 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// declare global: diff_match_patch, DIFF_INSERT, DIFF_DELETE, DIFF_EQUAL
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("diff_match_patch"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "diff_match_patch"], mod);
else // Plain browser env
mod(CodeMirror, diff_match_patch);
})(function(CodeMirror, diff_match_patch) {
"use strict";
var Pos = CodeMirror.Pos;
var svgNS = "http://www.w3.org/2000/svg";
function DiffView(mv, type) {
this.mv = mv;
this.type = type;
this.classes = type == "left"
? {chunk: "CodeMirror-merge-l-chunk",
start: "CodeMirror-merge-l-chunk-start",
end: "CodeMirror-merge-l-chunk-end",
insert: "CodeMirror-merge-l-inserted",
del: "CodeMirror-merge-l-deleted",
connect: "CodeMirror-merge-l-connect"}
: {chunk: "CodeMirror-merge-r-chunk",
start: "CodeMirror-merge-r-chunk-start",
end: "CodeMirror-merge-r-chunk-end",
insert: "CodeMirror-merge-r-inserted",
del: "CodeMirror-merge-r-deleted",
connect: "CodeMirror-merge-r-connect"};
}
DiffView.prototype = {
constructor: DiffView,
init: function(pane, orig, options) {
this.edit = this.mv.edit;
this.orig = CodeMirror(pane, copyObj({value: orig, readOnly: !this.mv.options.allowEditingOriginals}, copyObj(options)));
this.diff = getDiff(asString(orig), asString(options.value));
this.chunks = getChunks(this.diff);
this.diffOutOfDate = this.dealigned = false;
this.showDifferences = options.showDifferences !== false;
this.forceUpdate = registerUpdate(this);
setScrollLock(this, true, false);
registerScroll(this);
},
setShowDifferences: function(val) {
val = val !== false;
if (val != this.showDifferences) {
this.showDifferences = val;
this.forceUpdate("full");
}
}
};
function ensureDiff(dv) {
if (dv.diffOutOfDate) {
dv.diff = getDiff(dv.orig.getValue(), dv.edit.getValue());
dv.chunks = getChunks(dv.diff);
dv.diffOutOfDate = false;
CodeMirror.signal(dv.edit, "updateDiff", dv.diff);
}
}
var updating = false;
function registerUpdate(dv) {
var edit = {from: 0, to: 0, marked: []};
var orig = {from: 0, to: 0, marked: []};
var debounceChange, updatingFast = false;
function update(mode) {
updating = true;
updatingFast = false;
if (mode == "full") {
if (dv.svg) clear(dv.svg);
if (dv.copyButtons) clear(dv.copyButtons);
clearMarks(dv.edit, edit.marked, dv.classes);
clearMarks(dv.orig, orig.marked, dv.classes);
edit.from = edit.to = orig.from = orig.to = 0;
}
ensureDiff(dv);
if (dv.showDifferences) {
updateMarks(dv.edit, dv.diff, edit, DIFF_INSERT, dv.classes);
updateMarks(dv.orig, dv.diff, orig, DIFF_DELETE, dv.classes);
}
makeConnections(dv);
if (dv.mv.options.connect == "align")
alignChunks(dv);
updating = false;
}
function setDealign(fast) {
if (updating) return;
dv.dealigned = true;
set(fast);
}
function set(fast) {
if (updating || updatingFast) return;
clearTimeout(debounceChange);
if (fast === true) updatingFast = true;
debounceChange = setTimeout(update, fast === true ? 20 : 250);
}
function change(_cm, change) {
if (!dv.diffOutOfDate) {
dv.diffOutOfDate = true;
edit.from = edit.to = orig.from = orig.to = 0;
}
// Update faster when a line was added/removed
setDealign(change.text.length - 1 != change.to.line - change.from.line);
}
dv.edit.on("change", change);
dv.orig.on("change", change);
dv.edit.on("markerAdded", setDealign);
dv.edit.on("markerCleared", setDealign);
dv.orig.on("markerAdded", setDealign);
dv.orig.on("markerCleared", setDealign);
dv.edit.on("viewportChange", function() { set(false); });
dv.orig.on("viewportChange", function() { set(false); });
update();
return update;
}
function registerScroll(dv) {
dv.edit.on("scroll", function() {
syncScroll(dv, DIFF_INSERT) && makeConnections(dv);
});
dv.orig.on("scroll", function() {
syncScroll(dv, DIFF_DELETE) && makeConnections(dv);
});
}
function syncScroll(dv, type) {
// Change handler will do a refresh after a timeout when diff is out of date
if (dv.diffOutOfDate) return false;
if (!dv.lockScroll) return true;
var editor, other, now = +new Date;
if (type == DIFF_INSERT) { editor = dv.edit; other = dv.orig; }
else { editor = dv.orig; other = dv.edit; }
// Don't take action if the position of this editor was recently set
// (to prevent feedback loops)
if (editor.state.scrollSetBy == dv && (editor.state.scrollSetAt || 0) + 50 > now) return false;
var sInfo = editor.getScrollInfo();
if (dv.mv.options.connect == "align") {
targetPos = sInfo.top;
} else {
var halfScreen = .5 * sInfo.clientHeight, midY = sInfo.top + halfScreen;
var mid = editor.lineAtHeight(midY, "local");
var around = chunkBoundariesAround(dv.chunks, mid, type == DIFF_INSERT);
var off = getOffsets(editor, type == DIFF_INSERT ? around.edit : around.orig);
var offOther = getOffsets(other, type == DIFF_INSERT ? around.orig : around.edit);
var ratio = (midY - off.top) / (off.bot - off.top);
var targetPos = (offOther.top - halfScreen) + ratio * (offOther.bot - offOther.top);
var botDist, mix;
// Some careful tweaking to make sure no space is left out of view
// when scrolling to top or bottom.
if (targetPos > sInfo.top && (mix = sInfo.top / halfScreen) < 1) {
targetPos = targetPos * mix + sInfo.top * (1 - mix);
} else if ((botDist = sInfo.height - sInfo.clientHeight - sInfo.top) < halfScreen) {
var otherInfo = other.getScrollInfo();
var botDistOther = otherInfo.height - otherInfo.clientHeight - targetPos;
if (botDistOther > botDist && (mix = botDist / halfScreen) < 1)
targetPos = targetPos * mix + (otherInfo.height - otherInfo.clientHeight - botDist) * (1 - mix);
}
}
other.scrollTo(sInfo.left, targetPos);
other.state.scrollSetAt = now;
other.state.scrollSetBy = dv;
return true;
}
function getOffsets(editor, around) {
var bot = around.after;
if (bot == null) bot = editor.lastLine() + 1;
return {top: editor.heightAtLine(around.before || 0, "local"),
bot: editor.heightAtLine(bot, "local")};
}
function setScrollLock(dv, val, action) {
dv.lockScroll = val;
if (val && action != false) syncScroll(dv, DIFF_INSERT) && makeConnections(dv);
dv.lockButton.innerHTML = val ? "\u21db\u21da" : "\u21db&nbsp;&nbsp;\u21da";
}
// Updating the marks for editor content
function clearMarks(editor, arr, classes) {
for (var i = 0; i < arr.length; ++i) {
var mark = arr[i];
if (mark instanceof CodeMirror.TextMarker) {
mark.clear();
} else if (mark.parent) {
editor.removeLineClass(mark, "background", classes.chunk);
editor.removeLineClass(mark, "background", classes.start);
editor.removeLineClass(mark, "background", classes.end);
}
}
arr.length = 0;
}
// FIXME maybe add a margin around viewport to prevent too many updates
function updateMarks(editor, diff, state, type, classes) {
var vp = editor.getViewport();
editor.operation(function() {
if (state.from == state.to || vp.from - state.to > 20 || state.from - vp.to > 20) {
clearMarks(editor, state.marked, classes);
markChanges(editor, diff, type, state.marked, vp.from, vp.to, classes);
state.from = vp.from; state.to = vp.to;
} else {
if (vp.from < state.from) {
markChanges(editor, diff, type, state.marked, vp.from, state.from, classes);
state.from = vp.from;
}
if (vp.to > state.to) {
markChanges(editor, diff, type, state.marked, state.to, vp.to, classes);
state.to = vp.to;
}
}
});
}
function markChanges(editor, diff, type, marks, from, to, classes) {
var pos = Pos(0, 0);
var top = Pos(from, 0), bot = editor.clipPos(Pos(to - 1));
var cls = type == DIFF_DELETE ? classes.del : classes.insert;
function markChunk(start, end) {
var bfrom = Math.max(from, start), bto = Math.min(to, end);
for (var i = bfrom; i < bto; ++i) {
var line = editor.addLineClass(i, "background", classes.chunk);
if (i == start) editor.addLineClass(line, "background", classes.start);
if (i == end - 1) editor.addLineClass(line, "background", classes.end);
marks.push(line);
}
// When the chunk is empty, make sure a horizontal line shows up
if (start == end && bfrom == end && bto == end) {
if (bfrom)
marks.push(editor.addLineClass(bfrom - 1, "background", classes.end));
else
marks.push(editor.addLineClass(bfrom, "background", classes.start));
}
}
var chunkStart = 0;
for (var i = 0; i < diff.length; ++i) {
var part = diff[i], tp = part[0], str = part[1];
if (tp == DIFF_EQUAL) {
var cleanFrom = pos.line + (startOfLineClean(diff, i) ? 0 : 1);
moveOver(pos, str);
var cleanTo = pos.line + (endOfLineClean(diff, i) ? 1 : 0);
if (cleanTo > cleanFrom) {
if (i) markChunk(chunkStart, cleanFrom);
chunkStart = cleanTo;
}
} else {
if (tp == type) {
var end = moveOver(pos, str, true);
var a = posMax(top, pos), b = posMin(bot, end);
if (!posEq(a, b))
marks.push(editor.markText(a, b, {className: cls}));
pos = end;
}
}
}
if (chunkStart <= pos.line) markChunk(chunkStart, pos.line + 1);
}
// Updating the gap between editor and original
function makeConnections(dv) {
if (!dv.showDifferences) return;
if (dv.svg) {
clear(dv.svg);
var w = dv.gap.offsetWidth;
attrs(dv.svg, "width", w, "height", dv.gap.offsetHeight);
}
if (dv.copyButtons) clear(dv.copyButtons);
var vpEdit = dv.edit.getViewport(), vpOrig = dv.orig.getViewport();
var sTopEdit = dv.edit.getScrollInfo().top, sTopOrig = dv.orig.getScrollInfo().top;
for (var i = 0; i < dv.chunks.length; i++) {
var ch = dv.chunks[i];
if (ch.editFrom <= vpEdit.to && ch.editTo >= vpEdit.from &&
ch.origFrom <= vpOrig.to && ch.origTo >= vpOrig.from)
drawConnectorsForChunk(dv, ch, sTopOrig, sTopEdit, w);
}
}
function getMatchingOrigLine(editLine, chunks) {
var editStart = 0, origStart = 0;
for (var i = 0; i < chunks.length; i++) {
var chunk = chunks[i];
if (chunk.editTo > editLine && chunk.editFrom <= editLine) return null;
if (chunk.editFrom > editLine) break;
editStart = chunk.editTo;
origStart = chunk.origTo;
}
return origStart + (editLine - editStart);
}
function findAlignedLines(dv, other) {
var linesToAlign = [];
for (var i = 0; i < dv.chunks.length; i++) {
var chunk = dv.chunks[i];
linesToAlign.push([chunk.origTo, chunk.editTo, other ? getMatchingOrigLine(chunk.editTo, other.chunks) : null]);
}
if (other) {
for (var i = 0; i < other.chunks.length; i++) {
var chunk = other.chunks[i];
for (var j = 0; j < linesToAlign.length; j++) {
var align = linesToAlign[j];
if (align[1] == chunk.editTo) {
j = -1;
break;
} else if (align[1] > chunk.editTo) {
break;
}
}
if (j > -1)
linesToAlign.splice(j - 1, 0, [getMatchingOrigLine(chunk.editTo, dv.chunks), chunk.editTo, chunk.origTo]);
}
}
return linesToAlign;
}
function alignChunks(dv, force) {
if (!dv.dealigned && !force) return;
if (!dv.orig.curOp) return dv.orig.operation(function() {
alignChunks(dv, force);
});
dv.dealigned = false;
var other = dv.mv.left == dv ? dv.mv.right : dv.mv.left;
if (other) {
ensureDiff(other);
other.dealigned = false;
}
var linesToAlign = findAlignedLines(dv, other);
// Clear old aligners
var aligners = dv.mv.aligners;
for (var i = 0; i < aligners.length; i++)
aligners[i].clear();
aligners.length = 0;
var cm = [dv.orig, dv.edit], scroll = [];
if (other) cm.push(other.orig);
for (var i = 0; i < cm.length; i++)
scroll.push(cm[i].getScrollInfo().top);
for (var ln = 0; ln < linesToAlign.length; ln++)
alignLines(cm, linesToAlign[ln], aligners);
for (var i = 0; i < cm.length; i++)
cm[i].scrollTo(null, scroll[i]);
}
function alignLines(cm, lines, aligners) {
var maxOffset = 0, offset = [];
for (var i = 0; i < cm.length; i++) if (lines[i] != null) {
var off = cm[i].heightAtLine(lines[i], "local");
offset[i] = off;
maxOffset = Math.max(maxOffset, off);
}
for (var i = 0; i < cm.length; i++) if (lines[i] != null) {
var diff = maxOffset - offset[i];
if (diff > 1)
aligners.push(padAbove(cm[i], lines[i], diff));
}
}
function padAbove(cm, line, size) {
var above = true;
if (line > cm.lastLine()) {
line--;
above = false;
}
var elt = document.createElement("div");
elt.className = "CodeMirror-merge-spacer";
elt.style.height = size + "px"; elt.style.minWidth = "1px";
return cm.addLineWidget(line, elt, {height: size, above: above});
}
function drawConnectorsForChunk(dv, chunk, sTopOrig, sTopEdit, w) {
var flip = dv.type == "left";
var top = dv.orig.heightAtLine(chunk.origFrom, "local") - sTopOrig;
if (dv.svg) {
var topLpx = top;
var topRpx = dv.edit.heightAtLine(chunk.editFrom, "local") - sTopEdit;
if (flip) { var tmp = topLpx; topLpx = topRpx; topRpx = tmp; }
var botLpx = dv.orig.heightAtLine(chunk.origTo, "local") - sTopOrig;
var botRpx = dv.edit.heightAtLine(chunk.editTo, "local") - sTopEdit;
if (flip) { var tmp = botLpx; botLpx = botRpx; botRpx = tmp; }
var curveTop = " C " + w/2 + " " + topRpx + " " + w/2 + " " + topLpx + " " + (w + 2) + " " + topLpx;
var curveBot = " C " + w/2 + " " + botLpx + " " + w/2 + " " + botRpx + " -1 " + botRpx;
attrs(dv.svg.appendChild(document.createElementNS(svgNS, "path")),
"d", "M -1 " + topRpx + curveTop + " L " + (w + 2) + " " + botLpx + curveBot + " z",
"class", dv.classes.connect);
}
if (dv.copyButtons) {
var copy = dv.copyButtons.appendChild(elt("div", dv.type == "left" ? "\u21dd" : "\u21dc",
"CodeMirror-merge-copy"));
var editOriginals = dv.mv.options.allowEditingOriginals;
copy.title = editOriginals ? "Push to left" : "Revert chunk";
copy.chunk = chunk;
copy.style.top = top + "px";
if (editOriginals) {
var topReverse = dv.orig.heightAtLine(chunk.editFrom, "local") - sTopEdit;
var copyReverse = dv.copyButtons.appendChild(elt("div", dv.type == "right" ? "\u21dd" : "\u21dc",
"CodeMirror-merge-copy-reverse"));
copyReverse.title = "Push to right";
copyReverse.chunk = {editFrom: chunk.origFrom, editTo: chunk.origTo,
origFrom: chunk.editFrom, origTo: chunk.editTo};
copyReverse.style.top = topReverse + "px";
dv.type == "right" ? copyReverse.style.left = "2px" : copyReverse.style.right = "2px";
}
}
}
function copyChunk(dv, to, from, chunk) {
if (dv.diffOutOfDate) return;
to.replaceRange(from.getRange(Pos(chunk.origFrom, 0), Pos(chunk.origTo, 0)),
Pos(chunk.editFrom, 0), Pos(chunk.editTo, 0));
}
// Merge view, containing 0, 1, or 2 diff views.
var MergeView = CodeMirror.MergeView = function(node, options) {
if (!(this instanceof MergeView)) return new MergeView(node, options);
this.options = options;
var origLeft = options.origLeft, origRight = options.origRight == null ? options.orig : options.origRight;
var hasLeft = origLeft != null, hasRight = origRight != null;
var panes = 1 + (hasLeft ? 1 : 0) + (hasRight ? 1 : 0);
var wrap = [], left = this.left = null, right = this.right = null;
var self = this;
if (hasLeft) {
left = this.left = new DiffView(this, "left");
var leftPane = elt("div", null, "CodeMirror-merge-pane");
wrap.push(leftPane);
wrap.push(buildGap(left));
}
var editPane = elt("div", null, "CodeMirror-merge-pane");
wrap.push(editPane);
if (hasRight) {
right = this.right = new DiffView(this, "right");
wrap.push(buildGap(right));
var rightPane = elt("div", null, "CodeMirror-merge-pane");
wrap.push(rightPane);
}
(hasRight ? rightPane : editPane).className += " CodeMirror-merge-pane-rightmost";
wrap.push(elt("div", null, null, "height: 0; clear: both;"));
var wrapElt = this.wrap = node.appendChild(elt("div", wrap, "CodeMirror-merge CodeMirror-merge-" + panes + "pane"));
this.edit = CodeMirror(editPane, copyObj(options));
if (left) left.init(leftPane, origLeft, options);
if (right) right.init(rightPane, origRight, options);
if (options.collapseIdentical) {
updating = true;
this.editor().operation(function() {
collapseIdenticalStretches(self, options.collapseIdentical);
});
updating = false;
}
if (options.connect == "align") {
this.aligners = [];
alignChunks(this.left || this.right, true);
}
var onResize = function() {
if (left) makeConnections(left);
if (right) makeConnections(right);
};
CodeMirror.on(window, "resize", onResize);
var resizeInterval = setInterval(function() {
for (var p = wrapElt.parentNode; p && p != document.body; p = p.parentNode) {}
if (!p) { clearInterval(resizeInterval); CodeMirror.off(window, "resize", onResize); }
}, 5000);
};
function buildGap(dv) {
var lock = dv.lockButton = elt("div", null, "CodeMirror-merge-scrolllock");
lock.title = "Toggle locked scrolling";
var lockWrap = elt("div", [lock], "CodeMirror-merge-scrolllock-wrap");
CodeMirror.on(lock, "click", function() { setScrollLock(dv, !dv.lockScroll); });
var gapElts = [lockWrap];
if (dv.mv.options.revertButtons !== false) {
dv.copyButtons = elt("div", null, "CodeMirror-merge-copybuttons-" + dv.type);
CodeMirror.on(dv.copyButtons, "click", function(e) {
var node = e.target || e.srcElement;
if (!node.chunk) return;
if (node.className == "CodeMirror-merge-copy-reverse") {
copyChunk(dv, dv.orig, dv.edit, node.chunk);
return;
}
copyChunk(dv, dv.edit, dv.orig, node.chunk);
});
gapElts.unshift(dv.copyButtons);
}
if (dv.mv.options.connect != "align") {
var svg = document.createElementNS && document.createElementNS(svgNS, "svg");
if (svg && !svg.createSVGRect) svg = null;
dv.svg = svg;
if (svg) gapElts.push(svg);
}
return dv.gap = elt("div", gapElts, "CodeMirror-merge-gap");
}
MergeView.prototype = {
constuctor: MergeView,
editor: function() { return this.edit; },
rightOriginal: function() { return this.right && this.right.orig; },
leftOriginal: function() { return this.left && this.left.orig; },
setShowDifferences: function(val) {
if (this.right) this.right.setShowDifferences(val);
if (this.left) this.left.setShowDifferences(val);
},
rightChunks: function() {
if (this.right) { ensureDiff(this.right); return this.right.chunks; }
},
leftChunks: function() {
if (this.left) { ensureDiff(this.left); return this.left.chunks; }
}
};
function asString(obj) {
if (typeof obj == "string") return obj;
else return obj.getValue();
}
// Operations on diffs
var dmp = new diff_match_patch();
function getDiff(a, b) {
var diff = dmp.diff_main(a, b);
dmp.diff_cleanupSemantic(diff);
// The library sometimes leaves in empty parts, which confuse the algorithm
for (var i = 0; i < diff.length; ++i) {
var part = diff[i];
if (!part[1]) {
diff.splice(i--, 1);
} else if (i && diff[i - 1][0] == part[0]) {
diff.splice(i--, 1);
diff[i][1] += part[1];
}
}
return diff;
}
function getChunks(diff) {
var chunks = [];
var startEdit = 0, startOrig = 0;
var edit = Pos(0, 0), orig = Pos(0, 0);
for (var i = 0; i < diff.length; ++i) {
var part = diff[i], tp = part[0];
if (tp == DIFF_EQUAL) {
var startOff = startOfLineClean(diff, i) ? 0 : 1;
var cleanFromEdit = edit.line + startOff, cleanFromOrig = orig.line + startOff;
moveOver(edit, part[1], null, orig);
var endOff = endOfLineClean(diff, i) ? 1 : 0;
var cleanToEdit = edit.line + endOff, cleanToOrig = orig.line + endOff;
if (cleanToEdit > cleanFromEdit) {
if (i) chunks.push({origFrom: startOrig, origTo: cleanFromOrig,
editFrom: startEdit, editTo: cleanFromEdit});
startEdit = cleanToEdit; startOrig = cleanToOrig;
}
} else {
moveOver(tp == DIFF_INSERT ? edit : orig, part[1]);
}
}
if (startEdit <= edit.line || startOrig <= orig.line)
chunks.push({origFrom: startOrig, origTo: orig.line + 1,
editFrom: startEdit, editTo: edit.line + 1});
return chunks;
}
function endOfLineClean(diff, i) {
if (i == diff.length - 1) return true;
var next = diff[i + 1][1];
if (next.length == 1 || next.charCodeAt(0) != 10) return false;
if (i == diff.length - 2) return true;
next = diff[i + 2][1];
return next.length > 1 && next.charCodeAt(0) == 10;
}
function startOfLineClean(diff, i) {
if (i == 0) return true;
var last = diff[i - 1][1];
if (last.charCodeAt(last.length - 1) != 10) return false;
if (i == 1) return true;
last = diff[i - 2][1];
return last.charCodeAt(last.length - 1) == 10;
}
function chunkBoundariesAround(chunks, n, nInEdit) {
var beforeE, afterE, beforeO, afterO;
for (var i = 0; i < chunks.length; i++) {
var chunk = chunks[i];
var fromLocal = nInEdit ? chunk.editFrom : chunk.origFrom;
var toLocal = nInEdit ? chunk.editTo : chunk.origTo;
if (afterE == null) {
if (fromLocal > n) { afterE = chunk.editFrom; afterO = chunk.origFrom; }
else if (toLocal > n) { afterE = chunk.editTo; afterO = chunk.origTo; }
}
if (toLocal <= n) { beforeE = chunk.editTo; beforeO = chunk.origTo; }
else if (fromLocal <= n) { beforeE = chunk.editFrom; beforeO = chunk.origFrom; }
}
return {edit: {before: beforeE, after: afterE}, orig: {before: beforeO, after: afterO}};
}
function collapseSingle(cm, from, to) {
cm.addLineClass(from, "wrap", "CodeMirror-merge-collapsed-line");
var widget = document.createElement("span");
widget.className = "CodeMirror-merge-collapsed-widget";
widget.title = "Identical text collapsed. Click to expand.";
var mark = cm.markText(Pos(from, 0), Pos(to - 1), {
inclusiveLeft: true,
inclusiveRight: true,
replacedWith: widget,
clearOnEnter: true
});
function clear() {
mark.clear();
cm.removeLineClass(from, "wrap", "CodeMirror-merge-collapsed-line");
}
widget.addEventListener("click", clear);
return {mark: mark, clear: clear};
}
function collapseStretch(size, editors) {
var marks = [];
function clear() {
for (var i = 0; i < marks.length; i++) marks[i].clear();
}
for (var i = 0; i < editors.length; i++) {
var editor = editors[i];
var mark = collapseSingle(editor.cm, editor.line, editor.line + size);
marks.push(mark);
mark.mark.on("clear", clear);
}
return marks[0].mark;
}
function unclearNearChunks(dv, margin, off, clear) {
for (var i = 0; i < dv.chunks.length; i++) {
var chunk = dv.chunks[i];
for (var l = chunk.editFrom - margin; l < chunk.editTo + margin; l++) {
var pos = l + off;
if (pos >= 0 && pos < clear.length) clear[pos] = false;
}
}
}
function collapseIdenticalStretches(mv, margin) {
if (typeof margin != "number") margin = 2;
var clear = [], edit = mv.editor(), off = edit.firstLine();
for (var l = off, e = edit.lastLine(); l <= e; l++) clear.push(true);
if (mv.left) unclearNearChunks(mv.left, margin, off, clear);
if (mv.right) unclearNearChunks(mv.right, margin, off, clear);
for (var i = 0; i < clear.length; i++) {
if (clear[i]) {
var line = i + off;
for (var size = 1; i < clear.length - 1 && clear[i + 1]; i++, size++) {}
if (size > margin) {
var editors = [{line: line, cm: edit}];
if (mv.left) editors.push({line: getMatchingOrigLine(line, mv.left.chunks), cm: mv.left.orig});
if (mv.right) editors.push({line: getMatchingOrigLine(line, mv.right.chunks), cm: mv.right.orig});
var mark = collapseStretch(size, editors);
if (mv.options.onCollapse) mv.options.onCollapse(mv, line, size, mark);
}
}
}
}
// General utilities
function elt(tag, content, className, style) {
var e = document.createElement(tag);
if (className) e.className = className;
if (style) e.style.cssText = style;
if (typeof content == "string") e.appendChild(document.createTextNode(content));
else if (content) for (var i = 0; i < content.length; ++i) e.appendChild(content[i]);
return e;
}
function clear(node) {
for (var count = node.childNodes.length; count > 0; --count)
node.removeChild(node.firstChild);
}
function attrs(elt) {
for (var i = 1; i < arguments.length; i += 2)
elt.setAttribute(arguments[i], arguments[i+1]);
}
function copyObj(obj, target) {
if (!target) target = {};
for (var prop in obj) if (obj.hasOwnProperty(prop)) target[prop] = obj[prop];
return target;
}
function moveOver(pos, str, copy, other) {
var out = copy ? Pos(pos.line, pos.ch) : pos, at = 0;
for (;;) {
var nl = str.indexOf("\n", at);
if (nl == -1) break;
++out.line;
if (other) ++other.line;
at = nl + 1;
}
out.ch = (at ? 0 : out.ch) + (str.length - at);
if (other) other.ch = (at ? 0 : other.ch) + (str.length - at);
return out;
}
function posMin(a, b) { return (a.line - b.line || a.ch - b.ch) < 0 ? a : b; }
function posMax(a, b) { return (a.line - b.line || a.ch - b.ch) > 0 ? a : b; }
function posEq(a, b) { return a.line == b.line && a.ch == b.ch; }
});

View File

@@ -1,64 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), "cjs");
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], function(CM) { mod(CM, "amd"); });
else // Plain browser env
mod(CodeMirror, "plain");
})(function(CodeMirror, env) {
if (!CodeMirror.modeURL) CodeMirror.modeURL = "../mode/%N/%N.js";
var loading = {};
function splitCallback(cont, n) {
var countDown = n;
return function() { if (--countDown == 0) cont(); };
}
function ensureDeps(mode, cont) {
var deps = CodeMirror.modes[mode].dependencies;
if (!deps) return cont();
var missing = [];
for (var i = 0; i < deps.length; ++i) {
if (!CodeMirror.modes.hasOwnProperty(deps[i]))
missing.push(deps[i]);
}
if (!missing.length) return cont();
var split = splitCallback(cont, missing.length);
for (var i = 0; i < missing.length; ++i)
CodeMirror.requireMode(missing[i], split);
}
CodeMirror.requireMode = function(mode, cont) {
if (typeof mode != "string") mode = mode.name;
if (CodeMirror.modes.hasOwnProperty(mode)) return ensureDeps(mode, cont);
if (loading.hasOwnProperty(mode)) return loading[mode].push(cont);
var file = CodeMirror.modeURL.replace(/%N/g, mode);
if (env == "plain") {
var script = document.createElement("script");
script.src = file;
var others = document.getElementsByTagName("script")[0];
var list = loading[mode] = [cont];
CodeMirror.on(script, "load", function() {
ensureDeps(mode, function() {
for (var i = 0; i < list.length; ++i) list[i]();
});
});
others.parentNode.insertBefore(script, others);
} else if (env == "cjs") {
require(file);
cont();
} else if (env == "amd") {
requirejs([file], cont);
}
};
CodeMirror.autoLoadMode = function(instance, mode) {
if (!CodeMirror.modes.hasOwnProperty(mode))
CodeMirror.requireMode(mode, function() {
instance.setOption("mode", instance.getOption("mode"));
});
};
});

View File

@@ -1,118 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.multiplexingMode = function(outer /*, others */) {
// Others should be {open, close, mode [, delimStyle] [, innerStyle]} objects
var others = Array.prototype.slice.call(arguments, 1);
var n_others = others.length;
function indexOf(string, pattern, from) {
if (typeof pattern == "string") return string.indexOf(pattern, from);
var m = pattern.exec(from ? string.slice(from) : string);
return m ? m.index + from : -1;
}
return {
startState: function() {
return {
outer: CodeMirror.startState(outer),
innerActive: null,
inner: null
};
},
copyState: function(state) {
return {
outer: CodeMirror.copyState(outer, state.outer),
innerActive: state.innerActive,
inner: state.innerActive && CodeMirror.copyState(state.innerActive.mode, state.inner)
};
},
token: function(stream, state) {
if (!state.innerActive) {
var cutOff = Infinity, oldContent = stream.string;
for (var i = 0; i < n_others; ++i) {
var other = others[i];
var found = indexOf(oldContent, other.open, stream.pos);
if (found == stream.pos) {
stream.match(other.open);
state.innerActive = other;
state.inner = CodeMirror.startState(other.mode, outer.indent ? outer.indent(state.outer, "") : 0);
return other.delimStyle;
} else if (found != -1 && found < cutOff) {
cutOff = found;
}
}
if (cutOff != Infinity) stream.string = oldContent.slice(0, cutOff);
var outerToken = outer.token(stream, state.outer);
if (cutOff != Infinity) stream.string = oldContent;
return outerToken;
} else {
var curInner = state.innerActive, oldContent = stream.string;
if (!curInner.close && stream.sol()) {
state.innerActive = state.inner = null;
return this.token(stream, state);
}
var found = curInner.close ? indexOf(oldContent, curInner.close, stream.pos) : -1;
if (found == stream.pos) {
stream.match(curInner.close);
state.innerActive = state.inner = null;
return curInner.delimStyle;
}
if (found > -1) stream.string = oldContent.slice(0, found);
var innerToken = curInner.mode.token(stream, state.inner);
if (found > -1) stream.string = oldContent;
if (curInner.innerStyle) {
if (innerToken) innerToken = innerToken + ' ' + curInner.innerStyle;
else innerToken = curInner.innerStyle;
}
return innerToken;
}
},
indent: function(state, textAfter) {
var mode = state.innerActive ? state.innerActive.mode : outer;
if (!mode.indent) return CodeMirror.Pass;
return mode.indent(state.innerActive ? state.inner : state.outer, textAfter);
},
blankLine: function(state) {
var mode = state.innerActive ? state.innerActive.mode : outer;
if (mode.blankLine) {
mode.blankLine(state.innerActive ? state.inner : state.outer);
}
if (!state.innerActive) {
for (var i = 0; i < n_others; ++i) {
var other = others[i];
if (other.open === "\n") {
state.innerActive = other;
state.inner = CodeMirror.startState(other.mode, mode.indent ? mode.indent(state.outer, "") : 0);
}
}
} else if (state.innerActive.close === "\n") {
state.innerActive = state.inner = null;
}
},
electricChars: outer.electricChars,
innerMode: function(state) {
return state.inner ? {state: state.inner, mode: state.innerActive.mode} : {state: state.outer, mode: outer};
}
};
};
});

View File

@@ -1,33 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function() {
CodeMirror.defineMode("markdown_with_stex", function(){
var inner = CodeMirror.getMode({}, "stex");
var outer = CodeMirror.getMode({}, "markdown");
var innerOptions = {
open: '$',
close: '$',
mode: inner,
delimStyle: 'delim',
innerStyle: 'inner'
};
return CodeMirror.multiplexingMode(outer, innerOptions);
});
var mode = CodeMirror.getMode({}, "markdown_with_stex");
function MT(name) {
test.mode(
name,
mode,
Array.prototype.slice.call(arguments, 1),
'multiplexing');
}
MT(
"stexInsideMarkdown",
"[strong **Equation:**] [delim $][inner&tag \\pi][delim $]");
})();

View File

@@ -1,85 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Utility function that allows modes to be combined. The mode given
// as the base argument takes care of most of the normal mode
// functionality, but a second (typically simple) mode is used, which
// can override the style of text. Both modes get to parse all of the
// text, but when both assign a non-null style to a piece of code, the
// overlay wins, unless the combine argument was true and not overridden,
// or state.overlay.combineTokens was true, in which case the styles are
// combined.
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.overlayMode = function(base, overlay, combine) {
return {
startState: function() {
return {
base: CodeMirror.startState(base),
overlay: CodeMirror.startState(overlay),
basePos: 0, baseCur: null,
overlayPos: 0, overlayCur: null,
streamSeen: null
};
},
copyState: function(state) {
return {
base: CodeMirror.copyState(base, state.base),
overlay: CodeMirror.copyState(overlay, state.overlay),
basePos: state.basePos, baseCur: null,
overlayPos: state.overlayPos, overlayCur: null
};
},
token: function(stream, state) {
if (stream != state.streamSeen ||
Math.min(state.basePos, state.overlayPos) < stream.start) {
state.streamSeen = stream;
state.basePos = state.overlayPos = stream.start;
}
if (stream.start == state.basePos) {
state.baseCur = base.token(stream, state.base);
state.basePos = stream.pos;
}
if (stream.start == state.overlayPos) {
stream.pos = stream.start;
state.overlayCur = overlay.token(stream, state.overlay);
state.overlayPos = stream.pos;
}
stream.pos = Math.min(state.basePos, state.overlayPos);
// state.overlay.combineTokens always takes precedence over combine,
// unless set to null
if (state.overlayCur == null) return state.baseCur;
else if (state.baseCur != null &&
state.overlay.combineTokens ||
combine && state.overlay.combineTokens == null)
return state.baseCur + " " + state.overlayCur;
else return state.overlayCur;
},
indent: base.indent && function(state, textAfter) {
return base.indent(state.base, textAfter);
},
electricChars: base.electricChars,
innerMode: function(state) { return {state: state.base, mode: base}; },
blankLine: function(state) {
if (base.blankLine) base.blankLine(state.base);
if (overlay.blankLine) overlay.blankLine(state.overlay);
}
};
};
});

View File

@@ -1,213 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.defineSimpleMode = function(name, states) {
CodeMirror.defineMode(name, function(config) {
return CodeMirror.simpleMode(config, states);
});
};
CodeMirror.simpleMode = function(config, states) {
ensureState(states, "start");
var states_ = {}, meta = states.meta || {}, hasIndentation = false;
for (var state in states) if (state != meta && states.hasOwnProperty(state)) {
var list = states_[state] = [], orig = states[state];
for (var i = 0; i < orig.length; i++) {
var data = orig[i];
list.push(new Rule(data, states));
if (data.indent || data.dedent) hasIndentation = true;
}
}
var mode = {
startState: function() {
return {state: "start", pending: null,
local: null, localState: null,
indent: hasIndentation ? [] : null};
},
copyState: function(state) {
var s = {state: state.state, pending: state.pending,
local: state.local, localState: null,
indent: state.indent && state.indent.slice(0)};
if (state.localState)
s.localState = CodeMirror.copyState(state.local.mode, state.localState);
if (state.stack)
s.stack = state.stack.slice(0);
for (var pers = state.persistentStates; pers; pers = pers.next)
s.persistentStates = {mode: pers.mode,
spec: pers.spec,
state: pers.state == state.localState ? s.localState : CodeMirror.copyState(pers.mode, pers.state),
next: s.persistentStates};
return s;
},
token: tokenFunction(states_, config),
innerMode: function(state) { return state.local && {mode: state.local.mode, state: state.localState}; },
indent: indentFunction(states_, meta)
};
if (meta) for (var prop in meta) if (meta.hasOwnProperty(prop))
mode[prop] = meta[prop];
return mode;
};
function ensureState(states, name) {
if (!states.hasOwnProperty(name))
throw new Error("Undefined state " + name + "in simple mode");
}
function toRegex(val, caret) {
if (!val) return /(?:)/;
var flags = "";
if (val instanceof RegExp) {
if (val.ignoreCase) flags = "i";
val = val.source;
} else {
val = String(val);
}
return new RegExp((caret === false ? "" : "^") + "(?:" + val + ")", flags);
}
function asToken(val) {
if (!val) return null;
if (typeof val == "string") return val.replace(/\./g, " ");
var result = [];
for (var i = 0; i < val.length; i++)
result.push(val[i] && val[i].replace(/\./g, " "));
return result;
}
function Rule(data, states) {
if (data.next || data.push) ensureState(states, data.next || data.push);
this.regex = toRegex(data.regex);
this.token = asToken(data.token);
this.data = data;
}
function tokenFunction(states, config) {
return function(stream, state) {
if (state.pending) {
var pend = state.pending.shift();
if (state.pending.length == 0) state.pending = null;
stream.pos += pend.text.length;
return pend.token;
}
if (state.local) {
if (state.local.end && stream.match(state.local.end)) {
var tok = state.local.endToken || null;
state.local = state.localState = null;
return tok;
} else {
var tok = state.local.mode.token(stream, state.localState), m;
if (state.local.endScan && (m = state.local.endScan.exec(stream.current())))
stream.pos = stream.start + m.index;
return tok;
}
}
var curState = states[state.state];
for (var i = 0; i < curState.length; i++) {
var rule = curState[i];
var matches = (!rule.data.sol || stream.sol()) && stream.match(rule.regex);
if (matches) {
if (rule.data.next) {
state.state = rule.data.next;
} else if (rule.data.push) {
(state.stack || (state.stack = [])).push(state.state);
state.state = rule.data.push;
} else if (rule.data.pop && state.stack && state.stack.length) {
state.state = state.stack.pop();
}
if (rule.data.mode)
enterLocalMode(config, state, rule.data.mode, rule.token);
if (rule.data.indent)
state.indent.push(stream.indentation() + config.indentUnit);
if (rule.data.dedent)
state.indent.pop();
if (matches.length > 2) {
state.pending = [];
for (var j = 2; j < matches.length; j++)
if (matches[j])
state.pending.push({text: matches[j], token: rule.token[j - 1]});
stream.backUp(matches[0].length - (matches[1] ? matches[1].length : 0));
return rule.token[0];
} else if (rule.token && rule.token.join) {
return rule.token[0];
} else {
return rule.token;
}
}
}
stream.next();
return null;
};
}
function cmp(a, b) {
if (a === b) return true;
if (!a || typeof a != "object" || !b || typeof b != "object") return false;
var props = 0;
for (var prop in a) if (a.hasOwnProperty(prop)) {
if (!b.hasOwnProperty(prop) || !cmp(a[prop], b[prop])) return false;
props++;
}
for (var prop in b) if (b.hasOwnProperty(prop)) props--;
return props == 0;
}
function enterLocalMode(config, state, spec, token) {
var pers;
if (spec.persistent) for (var p = state.persistentStates; p && !pers; p = p.next)
if (spec.spec ? cmp(spec.spec, p.spec) : spec.mode == p.mode) pers = p;
var mode = pers ? pers.mode : spec.mode || CodeMirror.getMode(config, spec.spec);
var lState = pers ? pers.state : CodeMirror.startState(mode);
if (spec.persistent && !pers)
state.persistentStates = {mode: mode, spec: spec.spec, state: lState, next: state.persistentStates};
state.localState = lState;
state.local = {mode: mode,
end: spec.end && toRegex(spec.end),
endScan: spec.end && spec.forceEnd !== false && toRegex(spec.end, false),
endToken: token && token.join ? token[token.length - 1] : token};
}
function indexOf(val, arr) {
for (var i = 0; i < arr.length; i++) if (arr[i] === val) return true;
}
function indentFunction(states, meta) {
return function(state, textAfter, line) {
if (state.local && state.local.mode.indent)
return state.local.mode.indent(state.localState, textAfter, line);
if (state.indent == null || state.local || meta.dontIndentStates && indexOf(state.state, meta.dontIndentStates) > -1)
return CodeMirror.Pass;
var pos = state.indent.length - 1, rules = states[state.state];
scan: for (;;) {
for (var i = 0; i < rules.length; i++) {
var rule = rules[i];
if (rule.data.dedent && rule.data.dedentIfLineStart !== false) {
var m = rule.regex.exec(textAfter);
if (m && m[0]) {
pos--;
if (rule.next || rule.push) rules = states[rule.next || rule.push];
textAfter = textAfter.slice(m[0].length);
continue scan;
}
}
}
break;
}
return pos < 0 ? 0 : state.indent[pos];
};
}
});

View File

@@ -1,40 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("./runmode"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "./runmode"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
var isBlock = /^(p|li|div|h\\d|pre|blockquote|td)$/;
function textContent(node, out) {
if (node.nodeType == 3) return out.push(node.nodeValue);
for (var ch = node.firstChild; ch; ch = ch.nextSibling) {
textContent(ch, out);
if (isBlock.test(node.nodeType)) out.push("\n");
}
}
CodeMirror.colorize = function(collection, defaultMode) {
if (!collection) collection = document.body.getElementsByTagName("pre");
for (var i = 0; i < collection.length; ++i) {
var node = collection[i];
var mode = node.getAttribute("data-lang") || defaultMode;
if (!mode) continue;
var text = [];
textContent(node, text);
node.innerHTML = "";
CodeMirror.runMode(text.join(""), mode, node);
node.className += " cm-s-default";
}
};
});

View File

@@ -1,157 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
window.CodeMirror = {};
(function() {
"use strict";
function splitLines(string){ return string.split(/\r?\n|\r/); };
function StringStream(string) {
this.pos = this.start = 0;
this.string = string;
this.lineStart = 0;
}
StringStream.prototype = {
eol: function() {return this.pos >= this.string.length;},
sol: function() {return this.pos == 0;},
peek: function() {return this.string.charAt(this.pos) || null;},
next: function() {
if (this.pos < this.string.length)
return this.string.charAt(this.pos++);
},
eat: function(match) {
var ch = this.string.charAt(this.pos);
if (typeof match == "string") var ok = ch == match;
else var ok = ch && (match.test ? match.test(ch) : match(ch));
if (ok) {++this.pos; return ch;}
},
eatWhile: function(match) {
var start = this.pos;
while (this.eat(match)){}
return this.pos > start;
},
eatSpace: function() {
var start = this.pos;
while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos;
return this.pos > start;
},
skipToEnd: function() {this.pos = this.string.length;},
skipTo: function(ch) {
var found = this.string.indexOf(ch, this.pos);
if (found > -1) {this.pos = found; return true;}
},
backUp: function(n) {this.pos -= n;},
column: function() {return this.start - this.lineStart;},
indentation: function() {return 0;},
match: function(pattern, consume, caseInsensitive) {
if (typeof pattern == "string") {
var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;};
var substr = this.string.substr(this.pos, pattern.length);
if (cased(substr) == cased(pattern)) {
if (consume !== false) this.pos += pattern.length;
return true;
}
} else {
var match = this.string.slice(this.pos).match(pattern);
if (match && match.index > 0) return null;
if (match && consume !== false) this.pos += match[0].length;
return match;
}
},
current: function(){return this.string.slice(this.start, this.pos);},
hideFirstChars: function(n, inner) {
this.lineStart += n;
try { return inner(); }
finally { this.lineStart -= n; }
}
};
CodeMirror.StringStream = StringStream;
CodeMirror.startState = function (mode, a1, a2) {
return mode.startState ? mode.startState(a1, a2) : true;
};
var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {};
CodeMirror.defineMode = function (name, mode) {
if (arguments.length > 2)
mode.dependencies = Array.prototype.slice.call(arguments, 2);
modes[name] = mode;
};
CodeMirror.defineMIME = function (mime, spec) { mimeModes[mime] = spec; };
CodeMirror.resolveMode = function(spec) {
if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) {
spec = mimeModes[spec];
} else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) {
spec = mimeModes[spec.name];
}
if (typeof spec == "string") return {name: spec};
else return spec || {name: "null"};
};
CodeMirror.getMode = function (options, spec) {
spec = CodeMirror.resolveMode(spec);
var mfactory = modes[spec.name];
if (!mfactory) throw new Error("Unknown mode: " + spec);
return mfactory(options, spec);
};
CodeMirror.registerHelper = CodeMirror.registerGlobalHelper = Math.min;
CodeMirror.defineMode("null", function() {
return {token: function(stream) {stream.skipToEnd();}};
});
CodeMirror.defineMIME("text/plain", "null");
CodeMirror.runMode = function (string, modespec, callback, options) {
var mode = CodeMirror.getMode({ indentUnit: 2 }, modespec);
if (callback.nodeType == 1) {
var tabSize = (options && options.tabSize) || 4;
var node = callback, col = 0;
node.innerHTML = "";
callback = function (text, style) {
if (text == "\n") {
node.appendChild(document.createElement("br"));
col = 0;
return;
}
var content = "";
// replace tabs
for (var pos = 0; ;) {
var idx = text.indexOf("\t", pos);
if (idx == -1) {
content += text.slice(pos);
col += text.length - pos;
break;
} else {
col += idx - pos;
content += text.slice(pos, idx);
var size = tabSize - col % tabSize;
col += size;
for (var i = 0; i < size; ++i) content += " ";
pos = idx + 1;
}
}
if (style) {
var sp = node.appendChild(document.createElement("span"));
sp.className = "cm-" + style.replace(/ +/g, " cm-");
sp.appendChild(document.createTextNode(content));
} else {
node.appendChild(document.createTextNode(content));
}
};
}
var lines = splitLines(string), state = (options && options.state) || CodeMirror.startState(mode);
for (var i = 0, e = lines.length; i < e; ++i) {
if (i) callback("\n");
var stream = new CodeMirror.StringStream(lines[i]);
if (!stream.string && mode.blankLine) mode.blankLine(state);
while (!stream.eol()) {
var style = mode.token(stream, state);
callback(stream.current(), style, i, stream.start, state);
stream.start = stream.pos;
}
}
};
})();

View File

@@ -1,72 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.runMode = function(string, modespec, callback, options) {
var mode = CodeMirror.getMode(CodeMirror.defaults, modespec);
var ie = /MSIE \d/.test(navigator.userAgent);
var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9);
if (callback.nodeType == 1) {
var tabSize = (options && options.tabSize) || CodeMirror.defaults.tabSize;
var node = callback, col = 0;
node.innerHTML = "";
callback = function(text, style) {
if (text == "\n") {
// Emitting LF or CRLF on IE8 or earlier results in an incorrect display.
// Emitting a carriage return makes everything ok.
node.appendChild(document.createTextNode(ie_lt9 ? '\r' : text));
col = 0;
return;
}
var content = "";
// replace tabs
for (var pos = 0;;) {
var idx = text.indexOf("\t", pos);
if (idx == -1) {
content += text.slice(pos);
col += text.length - pos;
break;
} else {
col += idx - pos;
content += text.slice(pos, idx);
var size = tabSize - col % tabSize;
col += size;
for (var i = 0; i < size; ++i) content += " ";
pos = idx + 1;
}
}
if (style) {
var sp = node.appendChild(document.createElement("span"));
sp.className = "cm-" + style.replace(/ +/g, " cm-");
sp.appendChild(document.createTextNode(content));
} else {
node.appendChild(document.createTextNode(content));
}
};
}
var lines = CodeMirror.splitLines(string), state = (options && options.state) || CodeMirror.startState(mode);
for (var i = 0, e = lines.length; i < e; ++i) {
if (i) callback("\n");
var stream = new CodeMirror.StringStream(lines[i]);
if (!stream.string && mode.blankLine) mode.blankLine(state);
while (!stream.eol()) {
var style = mode.token(stream, state);
callback(stream.current(), style, i, stream.start, state);
stream.start = stream.pos;
}
}
};
});

View File

@@ -1,120 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
/* Just enough of CodeMirror to run runMode under node.js */
// declare global: StringStream
function splitLines(string){ return string.split(/\r?\n|\r/); };
function StringStream(string) {
this.pos = this.start = 0;
this.string = string;
this.lineStart = 0;
}
StringStream.prototype = {
eol: function() {return this.pos >= this.string.length;},
sol: function() {return this.pos == 0;},
peek: function() {return this.string.charAt(this.pos) || null;},
next: function() {
if (this.pos < this.string.length)
return this.string.charAt(this.pos++);
},
eat: function(match) {
var ch = this.string.charAt(this.pos);
if (typeof match == "string") var ok = ch == match;
else var ok = ch && (match.test ? match.test(ch) : match(ch));
if (ok) {++this.pos; return ch;}
},
eatWhile: function(match) {
var start = this.pos;
while (this.eat(match)){}
return this.pos > start;
},
eatSpace: function() {
var start = this.pos;
while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos;
return this.pos > start;
},
skipToEnd: function() {this.pos = this.string.length;},
skipTo: function(ch) {
var found = this.string.indexOf(ch, this.pos);
if (found > -1) {this.pos = found; return true;}
},
backUp: function(n) {this.pos -= n;},
column: function() {return this.start - this.lineStart;},
indentation: function() {return 0;},
match: function(pattern, consume, caseInsensitive) {
if (typeof pattern == "string") {
var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;};
var substr = this.string.substr(this.pos, pattern.length);
if (cased(substr) == cased(pattern)) {
if (consume !== false) this.pos += pattern.length;
return true;
}
} else {
var match = this.string.slice(this.pos).match(pattern);
if (match && match.index > 0) return null;
if (match && consume !== false) this.pos += match[0].length;
return match;
}
},
current: function(){return this.string.slice(this.start, this.pos);},
hideFirstChars: function(n, inner) {
this.lineStart += n;
try { return inner(); }
finally { this.lineStart -= n; }
}
};
exports.StringStream = StringStream;
exports.startState = function(mode, a1, a2) {
return mode.startState ? mode.startState(a1, a2) : true;
};
var modes = exports.modes = {}, mimeModes = exports.mimeModes = {};
exports.defineMode = function(name, mode) {
if (arguments.length > 2)
mode.dependencies = Array.prototype.slice.call(arguments, 2);
modes[name] = mode;
};
exports.defineMIME = function(mime, spec) { mimeModes[mime] = spec; };
exports.defineMode("null", function() {
return {token: function(stream) {stream.skipToEnd();}};
});
exports.defineMIME("text/plain", "null");
exports.resolveMode = function(spec) {
if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) {
spec = mimeModes[spec];
} else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) {
spec = mimeModes[spec.name];
}
if (typeof spec == "string") return {name: spec};
else return spec || {name: "null"};
};
exports.getMode = function(options, spec) {
spec = exports.resolveMode(spec);
var mfactory = modes[spec.name];
if (!mfactory) throw new Error("Unknown mode: " + spec);
return mfactory(options, spec);
};
exports.registerHelper = exports.registerGlobalHelper = Math.min;
exports.runMode = function(string, modespec, callback, options) {
var mode = exports.getMode({indentUnit: 2}, modespec);
var lines = splitLines(string), state = (options && options.state) || exports.startState(mode);
for (var i = 0, e = lines.length; i < e; ++i) {
if (i) callback("\n");
var stream = new exports.StringStream(lines[i]);
if (!stream.string && mode.blankLine) mode.blankLine(state);
while (!stream.eol()) {
var style = mode.token(stream, state);
callback(stream.current(), style, i, stream.start, state);
stream.start = stream.pos;
}
}
};
require.cache[require.resolve("../../lib/codemirror")] = require.cache[require.resolve("./runmode.node")];

View File

@@ -1,100 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.defineExtension("annotateScrollbar", function(options) {
if (typeof options == "string") options = {className: options};
return new Annotation(this, options);
});
CodeMirror.defineOption("scrollButtonHeight", 0);
function Annotation(cm, options) {
this.cm = cm;
this.options = options;
this.buttonHeight = options.scrollButtonHeight || cm.getOption("scrollButtonHeight");
this.annotations = [];
this.doRedraw = this.doUpdate = null;
this.div = cm.getWrapperElement().appendChild(document.createElement("div"));
this.div.style.cssText = "position: absolute; right: 0; top: 0; z-index: 7; pointer-events: none";
this.computeScale();
function scheduleRedraw(delay) {
clearTimeout(self.doRedraw);
self.doRedraw = setTimeout(function() { self.redraw(); }, delay);
}
var self = this;
cm.on("refresh", this.resizeHandler = function() {
clearTimeout(self.doUpdate);
self.doUpdate = setTimeout(function() {
if (self.computeScale()) scheduleRedraw(20);
}, 100);
});
cm.on("markerAdded", this.resizeHandler);
cm.on("markerCleared", this.resizeHandler);
if (options.listenForChanges !== false)
cm.on("change", this.changeHandler = function() {
scheduleRedraw(250);
});
}
Annotation.prototype.computeScale = function() {
var cm = this.cm;
var hScale = (cm.getWrapperElement().clientHeight - cm.display.barHeight - this.buttonHeight * 2) /
cm.heightAtLine(cm.lastLine() + 1, "local");
if (hScale != this.hScale) {
this.hScale = hScale;
return true;
}
};
Annotation.prototype.update = function(annotations) {
this.annotations = annotations;
this.redraw();
};
Annotation.prototype.redraw = function(compute) {
if (compute !== false) this.computeScale();
var cm = this.cm, hScale = this.hScale;
var frag = document.createDocumentFragment(), anns = this.annotations;
if (cm.display.barWidth) for (var i = 0, nextTop; i < anns.length; i++) {
var ann = anns[i];
var top = nextTop || cm.charCoords(ann.from, "local").top * hScale;
var bottom = cm.charCoords(ann.to, "local").bottom * hScale;
while (i < anns.length - 1) {
nextTop = cm.charCoords(anns[i + 1].from, "local").top * hScale;
if (nextTop > bottom + .9) break;
ann = anns[++i];
bottom = cm.charCoords(ann.to, "local").bottom * hScale;
}
if (bottom == top) continue;
var height = Math.max(bottom - top, 3);
var elt = frag.appendChild(document.createElement("div"));
elt.style.cssText = "position: absolute; right: 0px; width: " + Math.max(cm.display.barWidth - 1, 2) + "px; top: "
+ (top + this.buttonHeight) + "px; height: " + height + "px";
elt.className = this.options.className;
}
this.div.textContent = "";
this.div.appendChild(frag);
};
Annotation.prototype.clear = function() {
this.cm.off("refresh", this.resizeHandler);
this.cm.off("markerAdded", this.resizeHandler);
this.cm.off("markerCleared", this.resizeHandler);
if (this.changeHandler) this.cm.off("change", this.changeHandler);
this.div.parentNode.removeChild(this.div);
};
});

View File

@@ -1,46 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.defineOption("scrollPastEnd", false, function(cm, val, old) {
if (old && old != CodeMirror.Init) {
cm.off("change", onChange);
cm.off("refresh", updateBottomMargin);
cm.display.lineSpace.parentNode.style.paddingBottom = "";
cm.state.scrollPastEndPadding = null;
}
if (val) {
cm.on("change", onChange);
cm.on("refresh", updateBottomMargin);
updateBottomMargin(cm);
}
});
function onChange(cm, change) {
if (CodeMirror.changeEnd(change).line == cm.lastLine())
updateBottomMargin(cm);
}
function updateBottomMargin(cm) {
var padding = "";
if (cm.lineCount() > 1) {
var totalH = cm.display.scroller.clientHeight - 30,
lastLineH = cm.getLineHandle(cm.lastLine()).height;
padding = (totalH - lastLineH) + "px";
}
if (cm.state.scrollPastEndPadding != padding) {
cm.state.scrollPastEndPadding = padding;
cm.display.lineSpace.parentNode.style.paddingBottom = padding;
cm.setSize();
}
}
});

View File

@@ -1,66 +0,0 @@
.CodeMirror-simplescroll-horizontal div, .CodeMirror-simplescroll-vertical div {
position: absolute;
background: #ccc;
-moz-box-sizing: border-box;
box-sizing: border-box;
border: 1px solid #bbb;
border-radius: 2px;
}
.CodeMirror-simplescroll-horizontal, .CodeMirror-simplescroll-vertical {
position: absolute;
z-index: 6;
background: #eee;
}
.CodeMirror-simplescroll-horizontal {
bottom: 0; left: 0;
height: 8px;
}
.CodeMirror-simplescroll-horizontal div {
bottom: 0;
height: 100%;
}
.CodeMirror-simplescroll-vertical {
right: 0; top: 0;
width: 8px;
}
.CodeMirror-simplescroll-vertical div {
right: 0;
width: 100%;
}
.CodeMirror-overlayscroll .CodeMirror-scrollbar-filler, .CodeMirror-overlayscroll .CodeMirror-gutter-filler {
display: none;
}
.CodeMirror-overlayscroll-horizontal div, .CodeMirror-overlayscroll-vertical div {
position: absolute;
background: #bcd;
border-radius: 3px;
}
.CodeMirror-overlayscroll-horizontal, .CodeMirror-overlayscroll-vertical {
position: absolute;
z-index: 6;
}
.CodeMirror-overlayscroll-horizontal {
bottom: 0; left: 0;
height: 6px;
}
.CodeMirror-overlayscroll-horizontal div {
bottom: 0;
height: 100%;
}
.CodeMirror-overlayscroll-vertical {
right: 0; top: 0;
width: 6px;
}
.CodeMirror-overlayscroll-vertical div {
right: 0;
width: 100%;
}

View File

@@ -1,141 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
function Bar(cls, orientation, scroll) {
this.orientation = orientation;
this.scroll = scroll;
this.screen = this.total = this.size = 1;
this.pos = 0;
this.node = document.createElement("div");
this.node.className = cls + "-" + orientation;
this.inner = this.node.appendChild(document.createElement("div"));
var self = this;
CodeMirror.on(this.inner, "mousedown", function(e) {
if (e.which != 1) return;
CodeMirror.e_preventDefault(e);
var axis = self.orientation == "horizontal" ? "pageX" : "pageY";
var start = e[axis], startpos = self.pos;
function done() {
CodeMirror.off(document, "mousemove", move);
CodeMirror.off(document, "mouseup", done);
}
function move(e) {
if (e.which != 1) return done();
self.moveTo(startpos + (e[axis] - start) * (self.total / self.size));
}
CodeMirror.on(document, "mousemove", move);
CodeMirror.on(document, "mouseup", done);
});
CodeMirror.on(this.node, "click", function(e) {
CodeMirror.e_preventDefault(e);
var innerBox = self.inner.getBoundingClientRect(), where;
if (self.orientation == "horizontal")
where = e.clientX < innerBox.left ? -1 : e.clientX > innerBox.right ? 1 : 0;
else
where = e.clientY < innerBox.top ? -1 : e.clientY > innerBox.bottom ? 1 : 0;
self.moveTo(self.pos + where * self.screen);
});
function onWheel(e) {
var moved = CodeMirror.wheelEventPixels(e)[self.orientation == "horizontal" ? "x" : "y"];
var oldPos = self.pos;
self.moveTo(self.pos + moved);
if (self.pos != oldPos) CodeMirror.e_preventDefault(e);
}
CodeMirror.on(this.node, "mousewheel", onWheel);
CodeMirror.on(this.node, "DOMMouseScroll", onWheel);
}
Bar.prototype.moveTo = function(pos, update) {
if (pos < 0) pos = 0;
if (pos > this.total - this.screen) pos = this.total - this.screen;
if (pos == this.pos) return;
this.pos = pos;
this.inner.style[this.orientation == "horizontal" ? "left" : "top"] =
(pos * (this.size / this.total)) + "px";
if (update !== false) this.scroll(pos, this.orientation);
};
Bar.prototype.update = function(scrollSize, clientSize, barSize) {
this.screen = clientSize;
this.total = scrollSize;
this.size = barSize;
// FIXME clip to min size?
this.inner.style[this.orientation == "horizontal" ? "width" : "height"] =
this.screen * (this.size / this.total) + "px";
this.inner.style[this.orientation == "horizontal" ? "left" : "top"] =
this.pos * (this.size / this.total) + "px";
};
function SimpleScrollbars(cls, place, scroll) {
this.addClass = cls;
this.horiz = new Bar(cls, "horizontal", scroll);
place(this.horiz.node);
this.vert = new Bar(cls, "vertical", scroll);
place(this.vert.node);
this.width = null;
}
SimpleScrollbars.prototype.update = function(measure) {
if (this.width == null) {
var style = window.getComputedStyle ? window.getComputedStyle(this.horiz.node) : this.horiz.node.currentStyle;
if (style) this.width = parseInt(style.height);
}
var width = this.width || 0;
var needsH = measure.scrollWidth > measure.clientWidth + 1;
var needsV = measure.scrollHeight > measure.clientHeight + 1;
this.vert.node.style.display = needsV ? "block" : "none";
this.horiz.node.style.display = needsH ? "block" : "none";
if (needsV) {
this.vert.update(measure.scrollHeight, measure.clientHeight,
measure.viewHeight - (needsH ? width : 0));
this.vert.node.style.display = "block";
this.vert.node.style.bottom = needsH ? width + "px" : "0";
}
if (needsH) {
this.horiz.update(measure.scrollWidth, measure.clientWidth,
measure.viewWidth - (needsV ? width : 0) - measure.barLeft);
this.horiz.node.style.right = needsV ? width + "px" : "0";
this.horiz.node.style.left = measure.barLeft + "px";
}
return {right: needsV ? width : 0, bottom: needsH ? width : 0};
};
SimpleScrollbars.prototype.setScrollTop = function(pos) {
this.vert.moveTo(pos, false);
};
SimpleScrollbars.prototype.setScrollLeft = function(pos) {
this.horiz.moveTo(pos, false);
};
SimpleScrollbars.prototype.clear = function() {
var parent = this.horiz.node.parentNode;
parent.removeChild(this.horiz.node);
parent.removeChild(this.vert.node);
};
CodeMirror.scrollbarModel.simple = function(place, scroll) {
return new SimpleScrollbars("CodeMirror-simplescroll", place, scroll);
};
CodeMirror.scrollbarModel.overlay = function(place, scroll) {
return new SimpleScrollbars("CodeMirror-overlayscroll", place, scroll);
};
});

View File

@@ -1,71 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Because sometimes you need to style the cursor's line.
//
// Adds an option 'styleActiveLine' which, when enabled, gives the
// active line's wrapping <div> the CSS class "CodeMirror-activeline",
// and gives its background <div> the class "CodeMirror-activeline-background".
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
var WRAP_CLASS = "CodeMirror-activeline";
var BACK_CLASS = "CodeMirror-activeline-background";
CodeMirror.defineOption("styleActiveLine", false, function(cm, val, old) {
var prev = old && old != CodeMirror.Init;
if (val && !prev) {
cm.state.activeLines = [];
updateActiveLines(cm, cm.listSelections());
cm.on("beforeSelectionChange", selectionChange);
} else if (!val && prev) {
cm.off("beforeSelectionChange", selectionChange);
clearActiveLines(cm);
delete cm.state.activeLines;
}
});
function clearActiveLines(cm) {
for (var i = 0; i < cm.state.activeLines.length; i++) {
cm.removeLineClass(cm.state.activeLines[i], "wrap", WRAP_CLASS);
cm.removeLineClass(cm.state.activeLines[i], "background", BACK_CLASS);
}
}
function sameArray(a, b) {
if (a.length != b.length) return false;
for (var i = 0; i < a.length; i++)
if (a[i] != b[i]) return false;
return true;
}
function updateActiveLines(cm, ranges) {
var active = [];
for (var i = 0; i < ranges.length; i++) {
var range = ranges[i];
if (!range.empty()) continue;
var line = cm.getLineHandleVisualStart(range.head.line);
if (active[active.length - 1] != line) active.push(line);
}
if (sameArray(cm.state.activeLines, active)) return;
cm.operation(function() {
clearActiveLines(cm);
for (var i = 0; i < active.length; i++) {
cm.addLineClass(active[i], "wrap", WRAP_CLASS);
cm.addLineClass(active[i], "background", BACK_CLASS);
}
cm.state.activeLines = active;
});
}
function selectionChange(cm, sel) {
updateActiveLines(cm, sel.ranges);
}
});

View File

@@ -1,118 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Because sometimes you need to mark the selected *text*.
//
// Adds an option 'styleSelectedText' which, when enabled, gives
// selected text the CSS class given as option value, or
// "CodeMirror-selectedtext" when the value is not a string.
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.defineOption("styleSelectedText", false, function(cm, val, old) {
var prev = old && old != CodeMirror.Init;
if (val && !prev) {
cm.state.markedSelection = [];
cm.state.markedSelectionStyle = typeof val == "string" ? val : "CodeMirror-selectedtext";
reset(cm);
cm.on("cursorActivity", onCursorActivity);
cm.on("change", onChange);
} else if (!val && prev) {
cm.off("cursorActivity", onCursorActivity);
cm.off("change", onChange);
clear(cm);
cm.state.markedSelection = cm.state.markedSelectionStyle = null;
}
});
function onCursorActivity(cm) {
cm.operation(function() { update(cm); });
}
function onChange(cm) {
if (cm.state.markedSelection.length)
cm.operation(function() { clear(cm); });
}
var CHUNK_SIZE = 8;
var Pos = CodeMirror.Pos;
var cmp = CodeMirror.cmpPos;
function coverRange(cm, from, to, addAt) {
if (cmp(from, to) == 0) return;
var array = cm.state.markedSelection;
var cls = cm.state.markedSelectionStyle;
for (var line = from.line;;) {
var start = line == from.line ? from : Pos(line, 0);
var endLine = line + CHUNK_SIZE, atEnd = endLine >= to.line;
var end = atEnd ? to : Pos(endLine, 0);
var mark = cm.markText(start, end, {className: cls});
if (addAt == null) array.push(mark);
else array.splice(addAt++, 0, mark);
if (atEnd) break;
line = endLine;
}
}
function clear(cm) {
var array = cm.state.markedSelection;
for (var i = 0; i < array.length; ++i) array[i].clear();
array.length = 0;
}
function reset(cm) {
clear(cm);
var ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++)
coverRange(cm, ranges[i].from(), ranges[i].to());
}
function update(cm) {
if (!cm.somethingSelected()) return clear(cm);
if (cm.listSelections().length > 1) return reset(cm);
var from = cm.getCursor("start"), to = cm.getCursor("end");
var array = cm.state.markedSelection;
if (!array.length) return coverRange(cm, from, to);
var coverStart = array[0].find(), coverEnd = array[array.length - 1].find();
if (!coverStart || !coverEnd || to.line - from.line < CHUNK_SIZE ||
cmp(from, coverEnd.to) >= 0 || cmp(to, coverStart.from) <= 0)
return reset(cm);
while (cmp(from, coverStart.from) > 0) {
array.shift().clear();
coverStart = array[0].find();
}
if (cmp(from, coverStart.from) < 0) {
if (coverStart.to.line - from.line < CHUNK_SIZE) {
array.shift().clear();
coverRange(cm, from, coverStart.to, 0);
} else {
coverRange(cm, from, coverStart.from, 0);
}
}
while (cmp(to, coverEnd.to) < 0) {
array.pop().clear();
coverEnd = array[array.length - 1].find();
}
if (cmp(to, coverEnd.to) > 0) {
if (to.line - coverEnd.from.line < CHUNK_SIZE) {
array.pop().clear();
coverRange(cm, coverEnd.from, to);
} else {
coverRange(cm, coverEnd.to, to);
}
}
}
});

View File

@@ -1,98 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.defineOption("selectionPointer", false, function(cm, val) {
var data = cm.state.selectionPointer;
if (data) {
CodeMirror.off(cm.getWrapperElement(), "mousemove", data.mousemove);
CodeMirror.off(cm.getWrapperElement(), "mouseout", data.mouseout);
CodeMirror.off(window, "scroll", data.windowScroll);
cm.off("cursorActivity", reset);
cm.off("scroll", reset);
cm.state.selectionPointer = null;
cm.display.lineDiv.style.cursor = "";
}
if (val) {
data = cm.state.selectionPointer = {
value: typeof val == "string" ? val : "default",
mousemove: function(event) { mousemove(cm, event); },
mouseout: function(event) { mouseout(cm, event); },
windowScroll: function() { reset(cm); },
rects: null,
mouseX: null, mouseY: null,
willUpdate: false
};
CodeMirror.on(cm.getWrapperElement(), "mousemove", data.mousemove);
CodeMirror.on(cm.getWrapperElement(), "mouseout", data.mouseout);
CodeMirror.on(window, "scroll", data.windowScroll);
cm.on("cursorActivity", reset);
cm.on("scroll", reset);
}
});
function mousemove(cm, event) {
var data = cm.state.selectionPointer;
if (event.buttons == null ? event.which : event.buttons) {
data.mouseX = data.mouseY = null;
} else {
data.mouseX = event.clientX;
data.mouseY = event.clientY;
}
scheduleUpdate(cm);
}
function mouseout(cm, event) {
if (!cm.getWrapperElement().contains(event.relatedTarget)) {
var data = cm.state.selectionPointer;
data.mouseX = data.mouseY = null;
scheduleUpdate(cm);
}
}
function reset(cm) {
cm.state.selectionPointer.rects = null;
scheduleUpdate(cm);
}
function scheduleUpdate(cm) {
if (!cm.state.selectionPointer.willUpdate) {
cm.state.selectionPointer.willUpdate = true;
setTimeout(function() {
update(cm);
cm.state.selectionPointer.willUpdate = false;
}, 50);
}
}
function update(cm) {
var data = cm.state.selectionPointer;
if (!data) return;
if (data.rects == null && data.mouseX != null) {
data.rects = [];
if (cm.somethingSelected()) {
for (var sel = cm.display.selectionDiv.firstChild; sel; sel = sel.nextSibling)
data.rects.push(sel.getBoundingClientRect());
}
}
var inside = false;
if (data.mouseX != null) for (var i = 0; i < data.rects.length; i++) {
var rect = data.rects[i];
if (rect.left <= data.mouseX && rect.right >= data.mouseX &&
rect.top <= data.mouseY && rect.bottom >= data.mouseY)
inside = true;
}
var cursor = inside ? data.value : "";
if (cm.display.lineDiv.style.cursor != cursor)
cm.display.lineDiv.style.cursor = cursor;
}
});

View File

@@ -1,86 +0,0 @@
.CodeMirror-Tern-completion {
padding-left: 22px;
position: relative;
}
.CodeMirror-Tern-completion:before {
position: absolute;
left: 2px;
bottom: 2px;
border-radius: 50%;
font-size: 12px;
font-weight: bold;
height: 15px;
width: 15px;
line-height: 16px;
text-align: center;
color: white;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.CodeMirror-Tern-completion-unknown:before {
content: "?";
background: #4bb;
}
.CodeMirror-Tern-completion-object:before {
content: "O";
background: #77c;
}
.CodeMirror-Tern-completion-fn:before {
content: "F";
background: #7c7;
}
.CodeMirror-Tern-completion-array:before {
content: "A";
background: #c66;
}
.CodeMirror-Tern-completion-number:before {
content: "1";
background: #999;
}
.CodeMirror-Tern-completion-string:before {
content: "S";
background: #999;
}
.CodeMirror-Tern-completion-bool:before {
content: "B";
background: #999;
}
.CodeMirror-Tern-completion-guess {
color: #999;
}
.CodeMirror-Tern-tooltip {
border: 1px solid silver;
border-radius: 3px;
color: #444;
padding: 2px 5px;
font-size: 90%;
font-family: monospace;
background-color: white;
white-space: pre-wrap;
max-width: 40em;
position: absolute;
z-index: 10;
-webkit-box-shadow: 2px 3px 5px rgba(0,0,0,.2);
-moz-box-shadow: 2px 3px 5px rgba(0,0,0,.2);
box-shadow: 2px 3px 5px rgba(0,0,0,.2);
transition: opacity 1s;
-moz-transition: opacity 1s;
-webkit-transition: opacity 1s;
-o-transition: opacity 1s;
-ms-transition: opacity 1s;
}
.CodeMirror-Tern-hint-doc {
max-width: 25em;
margin-top: -3px;
}
.CodeMirror-Tern-fname { color: black; }
.CodeMirror-Tern-farg { color: #70a; }
.CodeMirror-Tern-farg-current { text-decoration: underline; }
.CodeMirror-Tern-type { color: #07c; }
.CodeMirror-Tern-fhint-guess { opacity: .7; }

View File

@@ -1,697 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Glue code between CodeMirror and Tern.
//
// Create a CodeMirror.TernServer to wrap an actual Tern server,
// register open documents (CodeMirror.Doc instances) with it, and
// call its methods to activate the assisting functions that Tern
// provides.
//
// Options supported (all optional):
// * defs: An array of JSON definition data structures.
// * plugins: An object mapping plugin names to configuration
// options.
// * getFile: A function(name, c) that can be used to access files in
// the project that haven't been loaded yet. Simply do c(null) to
// indicate that a file is not available.
// * fileFilter: A function(value, docName, doc) that will be applied
// to documents before passing them on to Tern.
// * switchToDoc: A function(name, doc) that should, when providing a
// multi-file view, switch the view or focus to the named file.
// * showError: A function(editor, message) that can be used to
// override the way errors are displayed.
// * completionTip: Customize the content in tooltips for completions.
// Is passed a single argument—the completion's data as returned by
// Tern—and may return a string, DOM node, or null to indicate that
// no tip should be shown. By default the docstring is shown.
// * typeTip: Like completionTip, but for the tooltips shown for type
// queries.
// * responseFilter: A function(doc, query, request, error, data) that
// will be applied to the Tern responses before treating them
//
//
// It is possible to run the Tern server in a web worker by specifying
// these additional options:
// * useWorker: Set to true to enable web worker mode. You'll probably
// want to feature detect the actual value you use here, for example
// !!window.Worker.
// * workerScript: The main script of the worker. Point this to
// wherever you are hosting worker.js from this directory.
// * workerDeps: An array of paths pointing (relative to workerScript)
// to the Acorn and Tern libraries and any Tern plugins you want to
// load. Or, if you minified those into a single script and included
// them in the workerScript, simply leave this undefined.
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
// declare global: tern
CodeMirror.TernServer = function(options) {
var self = this;
this.options = options || {};
var plugins = this.options.plugins || (this.options.plugins = {});
if (!plugins.doc_comment) plugins.doc_comment = true;
if (this.options.useWorker) {
this.server = new WorkerServer(this);
} else {
this.server = new tern.Server({
getFile: function(name, c) { return getFile(self, name, c); },
async: true,
defs: this.options.defs || [],
plugins: plugins
});
}
this.docs = Object.create(null);
this.trackChange = function(doc, change) { trackChange(self, doc, change); };
this.cachedArgHints = null;
this.activeArgHints = null;
this.jumpStack = [];
this.getHint = function(cm, c) { return hint(self, cm, c); };
this.getHint.async = true;
};
CodeMirror.TernServer.prototype = {
addDoc: function(name, doc) {
var data = {doc: doc, name: name, changed: null};
this.server.addFile(name, docValue(this, data));
CodeMirror.on(doc, "change", this.trackChange);
return this.docs[name] = data;
},
delDoc: function(id) {
var found = resolveDoc(this, id);
if (!found) return;
CodeMirror.off(found.doc, "change", this.trackChange);
delete this.docs[found.name];
this.server.delFile(found.name);
},
hideDoc: function(id) {
closeArgHints(this);
var found = resolveDoc(this, id);
if (found && found.changed) sendDoc(this, found);
},
complete: function(cm) {
cm.showHint({hint: this.getHint});
},
showType: function(cm, pos, c) { showContextInfo(this, cm, pos, "type", c); },
showDocs: function(cm, pos, c) { showContextInfo(this, cm, pos, "documentation", c); },
updateArgHints: function(cm) { updateArgHints(this, cm); },
jumpToDef: function(cm) { jumpToDef(this, cm); },
jumpBack: function(cm) { jumpBack(this, cm); },
rename: function(cm) { rename(this, cm); },
selectName: function(cm) { selectName(this, cm); },
request: function (cm, query, c, pos) {
var self = this;
var doc = findDoc(this, cm.getDoc());
var request = buildRequest(this, doc, query, pos);
this.server.request(request, function (error, data) {
if (!error && self.options.responseFilter)
data = self.options.responseFilter(doc, query, request, error, data);
c(error, data);
});
},
destroy: function () {
if (this.worker) {
this.worker.terminate();
this.worker = null;
}
}
};
var Pos = CodeMirror.Pos;
var cls = "CodeMirror-Tern-";
var bigDoc = 250;
function getFile(ts, name, c) {
var buf = ts.docs[name];
if (buf)
c(docValue(ts, buf));
else if (ts.options.getFile)
ts.options.getFile(name, c);
else
c(null);
}
function findDoc(ts, doc, name) {
for (var n in ts.docs) {
var cur = ts.docs[n];
if (cur.doc == doc) return cur;
}
if (!name) for (var i = 0;; ++i) {
n = "[doc" + (i || "") + "]";
if (!ts.docs[n]) { name = n; break; }
}
return ts.addDoc(name, doc);
}
function resolveDoc(ts, id) {
if (typeof id == "string") return ts.docs[id];
if (id instanceof CodeMirror) id = id.getDoc();
if (id instanceof CodeMirror.Doc) return findDoc(ts, id);
}
function trackChange(ts, doc, change) {
var data = findDoc(ts, doc);
var argHints = ts.cachedArgHints;
if (argHints && argHints.doc == doc && cmpPos(argHints.start, change.to) <= 0)
ts.cachedArgHints = null;
var changed = data.changed;
if (changed == null)
data.changed = changed = {from: change.from.line, to: change.from.line};
var end = change.from.line + (change.text.length - 1);
if (change.from.line < changed.to) changed.to = changed.to - (change.to.line - end);
if (end >= changed.to) changed.to = end + 1;
if (changed.from > change.from.line) changed.from = change.from.line;
if (doc.lineCount() > bigDoc && change.to - changed.from > 100) setTimeout(function() {
if (data.changed && data.changed.to - data.changed.from > 100) sendDoc(ts, data);
}, 200);
}
function sendDoc(ts, doc) {
ts.server.request({files: [{type: "full", name: doc.name, text: docValue(ts, doc)}]}, function(error) {
if (error) window.console.error(error);
else doc.changed = null;
});
}
// Completion
function hint(ts, cm, c) {
ts.request(cm, {type: "completions", types: true, docs: true, urls: true}, function(error, data) {
if (error) return showError(ts, cm, error);
var completions = [], after = "";
var from = data.start, to = data.end;
if (cm.getRange(Pos(from.line, from.ch - 2), from) == "[\"" &&
cm.getRange(to, Pos(to.line, to.ch + 2)) != "\"]")
after = "\"]";
for (var i = 0; i < data.completions.length; ++i) {
var completion = data.completions[i], className = typeToIcon(completion.type);
if (data.guess) className += " " + cls + "guess";
completions.push({text: completion.name + after,
displayText: completion.name,
className: className,
data: completion});
}
var obj = {from: from, to: to, list: completions};
var tooltip = null;
CodeMirror.on(obj, "close", function() { remove(tooltip); });
CodeMirror.on(obj, "update", function() { remove(tooltip); });
CodeMirror.on(obj, "select", function(cur, node) {
remove(tooltip);
var content = ts.options.completionTip ? ts.options.completionTip(cur.data) : cur.data.doc;
if (content) {
tooltip = makeTooltip(node.parentNode.getBoundingClientRect().right + window.pageXOffset,
node.getBoundingClientRect().top + window.pageYOffset, content);
tooltip.className += " " + cls + "hint-doc";
}
});
c(obj);
});
}
function typeToIcon(type) {
var suffix;
if (type == "?") suffix = "unknown";
else if (type == "number" || type == "string" || type == "bool") suffix = type;
else if (/^fn\(/.test(type)) suffix = "fn";
else if (/^\[/.test(type)) suffix = "array";
else suffix = "object";
return cls + "completion " + cls + "completion-" + suffix;
}
// Type queries
function showContextInfo(ts, cm, pos, queryName, c) {
ts.request(cm, queryName, function(error, data) {
if (error) return showError(ts, cm, error);
if (ts.options.typeTip) {
var tip = ts.options.typeTip(data);
} else {
var tip = elt("span", null, elt("strong", null, data.type || "not found"));
if (data.doc)
tip.appendChild(document.createTextNode(" — " + data.doc));
if (data.url) {
tip.appendChild(document.createTextNode(" "));
var child = tip.appendChild(elt("a", null, "[docs]"));
child.href = data.url;
child.target = "_blank";
}
}
tempTooltip(cm, tip);
if (c) c();
}, pos);
}
// Maintaining argument hints
function updateArgHints(ts, cm) {
closeArgHints(ts);
if (cm.somethingSelected()) return;
var state = cm.getTokenAt(cm.getCursor()).state;
var inner = CodeMirror.innerMode(cm.getMode(), state);
if (inner.mode.name != "javascript") return;
var lex = inner.state.lexical;
if (lex.info != "call") return;
var ch, argPos = lex.pos || 0, tabSize = cm.getOption("tabSize");
for (var line = cm.getCursor().line, e = Math.max(0, line - 9), found = false; line >= e; --line) {
var str = cm.getLine(line), extra = 0;
for (var pos = 0;;) {
var tab = str.indexOf("\t", pos);
if (tab == -1) break;
extra += tabSize - (tab + extra) % tabSize - 1;
pos = tab + 1;
}
ch = lex.column - extra;
if (str.charAt(ch) == "(") {found = true; break;}
}
if (!found) return;
var start = Pos(line, ch);
var cache = ts.cachedArgHints;
if (cache && cache.doc == cm.getDoc() && cmpPos(start, cache.start) == 0)
return showArgHints(ts, cm, argPos);
ts.request(cm, {type: "type", preferFunction: true, end: start}, function(error, data) {
if (error || !data.type || !(/^fn\(/).test(data.type)) return;
ts.cachedArgHints = {
start: pos,
type: parseFnType(data.type),
name: data.exprName || data.name || "fn",
guess: data.guess,
doc: cm.getDoc()
};
showArgHints(ts, cm, argPos);
});
}
function showArgHints(ts, cm, pos) {
closeArgHints(ts);
var cache = ts.cachedArgHints, tp = cache.type;
var tip = elt("span", cache.guess ? cls + "fhint-guess" : null,
elt("span", cls + "fname", cache.name), "(");
for (var i = 0; i < tp.args.length; ++i) {
if (i) tip.appendChild(document.createTextNode(", "));
var arg = tp.args[i];
tip.appendChild(elt("span", cls + "farg" + (i == pos ? " " + cls + "farg-current" : ""), arg.name || "?"));
if (arg.type != "?") {
tip.appendChild(document.createTextNode(":\u00a0"));
tip.appendChild(elt("span", cls + "type", arg.type));
}
}
tip.appendChild(document.createTextNode(tp.rettype ? ") ->\u00a0" : ")"));
if (tp.rettype) tip.appendChild(elt("span", cls + "type", tp.rettype));
var place = cm.cursorCoords(null, "page");
ts.activeArgHints = makeTooltip(place.right + 1, place.bottom, tip);
}
function parseFnType(text) {
var args = [], pos = 3;
function skipMatching(upto) {
var depth = 0, start = pos;
for (;;) {
var next = text.charAt(pos);
if (upto.test(next) && !depth) return text.slice(start, pos);
if (/[{\[\(]/.test(next)) ++depth;
else if (/[}\]\)]/.test(next)) --depth;
++pos;
}
}
// Parse arguments
if (text.charAt(pos) != ")") for (;;) {
var name = text.slice(pos).match(/^([^, \(\[\{]+): /);
if (name) {
pos += name[0].length;
name = name[1];
}
args.push({name: name, type: skipMatching(/[\),]/)});
if (text.charAt(pos) == ")") break;
pos += 2;
}
var rettype = text.slice(pos).match(/^\) -> (.*)$/);
return {args: args, rettype: rettype && rettype[1]};
}
// Moving to the definition of something
function jumpToDef(ts, cm) {
function inner(varName) {
var req = {type: "definition", variable: varName || null};
var doc = findDoc(ts, cm.getDoc());
ts.server.request(buildRequest(ts, doc, req), function(error, data) {
if (error) return showError(ts, cm, error);
if (!data.file && data.url) { window.open(data.url); return; }
if (data.file) {
var localDoc = ts.docs[data.file], found;
if (localDoc && (found = findContext(localDoc.doc, data))) {
ts.jumpStack.push({file: doc.name,
start: cm.getCursor("from"),
end: cm.getCursor("to")});
moveTo(ts, doc, localDoc, found.start, found.end);
return;
}
}
showError(ts, cm, "Could not find a definition.");
});
}
if (!atInterestingExpression(cm))
dialog(cm, "Jump to variable", function(name) { if (name) inner(name); });
else
inner();
}
function jumpBack(ts, cm) {
var pos = ts.jumpStack.pop(), doc = pos && ts.docs[pos.file];
if (!doc) return;
moveTo(ts, findDoc(ts, cm.getDoc()), doc, pos.start, pos.end);
}
function moveTo(ts, curDoc, doc, start, end) {
doc.doc.setSelection(start, end);
if (curDoc != doc && ts.options.switchToDoc) {
closeArgHints(ts);
ts.options.switchToDoc(doc.name, doc.doc);
}
}
// The {line,ch} representation of positions makes this rather awkward.
function findContext(doc, data) {
var before = data.context.slice(0, data.contextOffset).split("\n");
var startLine = data.start.line - (before.length - 1);
var start = Pos(startLine, (before.length == 1 ? data.start.ch : doc.getLine(startLine).length) - before[0].length);
var text = doc.getLine(startLine).slice(start.ch);
for (var cur = startLine + 1; cur < doc.lineCount() && text.length < data.context.length; ++cur)
text += "\n" + doc.getLine(cur);
if (text.slice(0, data.context.length) == data.context) return data;
var cursor = doc.getSearchCursor(data.context, 0, false);
var nearest, nearestDist = Infinity;
while (cursor.findNext()) {
var from = cursor.from(), dist = Math.abs(from.line - start.line) * 10000;
if (!dist) dist = Math.abs(from.ch - start.ch);
if (dist < nearestDist) { nearest = from; nearestDist = dist; }
}
if (!nearest) return null;
if (before.length == 1)
nearest.ch += before[0].length;
else
nearest = Pos(nearest.line + (before.length - 1), before[before.length - 1].length);
if (data.start.line == data.end.line)
var end = Pos(nearest.line, nearest.ch + (data.end.ch - data.start.ch));
else
var end = Pos(nearest.line + (data.end.line - data.start.line), data.end.ch);
return {start: nearest, end: end};
}
function atInterestingExpression(cm) {
var pos = cm.getCursor("end"), tok = cm.getTokenAt(pos);
if (tok.start < pos.ch && (tok.type == "comment" || tok.type == "string")) return false;
return /\w/.test(cm.getLine(pos.line).slice(Math.max(pos.ch - 1, 0), pos.ch + 1));
}
// Variable renaming
function rename(ts, cm) {
var token = cm.getTokenAt(cm.getCursor());
if (!/\w/.test(token.string)) return showError(ts, cm, "Not at a variable");
dialog(cm, "New name for " + token.string, function(newName) {
ts.request(cm, {type: "rename", newName: newName, fullDocs: true}, function(error, data) {
if (error) return showError(ts, cm, error);
applyChanges(ts, data.changes);
});
});
}
function selectName(ts, cm) {
var name = findDoc(ts, cm.doc).name;
ts.request(cm, {type: "refs"}, function(error, data) {
if (error) return showError(ts, cm, error);
var ranges = [], cur = 0;
for (var i = 0; i < data.refs.length; i++) {
var ref = data.refs[i];
if (ref.file == name) {
ranges.push({anchor: ref.start, head: ref.end});
if (cmpPos(cur, ref.start) >= 0 && cmpPos(cur, ref.end) <= 0)
cur = ranges.length - 1;
}
}
cm.setSelections(ranges, cur);
});
}
var nextChangeOrig = 0;
function applyChanges(ts, changes) {
var perFile = Object.create(null);
for (var i = 0; i < changes.length; ++i) {
var ch = changes[i];
(perFile[ch.file] || (perFile[ch.file] = [])).push(ch);
}
for (var file in perFile) {
var known = ts.docs[file], chs = perFile[file];;
if (!known) continue;
chs.sort(function(a, b) { return cmpPos(b.start, a.start); });
var origin = "*rename" + (++nextChangeOrig);
for (var i = 0; i < chs.length; ++i) {
var ch = chs[i];
known.doc.replaceRange(ch.text, ch.start, ch.end, origin);
}
}
}
// Generic request-building helper
function buildRequest(ts, doc, query, pos) {
var files = [], offsetLines = 0, allowFragments = !query.fullDocs;
if (!allowFragments) delete query.fullDocs;
if (typeof query == "string") query = {type: query};
query.lineCharPositions = true;
if (query.end == null) {
query.end = pos || doc.doc.getCursor("end");
if (doc.doc.somethingSelected())
query.start = doc.doc.getCursor("start");
}
var startPos = query.start || query.end;
if (doc.changed) {
if (doc.doc.lineCount() > bigDoc && allowFragments !== false &&
doc.changed.to - doc.changed.from < 100 &&
doc.changed.from <= startPos.line && doc.changed.to > query.end.line) {
files.push(getFragmentAround(doc, startPos, query.end));
query.file = "#0";
var offsetLines = files[0].offsetLines;
if (query.start != null) query.start = Pos(query.start.line - -offsetLines, query.start.ch);
query.end = Pos(query.end.line - offsetLines, query.end.ch);
} else {
files.push({type: "full",
name: doc.name,
text: docValue(ts, doc)});
query.file = doc.name;
doc.changed = null;
}
} else {
query.file = doc.name;
}
for (var name in ts.docs) {
var cur = ts.docs[name];
if (cur.changed && cur != doc) {
files.push({type: "full", name: cur.name, text: docValue(ts, cur)});
cur.changed = null;
}
}
return {query: query, files: files};
}
function getFragmentAround(data, start, end) {
var doc = data.doc;
var minIndent = null, minLine = null, endLine, tabSize = 4;
for (var p = start.line - 1, min = Math.max(0, p - 50); p >= min; --p) {
var line = doc.getLine(p), fn = line.search(/\bfunction\b/);
if (fn < 0) continue;
var indent = CodeMirror.countColumn(line, null, tabSize);
if (minIndent != null && minIndent <= indent) continue;
minIndent = indent;
minLine = p;
}
if (minLine == null) minLine = min;
var max = Math.min(doc.lastLine(), end.line + 20);
if (minIndent == null || minIndent == CodeMirror.countColumn(doc.getLine(start.line), null, tabSize))
endLine = max;
else for (endLine = end.line + 1; endLine < max; ++endLine) {
var indent = CodeMirror.countColumn(doc.getLine(endLine), null, tabSize);
if (indent <= minIndent) break;
}
var from = Pos(minLine, 0);
return {type: "part",
name: data.name,
offsetLines: from.line,
text: doc.getRange(from, Pos(endLine, 0))};
}
// Generic utilities
var cmpPos = CodeMirror.cmpPos;
function elt(tagname, cls /*, ... elts*/) {
var e = document.createElement(tagname);
if (cls) e.className = cls;
for (var i = 2; i < arguments.length; ++i) {
var elt = arguments[i];
if (typeof elt == "string") elt = document.createTextNode(elt);
e.appendChild(elt);
}
return e;
}
function dialog(cm, text, f) {
if (cm.openDialog)
cm.openDialog(text + ": <input type=text>", f);
else
f(prompt(text, ""));
}
// Tooltips
function tempTooltip(cm, content) {
if (cm.state.ternTooltip) remove(cm.state.ternTooltip);
var where = cm.cursorCoords();
var tip = cm.state.ternTooltip = makeTooltip(where.right + 1, where.bottom, content);
function maybeClear() {
old = true;
if (!mouseOnTip) clear();
}
function clear() {
cm.state.ternTooltip = null;
if (!tip.parentNode) return;
cm.off("cursorActivity", clear);
cm.off('blur', clear);
cm.off('scroll', clear);
fadeOut(tip);
}
var mouseOnTip = false, old = false;
CodeMirror.on(tip, "mousemove", function() { mouseOnTip = true; });
CodeMirror.on(tip, "mouseout", function(e) {
if (!CodeMirror.contains(tip, e.relatedTarget || e.toElement)) {
if (old) clear();
else mouseOnTip = false;
}
});
setTimeout(maybeClear, 1700);
cm.on("cursorActivity", clear);
cm.on('blur', clear);
cm.on('scroll', clear);
}
function makeTooltip(x, y, content) {
var node = elt("div", cls + "tooltip", content);
node.style.left = x + "px";
node.style.top = y + "px";
document.body.appendChild(node);
return node;
}
function remove(node) {
var p = node && node.parentNode;
if (p) p.removeChild(node);
}
function fadeOut(tooltip) {
tooltip.style.opacity = "0";
setTimeout(function() { remove(tooltip); }, 1100);
}
function showError(ts, cm, msg) {
if (ts.options.showError)
ts.options.showError(cm, msg);
else
tempTooltip(cm, String(msg));
}
function closeArgHints(ts) {
if (ts.activeArgHints) { remove(ts.activeArgHints); ts.activeArgHints = null; }
}
function docValue(ts, doc) {
var val = doc.doc.getValue();
if (ts.options.fileFilter) val = ts.options.fileFilter(val, doc.name, doc.doc);
return val;
}
// Worker wrapper
function WorkerServer(ts) {
var worker = ts.worker = new Worker(ts.options.workerScript);
worker.postMessage({type: "init",
defs: ts.options.defs,
plugins: ts.options.plugins,
scripts: ts.options.workerDeps});
var msgId = 0, pending = {};
function send(data, c) {
if (c) {
data.id = ++msgId;
pending[msgId] = c;
}
worker.postMessage(data);
}
worker.onmessage = function(e) {
var data = e.data;
if (data.type == "getFile") {
getFile(ts, data.name, function(err, text) {
send({type: "getFile", err: String(err), text: text, id: data.id});
});
} else if (data.type == "debug") {
window.console.log(data.message);
} else if (data.id && pending[data.id]) {
pending[data.id](data.err, data.body);
delete pending[data.id];
}
};
worker.onerror = function(e) {
for (var id in pending) pending[id](e);
pending = {};
};
this.addFile = function(name, text) { send({type: "add", name: name, text: text}); };
this.delFile = function(name) { send({type: "del", name: name}); };
this.request = function(body, c) { send({type: "req", body: body}, c); };
}
});

View File

@@ -1,44 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// declare global: tern, server
var server;
this.onmessage = function(e) {
var data = e.data;
switch (data.type) {
case "init": return startServer(data.defs, data.plugins, data.scripts);
case "add": return server.addFile(data.name, data.text);
case "del": return server.delFile(data.name);
case "req": return server.request(data.body, function(err, reqData) {
postMessage({id: data.id, body: reqData, err: err && String(err)});
});
case "getFile":
var c = pending[data.id];
delete pending[data.id];
return c(data.err, data.text);
default: throw new Error("Unknown message type: " + data.type);
}
};
var nextId = 0, pending = {};
function getFile(file, c) {
postMessage({type: "getFile", name: file, id: ++nextId});
pending[nextId] = c;
}
function startServer(defs, plugins, scripts) {
if (scripts) importScripts.apply(null, scripts);
server = new tern.Server({
getFile: getFile,
async: true,
defs: defs,
plugins: plugins
});
}
var console = {
log: function(v) { postMessage({type: "debug", message: v}); }
};

View File

@@ -1,139 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
var Pos = CodeMirror.Pos;
function findParagraph(cm, pos, options) {
var startRE = options.paragraphStart || cm.getHelper(pos, "paragraphStart");
for (var start = pos.line, first = cm.firstLine(); start > first; --start) {
var line = cm.getLine(start);
if (startRE && startRE.test(line)) break;
if (!/\S/.test(line)) { ++start; break; }
}
var endRE = options.paragraphEnd || cm.getHelper(pos, "paragraphEnd");
for (var end = pos.line + 1, last = cm.lastLine(); end <= last; ++end) {
var line = cm.getLine(end);
if (endRE && endRE.test(line)) { ++end; break; }
if (!/\S/.test(line)) break;
}
return {from: start, to: end};
}
function findBreakPoint(text, column, wrapOn, killTrailingSpace) {
for (var at = column; at > 0; --at)
if (wrapOn.test(text.slice(at - 1, at + 1))) break;
if (at == 0) at = column;
var endOfText = at;
if (killTrailingSpace)
while (text.charAt(endOfText - 1) == " ") --endOfText;
return {from: endOfText, to: at};
}
function wrapRange(cm, from, to, options) {
from = cm.clipPos(from); to = cm.clipPos(to);
var column = options.column || 80;
var wrapOn = options.wrapOn || /\s\S|-[^\.\d]/;
var killTrailing = options.killTrailingSpace !== false;
var changes = [], curLine = "", curNo = from.line;
var lines = cm.getRange(from, to, false);
if (!lines.length) return null;
var leadingSpace = lines[0].match(/^[ \t]*/)[0];
for (var i = 0; i < lines.length; ++i) {
var text = lines[i], oldLen = curLine.length, spaceInserted = 0;
if (curLine && text && !wrapOn.test(curLine.charAt(curLine.length - 1) + text.charAt(0))) {
curLine += " ";
spaceInserted = 1;
}
var spaceTrimmed = "";
if (i) {
spaceTrimmed = text.match(/^\s*/)[0];
text = text.slice(spaceTrimmed.length);
}
curLine += text;
if (i) {
var firstBreak = curLine.length > column && leadingSpace == spaceTrimmed &&
findBreakPoint(curLine, column, wrapOn, killTrailing);
// If this isn't broken, or is broken at a different point, remove old break
if (!firstBreak || firstBreak.from != oldLen || firstBreak.to != oldLen + spaceInserted) {
changes.push({text: [spaceInserted ? " " : ""],
from: Pos(curNo, oldLen),
to: Pos(curNo + 1, spaceTrimmed.length)});
} else {
curLine = leadingSpace + text;
++curNo;
}
}
while (curLine.length > column) {
var bp = findBreakPoint(curLine, column, wrapOn, killTrailing);
changes.push({text: ["", leadingSpace],
from: Pos(curNo, bp.from),
to: Pos(curNo, bp.to)});
curLine = leadingSpace + curLine.slice(bp.to);
++curNo;
}
}
if (changes.length) cm.operation(function() {
for (var i = 0; i < changes.length; ++i) {
var change = changes[i];
cm.replaceRange(change.text, change.from, change.to);
}
});
return changes.length ? {from: changes[0].from, to: CodeMirror.changeEnd(changes[changes.length - 1])} : null;
}
CodeMirror.defineExtension("wrapParagraph", function(pos, options) {
options = options || {};
if (!pos) pos = this.getCursor();
var para = findParagraph(this, pos, options);
return wrapRange(this, Pos(para.from, 0), Pos(para.to - 1), options);
});
CodeMirror.commands.wrapLines = function(cm) {
cm.operation(function() {
var ranges = cm.listSelections(), at = cm.lastLine() + 1;
for (var i = ranges.length - 1; i >= 0; i--) {
var range = ranges[i], span;
if (range.empty()) {
var para = findParagraph(cm, range.head, {});
span = {from: Pos(para.from, 0), to: Pos(para.to - 1)};
} else {
span = {from: range.from(), to: range.to()};
}
if (span.to.line >= at) continue;
at = span.from.line;
wrapRange(cm, span.from, span.to, {});
}
});
};
CodeMirror.defineExtension("wrapRange", function(from, to, options) {
return wrapRange(this, from, to, options || {});
});
CodeMirror.defineExtension("wrapParagraphsInRange", function(from, to, options) {
options = options || {};
var cm = this, paras = [];
for (var line = from.line; line <= to.line;) {
var para = findParagraph(cm, Pos(line, 0), options);
paras.push(para);
line = para.to;
}
var madeChange = false;
if (paras.length) cm.operation(function() {
for (var i = paras.length - 1; i >= 0; --i)
madeChange = madeChange || wrapRange(cm, Pos(paras[i].from, 0), Pos(paras[i].to - 1), options);
});
return madeChange;
});
});

Some files were not shown because too many files have changed in this diff Show More