Initial source tree
This commit is contained in:
Коммит
cfe0f04ade
|
@ -0,0 +1,33 @@
|
|||
image: Visual Studio 2017
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- stable
|
||||
|
||||
# Don't create a build when a PR is opened
|
||||
skip_branch_with_pr: true
|
||||
|
||||
nuget:
|
||||
disable_publish_on_pr: true
|
||||
|
||||
skip_commits:
|
||||
files:
|
||||
- 'doc/**/*.*'
|
||||
|
||||
init:
|
||||
- ps: git config --global core.autocrlf true
|
||||
|
||||
build_script:
|
||||
- cmd: git submodule update --init --recursive
|
||||
- ps: .\build\build.ps1 -script build\build.cake
|
||||
|
||||
artifacts:
|
||||
- path: .\build\nuget\*.nupkg
|
||||
|
||||
deploy:
|
||||
provider: NuGet
|
||||
api_key:
|
||||
secure: q2moGyPXNP7agMjH6aHxbg8a9Q4ftB/al9aZPYL97Fdte0cZ+d1ak0yoBFc1eWNr
|
||||
skip_symbols: true
|
||||
artifact: /.*\.nupkg/
|
|
@ -0,0 +1,63 @@
|
|||
###############################################################################
|
||||
# Set default behavior to automatically normalize line endings.
|
||||
###############################################################################
|
||||
* text=auto
|
||||
|
||||
###############################################################################
|
||||
# Set default behavior for command prompt diff.
|
||||
#
|
||||
# This is need for earlier builds of msysgit that does not have it on by
|
||||
# default for csharp files.
|
||||
# Note: This is only used by command line
|
||||
###############################################################################
|
||||
#*.cs diff=csharp
|
||||
|
||||
###############################################################################
|
||||
# Set the merge driver for project and solution files
|
||||
#
|
||||
# Merging from the command prompt will add diff markers to the files if there
|
||||
# are conflicts (Merging from VS is not affected by the settings below, in VS
|
||||
# the diff markers are never inserted). Diff markers may cause the following
|
||||
# file extensions to fail to load in VS. An alternative would be to treat
|
||||
# these files as binary and thus will always conflict and require user
|
||||
# intervention with every merge. To do so, just uncomment the entries below
|
||||
###############################################################################
|
||||
#*.sln merge=binary
|
||||
#*.csproj merge=binary
|
||||
#*.vbproj merge=binary
|
||||
#*.vcxproj merge=binary
|
||||
#*.vcproj merge=binary
|
||||
#*.dbproj merge=binary
|
||||
#*.fsproj merge=binary
|
||||
#*.lsproj merge=binary
|
||||
#*.wixproj merge=binary
|
||||
#*.modelproj merge=binary
|
||||
#*.sqlproj merge=binary
|
||||
#*.wwaproj merge=binary
|
||||
|
||||
###############################################################################
|
||||
# behavior for image files
|
||||
#
|
||||
# image files are treated as binary by default.
|
||||
###############################################################################
|
||||
#*.jpg binary
|
||||
#*.png binary
|
||||
#*.gif binary
|
||||
|
||||
###############################################################################
|
||||
# diff behavior for common document formats
|
||||
#
|
||||
# Convert binary document formats to text before diffing them. This feature
|
||||
# is only available from the command line. Turn it on by uncommenting the
|
||||
# entries below.
|
||||
###############################################################################
|
||||
#*.doc diff=astextplain
|
||||
#*.DOC diff=astextplain
|
||||
#*.docx diff=astextplain
|
||||
#*.DOCX diff=astextplain
|
||||
#*.dot diff=astextplain
|
||||
#*.DOT diff=astextplain
|
||||
#*.pdf diff=astextplain
|
||||
#*.PDF diff=astextplain
|
||||
#*.rtf diff=astextplain
|
||||
#*.RTF diff=astextplain
|
|
@ -0,0 +1,247 @@
|
|||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
[Xx]64/
|
||||
[Xx]86/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Gg]enerated[Ff]iles/
|
||||
|
||||
# Visual Studio 2015 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUNIT
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# DNX
|
||||
project.lock.json
|
||||
artifacts/
|
||||
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_i.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# JustCode is a .NET coding add-in
|
||||
.JustCode
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
|
||||
# TODO: Un-comment the next line if you do not want to checkin
|
||||
# your web deploy settings because they may include unencrypted
|
||||
# passwords
|
||||
#*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/packages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/packages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/packages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignoreable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Microsoft Azure ApplicationInsights config file
|
||||
ApplicationInsights.config
|
||||
|
||||
# Windows Store app package directory
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
[Ss]tyle[Cc]op.*
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
node_modules/
|
||||
orleans.codegen.cs
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# LightSwitch generated files
|
||||
GeneratedArtifacts/
|
||||
ModelManifest.xml
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
build/tools/**
|
||||
!build/tools/packages.config
|
|
@ -0,0 +1,3 @@
|
|||
[submodule "src/Uno.Wasm.Bootstrap/linker"]
|
||||
path = src/Uno.Wasm.Bootstrap/linker
|
||||
url = https://github.com/mono/linker.git
|
|
@ -0,0 +1,209 @@
|
|||
# Uno.Roslyn
|
||||
|
||||
Copyright (c) nventive
|
||||
|
||||
All rights reserved.
|
||||
|
||||
# Apache 2.0 License
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"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.
|
|
@ -0,0 +1,67 @@
|
|||
# Uno.Wasm.Bootstrap
|
||||
|
||||
Uno.Wasm.Bootstrap provides a simple way to package a C# .NET Standard 2.0 library, and run it from a compatible browser environment.
|
||||
|
||||
It is a standalone Mono Web Assembly (WASM) sdk bootstrapper taking the form of a nuget package.
|
||||
|
||||
Installing it on a .NET Standard 2.0 library with an entry point allows to publish it as part of a WASM distribution folder, along with CSS, Javascript and content files.
|
||||
|
||||
This package only provides the bootstrapping features to run a .NET assembly and write to the javascript console, through `Console.WriteLine`.
|
||||
|
||||
This package is based on the excellent work from @praeclarum's [OOui Wasm MSBuild task](https://github.com/praeclarum/Ooui).
|
||||
|
||||
## How to use the package
|
||||
* Create a .NET Standard 2.0 library, with the following basic definition:
|
||||
```xml
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Uno.Wasm.Bootstrapp" Version="1.0.0-dev.16" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
```
|
||||
|
||||
* Add a main entry point:
|
||||
```csharp
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
Console.WriteLine("Hello from C#!");
|
||||
}
|
||||
}
|
||||
```
|
||||
* Build the project, the WASM output will be located in `bin\Debug\netstandard2.0\dist`.
|
||||
* Run the `server.py`, which will open an HTTP server on http://localhost:8000. On Windows, use Python tools or the excellent Linux Subsystem.
|
||||
* The output of the Console.WriteLine will appear in the javascript debugging console
|
||||
|
||||
## Features
|
||||
### Support for additional JS files
|
||||
Providing additional JS files is done through the inclusion of `EmbeddedResource` msbuild item files, in a project folder named `WasmScripts`.
|
||||
Files are processed as embedded resources to allow for libraries to provide javascript files.
|
||||
|
||||
### Support for additional CSS files
|
||||
Additional CSS files are supported through the inclusion of `EmbeddedResource` msbuild item files, in a project folder named `WasmCSS`.
|
||||
|
||||
### Support for additional Content files
|
||||
Additional CSS files are supported through the inclusion of `Content` files. The folder structure is preserved in the output `dist` folder.
|
||||
|
||||
### Linker configuration
|
||||
The linker may be configured via the inclusion of `LinkerDescriptors` msbuild item files.
|
||||
|
||||
The file format of the descriptor can [be found here](https://github.com/mono/linker/tree/master/linker#syntax-of-xml-descriptor).
|
||||
|
||||
### Configuration of the runtime
|
||||
- The msbuild property `RuntimeDebugLogging` can be set to `true` to allow for mono to output additional debugging details.
|
||||
- The msbuild property `RuntimeConfiguration` allows for the selection of the debug runtime, but is mainly used for debugging the runtime itself. The value can either be `release` or `debug`.
|
||||
|
||||
## TODO
|
||||
Lots!
|
||||
- The main missing part is the ability to change the index.html, but it should pretty easy to add.
|
||||
- The other one is the ability to use an actual release of the mono-wasm release.
|
|
@ -0,0 +1,24 @@
|
|||
// ******************************************************************
|
||||
// Copyright <20> 2015-2018 nventive inc. All rights reserved.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// ******************************************************************
|
||||
[assembly: System.Reflection.AssemblyVersion("1.0.0.0")]
|
||||
[assembly: System.Reflection.AssemblyFileVersion("1.0.8888")]
|
||||
[assembly: System.Reflection.AssemblyInformationalVersion("1.0.8888 - ")]
|
||||
[assembly: System.Reflection.AssemblyProduct("Uno.Wasm.ShellBase")]
|
||||
[assembly: System.Reflection.AssemblyCompany("nventive")]
|
||||
[assembly: System.Reflection.AssemblyCopyright("Copyright (C) nVentive 2011-2018")]
|
||||
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
@ECHO OFF
|
||||
PowerShell.exe -file build.ps1 -target=UpdateHeaders -Verbosity Verbose
|
||||
PAUSE
|
|
@ -0,0 +1,151 @@
|
|||
#addin "nuget:?package=Cake.FileHelpers"
|
||||
#addin "nuget:?package=Cake.Powershell"
|
||||
#tool "nuget:?package=GitVersion.CommandLine"
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// ARGUMENTS
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
var target = Argument("target", "Default");
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// VERSIONS
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
var gitVersioningVersion = "2.0.41";
|
||||
var signClientVersion = "0.9.0";
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// VARIABLES
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
var baseDir = MakeAbsolute(Directory("../")).ToString();
|
||||
var buildDir = baseDir + "/build";
|
||||
var Solution = baseDir + "/src/Uno.Wasm.Bootstrap.sln";
|
||||
var toolsDir = buildDir + "/tools";
|
||||
GitVersion versionInfo = null;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// METHODS
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
void VerifyHeaders(bool Replace)
|
||||
{
|
||||
var header = FileReadText("header.txt") + "\r\n";
|
||||
bool hasMissing = false;
|
||||
|
||||
Func<IFileSystemInfo, bool> exclude_objDir =
|
||||
fileSystemInfo => !fileSystemInfo.Path.Segments.Contains("obj");
|
||||
|
||||
var files = GetFiles(baseDir + "/**/*.cs", exclude_objDir).Where(file =>
|
||||
{
|
||||
var path = file.ToString();
|
||||
return !(path.EndsWith(".g.cs") || path.EndsWith(".i.cs") || System.IO.Path.GetFileName(path).Contains("TemporaryGeneratedFile"));
|
||||
});
|
||||
|
||||
Information("\nChecking " + files.Count() + " file header(s)");
|
||||
foreach(var file in files)
|
||||
{
|
||||
var oldContent = FileReadText(file);
|
||||
if(oldContent.Contains("// <auto-generated>"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var rgx = new Regex("^(//.*\r?\n|\r?\n)*");
|
||||
var newContent = header + rgx.Replace(oldContent, "");
|
||||
|
||||
if(!newContent.Equals(oldContent, StringComparison.Ordinal))
|
||||
{
|
||||
if(Replace)
|
||||
{
|
||||
Information("\nUpdating " + file + " header...");
|
||||
FileWriteText(file, newContent);
|
||||
}
|
||||
else
|
||||
{
|
||||
Error("\nWrong/missing header on " + file);
|
||||
hasMissing = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!Replace && hasMissing)
|
||||
{
|
||||
throw new Exception("Please run UpdateHeaders.bat or '.\\build.ps1 -target=UpdateHeaders' and commit the changes.");
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// DEFAULT TASK
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
Task("Build")
|
||||
.IsDependentOn("Version")
|
||||
.Description("Build all projects and get the assemblies")
|
||||
.Does(() =>
|
||||
{
|
||||
Information("\nBuilding Solution");
|
||||
|
||||
var buildSettings = new MSBuildSettings
|
||||
{
|
||||
MaxCpuCount = 1
|
||||
}
|
||||
.SetConfiguration("Release")
|
||||
.WithProperty("PackageVersion", versionInfo.FullSemVer)
|
||||
.WithProperty("InformationalVersion", versionInfo.InformationalVersion)
|
||||
.WithProperty("PackageOutputPath", System.IO.Path.Combine(buildDir, "nuget"))
|
||||
.WithTarget("Restore")
|
||||
.WithTarget("Build")
|
||||
.WithTarget("Pack");
|
||||
|
||||
MSBuild(Solution, buildSettings);
|
||||
});
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// TASK TARGETS
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
Task("Default")
|
||||
.IsDependentOn("Build");
|
||||
|
||||
Task("UpdateHeaders")
|
||||
.Description("Updates the headers in *.cs files")
|
||||
.Does(() =>
|
||||
{
|
||||
VerifyHeaders(true);
|
||||
});
|
||||
|
||||
Task("Version")
|
||||
.Description("Updates target versions")
|
||||
.Does(() =>
|
||||
{
|
||||
versionInfo = GitVersion(new GitVersionSettings {
|
||||
UpdateAssemblyInfo = true,
|
||||
UpdateAssemblyInfoFilePath = baseDir + "/build/AssemblyVersion.cs"
|
||||
});
|
||||
|
||||
Information($"FullSemVer: {versionInfo.FullSemVer} Sha: {versionInfo.Sha}");
|
||||
|
||||
var files = new[] {
|
||||
@"..\src\Uno.Wasm.Bootstrap\Uno.Wasm.Bootstrap.csproj",
|
||||
@"..\src\Uno.Wasm.Bootstrap\ShellTask.cs",
|
||||
@"..\src\Uno.Wasm.Bootstrap\build\Uno.Wasm.Bootstrap.targets"
|
||||
};
|
||||
|
||||
foreach(var file in files)
|
||||
{
|
||||
var text = System.IO.File.ReadAllText(file);
|
||||
System.IO.File.WriteAllText(file, text.Replace("v0", "v" + versionInfo.Sha));
|
||||
}
|
||||
});
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// EXECUTION
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
RunTarget(target);
|
|
@ -0,0 +1,235 @@
|
|||
##########################################################################
|
||||
# This is the Cake bootstrapper script for PowerShell.
|
||||
# This file was downloaded from https://github.com/cake-build/resources
|
||||
# Feel free to change this file to fit your needs.
|
||||
##########################################################################
|
||||
|
||||
<#
|
||||
|
||||
.SYNOPSIS
|
||||
This is a Powershell script to bootstrap a Cake build.
|
||||
|
||||
.DESCRIPTION
|
||||
This Powershell script will download NuGet if missing, restore NuGet tools (including Cake)
|
||||
and execute your Cake build script with the parameters you provide.
|
||||
|
||||
.PARAMETER Script
|
||||
The build script to execute.
|
||||
.PARAMETER Target
|
||||
The build script target to run.
|
||||
.PARAMETER Configuration
|
||||
The build configuration to use.
|
||||
.PARAMETER Verbosity
|
||||
Specifies the amount of information to be displayed.
|
||||
.PARAMETER ShowDescription
|
||||
Shows description about tasks.
|
||||
.PARAMETER DryRun
|
||||
Performs a dry run.
|
||||
.PARAMETER Experimental
|
||||
Uses the nightly builds of the Roslyn script engine.
|
||||
.PARAMETER Mono
|
||||
Uses the Mono Compiler rather than the Roslyn script engine.
|
||||
.PARAMETER SkipToolPackageRestore
|
||||
Skips restoring of packages.
|
||||
.PARAMETER ScriptArgs
|
||||
Remaining arguments are added here.
|
||||
|
||||
.LINK
|
||||
https://cakebuild.net
|
||||
|
||||
#>
|
||||
|
||||
[CmdletBinding()]
|
||||
Param(
|
||||
[string]$Script = "build.cake",
|
||||
[string]$Target,
|
||||
[string]$Configuration,
|
||||
[ValidateSet("Quiet", "Minimal", "Normal", "Verbose", "Diagnostic")]
|
||||
[string]$Verbosity,
|
||||
[switch]$ShowDescription,
|
||||
[Alias("WhatIf", "Noop")]
|
||||
[switch]$DryRun,
|
||||
[switch]$Experimental,
|
||||
[switch]$Mono,
|
||||
[switch]$SkipToolPackageRestore,
|
||||
[Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)]
|
||||
[string[]]$ScriptArgs
|
||||
)
|
||||
|
||||
[Reflection.Assembly]::LoadWithPartialName("System.Security") | Out-Null
|
||||
function MD5HashFile([string] $filePath)
|
||||
{
|
||||
if ([string]::IsNullOrEmpty($filePath) -or !(Test-Path $filePath -PathType Leaf))
|
||||
{
|
||||
return $null
|
||||
}
|
||||
|
||||
[System.IO.Stream] $file = $null;
|
||||
[System.Security.Cryptography.MD5] $md5 = $null;
|
||||
try
|
||||
{
|
||||
$md5 = [System.Security.Cryptography.MD5]::Create()
|
||||
$file = [System.IO.File]::OpenRead($filePath)
|
||||
return [System.BitConverter]::ToString($md5.ComputeHash($file))
|
||||
}
|
||||
finally
|
||||
{
|
||||
if ($file -ne $null)
|
||||
{
|
||||
$file.Dispose()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function GetProxyEnabledWebClient
|
||||
{
|
||||
$wc = New-Object System.Net.WebClient
|
||||
$proxy = [System.Net.WebRequest]::GetSystemWebProxy()
|
||||
$proxy.Credentials = [System.Net.CredentialCache]::DefaultCredentials
|
||||
$wc.Proxy = $proxy
|
||||
return $wc
|
||||
}
|
||||
|
||||
Write-Host "Preparing to run build script..."
|
||||
|
||||
if(!$PSScriptRoot){
|
||||
$PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent
|
||||
}
|
||||
|
||||
$TOOLS_DIR = Join-Path $PSScriptRoot "tools"
|
||||
$ADDINS_DIR = Join-Path $TOOLS_DIR "Addins"
|
||||
$MODULES_DIR = Join-Path $TOOLS_DIR "Modules"
|
||||
$NUGET_EXE = Join-Path $TOOLS_DIR "nuget.exe"
|
||||
$CAKE_EXE = Join-Path $TOOLS_DIR "Cake/Cake.exe"
|
||||
$NUGET_URL = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe"
|
||||
$PACKAGES_CONFIG = Join-Path $TOOLS_DIR "packages.config"
|
||||
$PACKAGES_CONFIG_MD5 = Join-Path $TOOLS_DIR "packages.config.md5sum"
|
||||
$ADDINS_PACKAGES_CONFIG = Join-Path $ADDINS_DIR "packages.config"
|
||||
$MODULES_PACKAGES_CONFIG = Join-Path $MODULES_DIR "packages.config"
|
||||
|
||||
# Make sure tools folder exists
|
||||
if ((Test-Path $PSScriptRoot) -and !(Test-Path $TOOLS_DIR)) {
|
||||
Write-Verbose -Message "Creating tools directory..."
|
||||
New-Item -Path $TOOLS_DIR -Type directory | out-null
|
||||
}
|
||||
|
||||
# Make sure that packages.config exist.
|
||||
if (!(Test-Path $PACKAGES_CONFIG)) {
|
||||
Write-Verbose -Message "Downloading packages.config..."
|
||||
try {
|
||||
$wc = GetProxyEnabledWebClient
|
||||
$wc.DownloadFile("https://cakebuild.net/download/bootstrapper/packages", $PACKAGES_CONFIG) } catch {
|
||||
Throw "Could not download packages.config."
|
||||
}
|
||||
}
|
||||
|
||||
# Try find NuGet.exe in path if not exists
|
||||
if (!(Test-Path $NUGET_EXE)) {
|
||||
Write-Verbose -Message "Trying to find nuget.exe in PATH..."
|
||||
$existingPaths = $Env:Path -Split ';' | Where-Object { (![string]::IsNullOrEmpty($_)) -and (Test-Path $_ -PathType Container) }
|
||||
$NUGET_EXE_IN_PATH = Get-ChildItem -Path $existingPaths -Filter "nuget.exe" | Select -First 1
|
||||
if ($NUGET_EXE_IN_PATH -ne $null -and (Test-Path $NUGET_EXE_IN_PATH.FullName)) {
|
||||
Write-Verbose -Message "Found in PATH at $($NUGET_EXE_IN_PATH.FullName)."
|
||||
$NUGET_EXE = $NUGET_EXE_IN_PATH.FullName
|
||||
}
|
||||
}
|
||||
|
||||
# Try download NuGet.exe if not exists
|
||||
if (!(Test-Path $NUGET_EXE)) {
|
||||
Write-Verbose -Message "Downloading NuGet.exe..."
|
||||
try {
|
||||
$wc = GetProxyEnabledWebClient
|
||||
$wc.DownloadFile($NUGET_URL, $NUGET_EXE)
|
||||
} catch {
|
||||
Throw "Could not download NuGet.exe."
|
||||
}
|
||||
}
|
||||
|
||||
# Save nuget.exe path to environment to be available to child processed
|
||||
$ENV:NUGET_EXE = $NUGET_EXE
|
||||
|
||||
# Restore tools from NuGet?
|
||||
if(-Not $SkipToolPackageRestore.IsPresent) {
|
||||
Push-Location
|
||||
Set-Location $TOOLS_DIR
|
||||
|
||||
# Check for changes in packages.config and remove installed tools if true.
|
||||
[string] $md5Hash = MD5HashFile($PACKAGES_CONFIG)
|
||||
if((!(Test-Path $PACKAGES_CONFIG_MD5)) -Or
|
||||
($md5Hash -ne (Get-Content $PACKAGES_CONFIG_MD5 ))) {
|
||||
Write-Verbose -Message "Missing or changed package.config hash..."
|
||||
Get-ChildItem -Exclude packages.config,nuget.exe,Cake.Bakery |
|
||||
Remove-Item -Recurse
|
||||
}
|
||||
|
||||
Write-Verbose -Message "Restoring tools from NuGet..."
|
||||
$NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$TOOLS_DIR`""
|
||||
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Throw "An error occurred while restoring NuGet tools."
|
||||
}
|
||||
else
|
||||
{
|
||||
$md5Hash | Out-File $PACKAGES_CONFIG_MD5 -Encoding "ASCII"
|
||||
}
|
||||
Write-Verbose -Message ($NuGetOutput | out-string)
|
||||
|
||||
Pop-Location
|
||||
}
|
||||
|
||||
# Restore addins from NuGet
|
||||
if (Test-Path $ADDINS_PACKAGES_CONFIG) {
|
||||
Push-Location
|
||||
Set-Location $ADDINS_DIR
|
||||
|
||||
Write-Verbose -Message "Restoring addins from NuGet..."
|
||||
$NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$ADDINS_DIR`""
|
||||
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Throw "An error occurred while restoring NuGet addins."
|
||||
}
|
||||
|
||||
Write-Verbose -Message ($NuGetOutput | out-string)
|
||||
|
||||
Pop-Location
|
||||
}
|
||||
|
||||
# Restore modules from NuGet
|
||||
if (Test-Path $MODULES_PACKAGES_CONFIG) {
|
||||
Push-Location
|
||||
Set-Location $MODULES_DIR
|
||||
|
||||
Write-Verbose -Message "Restoring modules from NuGet..."
|
||||
$NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$MODULES_DIR`""
|
||||
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Throw "An error occurred while restoring NuGet modules."
|
||||
}
|
||||
|
||||
Write-Verbose -Message ($NuGetOutput | out-string)
|
||||
|
||||
Pop-Location
|
||||
}
|
||||
|
||||
# Make sure that Cake has been installed.
|
||||
if (!(Test-Path $CAKE_EXE)) {
|
||||
Throw "Could not find Cake.exe at $CAKE_EXE"
|
||||
}
|
||||
|
||||
|
||||
|
||||
# Build Cake arguments
|
||||
$cakeArguments = @("$Script");
|
||||
if ($Target) { $cakeArguments += "-target=$Target" }
|
||||
if ($Configuration) { $cakeArguments += "-configuration=$Configuration" }
|
||||
if ($Verbosity) { $cakeArguments += "-verbosity=$Verbosity" }
|
||||
if ($ShowDescription) { $cakeArguments += "-showdescription" }
|
||||
if ($DryRun) { $cakeArguments += "-dryrun" }
|
||||
if ($Experimental) { $cakeArguments += "-experimental" }
|
||||
if ($Mono) { $cakeArguments += "-mono" }
|
||||
$cakeArguments += $ScriptArgs
|
||||
|
||||
# Start Cake
|
||||
Write-Host "Running build script..."
|
||||
&$CAKE_EXE $cakeArguments
|
||||
exit $LASTEXITCODE
|
|
@ -0,0 +1,16 @@
|
|||
// ******************************************************************
|
||||
// Copyright © 2015-2018 nventive inc. All rights reserved.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// ******************************************************************
|
Двоичный файл не отображается.
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Cake" version="0.24.0" />
|
||||
</packages>
|
|
@ -0,0 +1,15 @@
|
|||
assembly-versioning-scheme: MajorMinorPatch
|
||||
mode: ContinuousDeployment
|
||||
next-version: 1.0.0
|
||||
continuous-delivery-fallback-tag: ""
|
||||
branches:
|
||||
master:
|
||||
tag: dev
|
||||
(stable):
|
||||
tag: ""
|
||||
dev/.*?/(.*?):
|
||||
tag: dev.{BranchName}
|
||||
projects/(.*?):
|
||||
tag: proj-{BranchName}
|
||||
ignore:
|
||||
sha: []
|
|
@ -0,0 +1,34 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.27520.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Uno.Wasm.Sample", "Uno.Wasm.Sample\Uno.Wasm.Sample.csproj", "{5641753C-F10C-4CC0-881B-1734B25E0F48}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{A3899B5E-FDE5-4F5B-B960-6B2BE73685B1} = {A3899B5E-FDE5-4F5B-B960-6B2BE73685B1}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Uno.Wasm.Bootstrap", "Uno.Wasm.Bootstrap\Uno.Wasm.Bootstrap.csproj", "{A3899B5E-FDE5-4F5B-B960-6B2BE73685B1}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{5641753C-F10C-4CC0-881B-1734B25E0F48}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{5641753C-F10C-4CC0-881B-1734B25E0F48}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{5641753C-F10C-4CC0-881B-1734B25E0F48}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{5641753C-F10C-4CC0-881B-1734B25E0F48}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A3899B5E-FDE5-4F5B-B960-6B2BE73685B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A3899B5E-FDE5-4F5B-B960-6B2BE73685B1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A3899B5E-FDE5-4F5B-B960-6B2BE73685B1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A3899B5E-FDE5-4F5B-B960-6B2BE73685B1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {FA350FE9-9316-4846-8145-356F9A0ACBC7}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -0,0 +1,54 @@
|
|||
// ******************************************************************
|
||||
// Copyright <20> 2015-2018 nventive inc. All rights reserved.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// ******************************************************************
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Xml;
|
||||
using System.Xml.XPath;
|
||||
|
||||
using Mono.Cecil;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Mono.Linker.Steps
|
||||
{
|
||||
|
||||
public class ExplicitBlacklistStep : BaseStep
|
||||
{
|
||||
private readonly IEnumerable<string> _linkerDescriptors;
|
||||
|
||||
public ExplicitBlacklistStep(IEnumerable<string> linkerDescriptors)
|
||||
{
|
||||
_linkerDescriptors = linkerDescriptors ?? Enumerable.Empty<string>();
|
||||
}
|
||||
|
||||
protected override void Process()
|
||||
{
|
||||
if (_linkerDescriptors.Any())
|
||||
{
|
||||
foreach (var def in _linkerDescriptors)
|
||||
{
|
||||
var step = new ResolveFromXmlStep(new XPathDocument(def));
|
||||
|
||||
Context.Pipeline.AddStepAfter(typeof(TypeMapStep), step);
|
||||
|
||||
Context.LogMessage($"Processing explicit linker descriptor: {def}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
// ******************************************************************
|
||||
// Copyright <20> 2015-2018 nventive inc. All rights reserved.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// ******************************************************************
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Mono.Cecil;
|
||||
|
||||
namespace Uno.Wasm.Bootstrap
|
||||
{
|
||||
internal static class Extensions
|
||||
{
|
||||
public static bool Inherits(this TypeReference self, string className)
|
||||
{
|
||||
if (className == null)
|
||||
{
|
||||
throw new ArgumentNullException("className");
|
||||
}
|
||||
|
||||
if (self == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
TypeReference current = self.Resolve();
|
||||
|
||||
while (current != null)
|
||||
{
|
||||
string fullname = current.FullName;
|
||||
|
||||
if (fullname == className)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (fullname == "System.Object")
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (current.Resolve() == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
current = current.Resolve()?.BaseType;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool Is(this TypeReference type, string @namespace, string name)
|
||||
=> type != null && type.Name == name && type.Namespace == @namespace;
|
||||
|
||||
public static bool Inherits(this TypeReference self, string @namespace, string name)
|
||||
{
|
||||
if (@namespace == null)
|
||||
{
|
||||
throw new ArgumentNullException("namespace");
|
||||
}
|
||||
|
||||
if (name == null)
|
||||
{
|
||||
throw new ArgumentNullException("name");
|
||||
}
|
||||
|
||||
if (self == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
TypeDefinition typeDefinition;
|
||||
|
||||
for (TypeReference typeReference = self.Resolve(); typeReference != null; typeReference = typeDefinition.BaseType)
|
||||
{
|
||||
if (typeReference.Is(@namespace, name))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (typeReference.Is("System", "Object"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
typeDefinition = typeReference.Resolve();
|
||||
if (typeDefinition == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
//******************************************************************
|
||||
// This file is part of the Xamarin.Android SDK
|
||||
|
||||
// The MIT License(MIT)
|
||||
|
||||
// Copyright(c) .NET Foundation Contributors
|
||||
|
||||
// All rights reserved.
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
//******************************************************************
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Mono.Linker;
|
||||
using Mono.Cecil;
|
||||
using Mono.Linker.Steps;
|
||||
|
||||
namespace Uno.Wasm.Bootstrap
|
||||
{
|
||||
public class PreserveTypeConverters : ResolveStep
|
||||
{
|
||||
protected override void Process()
|
||||
{
|
||||
var asms = Context.GetAssemblies();
|
||||
foreach (var a in asms)
|
||||
{
|
||||
foreach (var m in a.Modules)
|
||||
{
|
||||
foreach (var t in m.Types.Where(IsTypeConverter))
|
||||
{
|
||||
PreserveTypeConverter(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PreserveTypeConverter(TypeDefinition type)
|
||||
{
|
||||
if (!type.HasMethods)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var ctor in type.Methods.Where(m => m.IsConstructor))
|
||||
{
|
||||
// We only care about ctors with 0 or 1 params.
|
||||
if (ctor.HasParameters && ctor.Parameters.Count > 1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Annotations.AddPreservedMethod(type, ctor);
|
||||
}
|
||||
}
|
||||
|
||||
static bool IsTypeConverter(TypeDefinition type)
|
||||
{
|
||||
return type.Inherits("System.ComponentModel", "TypeConverter");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
// ******************************************************************
|
||||
// Copyright <20> 2015-2018 nventive inc. All rights reserved.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// ******************************************************************
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Mono.Cecil;
|
||||
using Mono.Linker;
|
||||
using Mono.Linker.Steps;
|
||||
|
||||
namespace Uno.Wasm.Bootstrap
|
||||
{
|
||||
internal class PreserveUsingAttributesStep : ResolveStep
|
||||
{
|
||||
readonly HashSet<string> ignoreAsmNames;
|
||||
|
||||
public PreserveUsingAttributesStep(IEnumerable<string> ignoreAsmNames)
|
||||
{
|
||||
this.ignoreAsmNames = new HashSet<string>(ignoreAsmNames.Where(n => n != "mscorlib"));
|
||||
}
|
||||
|
||||
protected override void Process()
|
||||
{
|
||||
var asms = Context.GetAssemblies();
|
||||
foreach (var a in asms.Where(x => !ignoreAsmNames.Contains(x.Name.Name)))
|
||||
{
|
||||
foreach (var m in a.Modules)
|
||||
{
|
||||
foreach (var t in m.Types)
|
||||
{
|
||||
PreserveTypeIfRequested(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PreserveTypeIfRequested(TypeDefinition type)
|
||||
{
|
||||
var typePreserved = IsTypePreserved(type);
|
||||
if (IsTypePreserved(type))
|
||||
{
|
||||
MarkAndPreserveAll(type);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var m in type.Methods.Where(IsMethodPreserved))
|
||||
{
|
||||
Annotations.AddPreservedMethod(type, m);
|
||||
}
|
||||
foreach (var t in type.NestedTypes)
|
||||
{
|
||||
PreserveTypeIfRequested(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool IsTypePreserved(TypeDefinition m)
|
||||
{
|
||||
// Exclude WasmRuntime to that timer can get called properly
|
||||
// https://github.com/mono/mono/blob/a49aa771c10889c6ac1974af81f9fcc375d391cb/mcs/class/corlib/System.Threading/Timer.cs#L56
|
||||
if (m.Name.EndsWith("WasmRuntime"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return m.CustomAttributes.FirstOrDefault(x => x.AttributeType.Name.StartsWith("Preserve", StringComparison.Ordinal)) != null;
|
||||
}
|
||||
|
||||
static bool IsMethodPreserved(MethodDefinition m)
|
||||
{
|
||||
return m.CustomAttributes.FirstOrDefault(x => x.AttributeType.Name.StartsWith("Preserve", StringComparison.Ordinal)) != null;
|
||||
}
|
||||
|
||||
void MarkAndPreserveAll(TypeDefinition type)
|
||||
{
|
||||
Annotations.MarkAndPush(type);
|
||||
Annotations.SetPreserve(type, TypePreserve.All);
|
||||
if (!type.HasNestedTypes)
|
||||
{
|
||||
Tracer.Pop();
|
||||
return;
|
||||
}
|
||||
foreach (TypeDefinition nested in type.NestedTypes)
|
||||
{
|
||||
MarkAndPreserveAll(nested);
|
||||
}
|
||||
|
||||
Tracer.Pop();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,380 @@
|
|||
// ******************************************************************
|
||||
// Copyright <20> 2015-2018 nventive inc. All rights reserved.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// ******************************************************************
|
||||
//
|
||||
// This file is based on the work from https://github.com/praeclarum/Ooui
|
||||
//
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using Microsoft.Build.Utilities;
|
||||
using Mono.Cecil;
|
||||
using Mono.Cecil.Cil;
|
||||
using Mono.Linker;
|
||||
using Mono.Linker.Steps;
|
||||
|
||||
namespace Uno.Wasm.Bootstrap
|
||||
{
|
||||
public partial class ShellTask_v0 : Microsoft.Build.Utilities.Task
|
||||
{
|
||||
private const string SdkUrl = "https://jenkins.mono-project.com/job/test-mono-mainline-webassembly/62/label=highsierra/Azure/processDownloadRequest/62/highsierra/sdks/wasm/mono-wasm-ddf4e7be31b.zip";
|
||||
|
||||
private string _distPath;
|
||||
private string _managedPath;
|
||||
private string _bclPath;
|
||||
private List<string> _linkedAsmPaths;
|
||||
private List<string> _referencedAssemblies;
|
||||
private Dictionary<string, string> _bclAssemblies;
|
||||
private string _sdkPath;
|
||||
private List<string> _additionalScripts = new List<string>();
|
||||
private string[] _additionalStyles;
|
||||
|
||||
[Microsoft.Build.Framework.Required]
|
||||
public string Assembly { get; set; }
|
||||
|
||||
[Microsoft.Build.Framework.Required]
|
||||
public string OutputPath { get; set; }
|
||||
|
||||
public string ReferencePath { get; set; }
|
||||
|
||||
public Microsoft.Build.Framework.ITaskItem[] Assets { get; set; }
|
||||
|
||||
public Microsoft.Build.Framework.ITaskItem[] LinkerDescriptors { get; set; }
|
||||
|
||||
[Microsoft.Build.Framework.Required]
|
||||
public string RuntimeConfiguration { get; set; }
|
||||
|
||||
[Microsoft.Build.Framework.Required]
|
||||
public bool RuntimeDebugLogging { get; set; }
|
||||
|
||||
public override bool Execute()
|
||||
{
|
||||
try
|
||||
{
|
||||
InstallSdk();
|
||||
GetBcl();
|
||||
CreateDist();
|
||||
CopyContent();
|
||||
CopyRuntime();
|
||||
LinkAssemblies();
|
||||
ExtractAdditionalJS();
|
||||
ExtractAdditionalCSS();
|
||||
GenerateHtml();
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.LogErrorFromException(ex, false, true, null);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void InstallSdk()
|
||||
{
|
||||
var sdkName = Path.GetFileNameWithoutExtension(new Uri(SdkUrl).AbsolutePath.Replace('/', Path.DirectorySeparatorChar));
|
||||
Log.LogMessage("SDK: " + sdkName);
|
||||
_sdkPath = Path.Combine(Path.GetTempPath(), sdkName);
|
||||
Log.LogMessage("SDK Path: " + _sdkPath);
|
||||
|
||||
if (Directory.Exists(_sdkPath))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var client = new WebClient();
|
||||
var zipPath = _sdkPath + ".zip";
|
||||
Log.LogMessage($"Downloading {sdkName} to {zipPath}");
|
||||
client.DownloadFile(SdkUrl, zipPath);
|
||||
|
||||
ZipFile.ExtractToDirectory(zipPath, _sdkPath);
|
||||
Log.LogMessage($"Extracted {sdkName} to {_sdkPath}");
|
||||
}
|
||||
|
||||
private void GetBcl()
|
||||
{
|
||||
_bclPath = Path.Combine(_sdkPath, "bcl");
|
||||
var reals = Directory.GetFiles(_bclPath, "*.dll");
|
||||
var facades = Directory.GetFiles(Path.Combine(_bclPath, "Facades"), "*.dll");
|
||||
var allFiles = reals.Concat(facades);
|
||||
_bclAssemblies = allFiles.ToDictionary(x => Path.GetFileName(x));
|
||||
}
|
||||
|
||||
private void CreateDist()
|
||||
{
|
||||
var outputPath = Path.GetFullPath(OutputPath);
|
||||
_distPath = Path.Combine(outputPath, "dist");
|
||||
_managedPath = Path.Combine(_distPath, "managed");
|
||||
Directory.CreateDirectory(_managedPath);
|
||||
}
|
||||
|
||||
private void CopyRuntime()
|
||||
{
|
||||
var runtimePath = Path.Combine(_sdkPath, RuntimeConfiguration.ToLower());
|
||||
|
||||
foreach (var sourceFile in Directory.EnumerateFiles(runtimePath))
|
||||
{
|
||||
var dest = Path.Combine(_distPath, Path.GetFileName(sourceFile));
|
||||
Log.LogMessage($"Runtime {sourceFile} -> {dest}");
|
||||
File.Copy(sourceFile, dest, true);
|
||||
}
|
||||
|
||||
File.Copy(Path.Combine(_sdkPath, "server.py"), Path.Combine(_distPath, "server.py"), true);
|
||||
}
|
||||
|
||||
private void CopyContent()
|
||||
{
|
||||
if (Assets != null)
|
||||
{
|
||||
var runtimePath = Path.Combine(_sdkPath, RuntimeConfiguration.ToLower());
|
||||
|
||||
foreach (var sourceFile in Assets)
|
||||
{
|
||||
var baseSourceFile = sourceFile.GetMetadata("DefiningProjectDirectory");
|
||||
|
||||
Directory.CreateDirectory(Path.Combine(_distPath, Path.GetDirectoryName(sourceFile.ToString())));
|
||||
|
||||
var dest = Path.Combine(_distPath, sourceFile.ItemSpec);
|
||||
var fullSourcePath = Path.Combine(baseSourceFile, sourceFile.ItemSpec);
|
||||
Log.LogMessage($"ContentFile {fullSourcePath} -> {dest}");
|
||||
File.Copy(fullSourcePath, dest, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Logger : ILogger
|
||||
{
|
||||
private TaskLoggingHelper log;
|
||||
|
||||
public Logger(TaskLoggingHelper log) => this.log = log;
|
||||
|
||||
public void LogMessage(MessageImportance importance, string message, params object[] values)
|
||||
{
|
||||
switch (importance)
|
||||
{
|
||||
case MessageImportance.High:
|
||||
log.LogMessage(Microsoft.Build.Framework.MessageImportance.High, message, values);
|
||||
break;
|
||||
case MessageImportance.Normal:
|
||||
log.LogMessage(Microsoft.Build.Framework.MessageImportance.Normal, message, values);
|
||||
break;
|
||||
case MessageImportance.Low:
|
||||
log.LogMessage(Microsoft.Build.Framework.MessageImportance.Low, message, values);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LinkAssemblies()
|
||||
{
|
||||
var references = ReferencePath.Split(';').Select(x => x.Trim()).Where(x => x.Length > 0).ToList();
|
||||
_referencedAssemblies = new List<string>();
|
||||
foreach (var r in references)
|
||||
{
|
||||
var name = Path.GetFileName(r);
|
||||
if (_bclAssemblies.ContainsKey(name))
|
||||
{
|
||||
_referencedAssemblies.Add(_bclAssemblies[name]);
|
||||
}
|
||||
else
|
||||
{
|
||||
_referencedAssemblies.Add(r);
|
||||
}
|
||||
}
|
||||
|
||||
var asmPath = Path.GetFullPath(Assembly);
|
||||
|
||||
var pipeline = GetLinkerPipeline();
|
||||
using (var context = new LinkContext(pipeline))
|
||||
{
|
||||
context.CoreAction = AssemblyAction.Link;
|
||||
context.UserAction = AssemblyAction.Link;
|
||||
|
||||
// Disabled until we can actually use symbols, and that
|
||||
// the rewriter does not fail for a memory allocation error.
|
||||
// context.SymbolReaderProvider = new DefaultSymbolReaderProvider(true);
|
||||
// context.SymbolWriterProvider = new DefaultSymbolWriterProvider();
|
||||
// context.LinkSymbols = true;
|
||||
context.Logger = new Logger(Log);
|
||||
context.LogMessages = true;
|
||||
context.KeepTypeForwarderOnlyAssemblies = true;
|
||||
context.OutputDirectory = _managedPath;
|
||||
|
||||
pipeline.PrependStep(new ResolveFromAssemblyStep(asmPath, ResolveFromAssemblyStep.RootVisibility.Any));
|
||||
|
||||
var refdirs = _referencedAssemblies.Select(x => Path.GetDirectoryName(x)).Distinct().ToList();
|
||||
refdirs.Insert(0, Path.Combine(_bclPath, "Facades"));
|
||||
refdirs.Insert(0, _bclPath);
|
||||
foreach (var d in refdirs.Distinct())
|
||||
{
|
||||
context.Resolver.AddSearchDirectory(d);
|
||||
}
|
||||
|
||||
pipeline.AddStepAfter(typeof(LoadReferencesStep), new LoadI18nAssemblies(I18nAssemblies.None));
|
||||
|
||||
foreach (var dll in Directory.GetFiles(_managedPath, "*.dll"))
|
||||
{
|
||||
File.Delete(dll);
|
||||
}
|
||||
|
||||
pipeline.Process(context);
|
||||
}
|
||||
|
||||
_linkedAsmPaths = Directory.GetFiles(_managedPath, "*.dll")
|
||||
.Concat(Directory.GetFiles(_managedPath, "*.exe"))
|
||||
.OrderBy(x => Path.GetFileName(x))
|
||||
.ToList();
|
||||
}
|
||||
|
||||
Pipeline GetLinkerPipeline()
|
||||
{
|
||||
var p = new Pipeline();
|
||||
p.AppendStep(new LoadReferencesStep());
|
||||
p.AppendStep(new PreserveUsingAttributesStep(_bclAssemblies.Values.Select(Path.GetFileNameWithoutExtension)));
|
||||
p.AppendStep(new PreserveTypeConverters());
|
||||
p.AppendStep(new BlacklistStep());
|
||||
p.AppendStep(new ExplicitBlacklistStep(LinkerDescriptors?.Select(l => l.ItemSpec)));
|
||||
p.AppendStep(new TypeMapStep());
|
||||
p.AppendStep(new MarkStep());
|
||||
p.AppendStep(new SweepStep());
|
||||
p.AppendStep(new CleanStep());
|
||||
p.AppendStep(new RegenerateGuidStep());
|
||||
p.AppendStep(new OutputStep());
|
||||
return p;
|
||||
}
|
||||
|
||||
private void ExtractAdditionalJS()
|
||||
{
|
||||
var q = EnumerateResources("js", "WasmDist")
|
||||
.Concat(EnumerateResources("js", "WasmScripts"));
|
||||
|
||||
q.AsParallel().ForAll(res =>
|
||||
{
|
||||
if (res.name != "uno-bootstrap.js")
|
||||
{
|
||||
_additionalScripts.Add(res.name);
|
||||
}
|
||||
|
||||
CopyResourceToOutput(res.name, res.resource);
|
||||
|
||||
Log.LogMessage($"Additional JS {res.name}");
|
||||
});
|
||||
}
|
||||
|
||||
private void ExtractAdditionalCSS()
|
||||
{
|
||||
var q = EnumerateResources("css", "WasmCSS");
|
||||
|
||||
_additionalStyles = q.AsParallel().Select(res => {
|
||||
using (var srcs = res.resource.GetResourceStream())
|
||||
{
|
||||
CopyResourceToOutput(res.name, res.resource);
|
||||
|
||||
Log.LogMessage($"Additional CSS {res.name}");
|
||||
}
|
||||
|
||||
return res.name;
|
||||
})
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
private void CopyResourceToOutput(string name, EmbeddedResource resource)
|
||||
{
|
||||
var dest = Path.Combine(_distPath, name);
|
||||
|
||||
using (var srcs = resource.GetResourceStream())
|
||||
{
|
||||
using (var dests = new FileStream(dest, FileMode.Create, FileAccess.Write))
|
||||
{
|
||||
srcs.CopyTo(dests);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<(string name, EmbeddedResource resource)> EnumerateResources(string extension, string folder)
|
||||
{
|
||||
var fullExtension = "." + extension;
|
||||
var fullFolder = "." + folder + ".";
|
||||
|
||||
return from asmPath in _referencedAssemblies.Concat(new[] { Assembly, this.GetType().Assembly.Location })
|
||||
let asm = AssemblyDefinition.ReadAssembly(asmPath)
|
||||
from res in asm.MainModule.Resources.OfType<EmbeddedResource>()
|
||||
where res.Name.EndsWith(fullExtension)
|
||||
where res.Name.Contains(fullFolder)
|
||||
select (
|
||||
name: res.Name.Substring(res.Name.IndexOf(fullFolder) + fullFolder.Length),
|
||||
resource: res
|
||||
);
|
||||
}
|
||||
|
||||
private MethodDefinition DiscoverEntryPoint()
|
||||
{
|
||||
var asm = AssemblyDefinition.ReadAssembly(Assembly);
|
||||
|
||||
if (asm?.EntryPoint is MethodDefinition def)
|
||||
{
|
||||
return def;
|
||||
}
|
||||
|
||||
throw new Exception($"{Path.GetFileName(Assembly)} is missing an entry point");
|
||||
}
|
||||
|
||||
private void GenerateHtml()
|
||||
{
|
||||
var htmlPath = Path.Combine(_distPath, "index.html");
|
||||
|
||||
var entryPoint = DiscoverEntryPoint();
|
||||
|
||||
using (var w = new StreamWriter(htmlPath, false, new UTF8Encoding(false)))
|
||||
{
|
||||
string indexHtmlResName = $"{GetType().Assembly.GetName().Name}.Templates.Index.html";
|
||||
var stream = this.GetType().Assembly.GetManifestResourceStream(indexHtmlResName);
|
||||
|
||||
if (stream == null)
|
||||
{
|
||||
throw new InvalidOperationException($"Unable to find {indexHtmlResName}");
|
||||
}
|
||||
|
||||
using (var sr = new StreamReader(stream))
|
||||
{
|
||||
var html = sr.ReadToEnd();
|
||||
var assemblies = string.Join(", ", _linkedAsmPaths.Select(x => $"\"{Path.GetFileName(x)}\""));
|
||||
|
||||
html = html.Replace("$(ASSEMBLIES_LIST)", assemblies);
|
||||
html = html.Replace("$(MAIN_ASSEMBLY_NAME)", entryPoint.DeclaringType.Module.Assembly.Name.Name);
|
||||
html = html.Replace("$(MAIN_NAMESPACE)", entryPoint.DeclaringType.Namespace);
|
||||
html = html.Replace("$(MAIN_TYPENAME)", entryPoint.DeclaringType.Name);
|
||||
html = html.Replace("$(MAIN_METHOD)", entryPoint.Name);
|
||||
html = html.Replace("$(ENABLE_RUNTIMEDEBUG)", RuntimeDebugLogging.ToString().ToLower());
|
||||
|
||||
var scripts = string.Join("\r\n", _additionalScripts.Select(s => $"<script defer type=\"text/javascript\" src=\"{s}\"></script>"));
|
||||
html = html.Replace("$(ADDITIONAL_SCRIPTS)", scripts);
|
||||
|
||||
var styles = string.Join("\r\n", _additionalStyles.Select(s => $"<link rel=\"stylesheet\" type=\"text/css\" href=\"{s}\" />"));
|
||||
html = html.Replace("$(ADDITIONAL_CSS)", styles);
|
||||
|
||||
w.Write(html);
|
||||
}
|
||||
|
||||
|
||||
Log.LogMessage($"HTML {htmlPath}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/css/bootstrap.min.css" />
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" />
|
||||
$(ADDITIONAL_CSS)
|
||||
</head>
|
||||
<body>
|
||||
<div id="uno-body" class="container-fluid">
|
||||
<p id="loading"><i class="fa fa-refresh fa-spin" style="font-size:14px;margin-right:0.5em;"></i> Loading...</p>
|
||||
</div>
|
||||
<script defer type="text/javascript" src="uno-bootstrap.js"></script>
|
||||
<script type="text/javascript">
|
||||
var assemblies = [$(ASSEMBLIES_LIST)];
|
||||
document.addEventListener(
|
||||
"DOMContentLoaded",
|
||||
function (event) {
|
||||
unoWasmMain("$(MAIN_ASSEMBLY_NAME)", "$(MAIN_NAMESPACE)", "$(MAIN_TYPENAME)", "$(MAIN_METHOD)", assemblies, $(ENABLE_RUNTIMEDEBUG));
|
||||
}
|
||||
);
|
||||
</script>
|
||||
<script defer type="text/javascript" src="mono.js"></script>
|
||||
$(ADDITIONAL_SCRIPTS)
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,69 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<DefineConstants>NET_CORE</DefineConstants>
|
||||
<NoWarn>1701;1702;1705;649</NoWarn>
|
||||
<AssemblyName>Uno.Wasm.Bootstrap.v0</AssemblyName>
|
||||
<RootNamespace>Uno.Wasm.Bootstrap.v0</RootNamespace>
|
||||
<PackageId>Uno.Wasm.Bootstrap</PackageId>
|
||||
<IsTool>true</IsTool>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<Authors>nventive</Authors>
|
||||
<PackageProjectUrl>https://github.com/nventive/Uno.Wasm.Bootstrap</PackageProjectUrl>
|
||||
<PackageIconUrl>https://nv-assets.azurewebsites.net/logos/uno.png</PackageIconUrl>
|
||||
<RepositoryUrl>https://github.com/nventive/Uno.Core</RepositoryUrl>
|
||||
<Description>This package provides a Wasm bootstap for netstandard 2.0 projects.</Description>
|
||||
<Copyright>Copyright (C) 2015-2018 nventive inc. - all rights reserved</Copyright>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Build" Version="15.3.409" />
|
||||
<PackageReference Include="Microsoft.Build.Framework" Version="15.3.409" />
|
||||
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="15.3.409" />
|
||||
<PackageReference Include="Microsoft.Build.Tasks.Core" Version="15.3.409" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="linker\**" />
|
||||
<Compile Remove="linker\**" />
|
||||
<Compile Include="linker\linker\Linker\**\*.cs" />
|
||||
<Compile Include="linker\linker\Linker.Steps\**\*.cs" />
|
||||
<Compile Include="linker\cecil\Mono.Cecil\**\*.cs" />
|
||||
<Compile Include="linker\cecil\Mono.Cecil.Cil\**\*.cs" />
|
||||
<Compile Include="linker\cecil\Mono.Cecil.Metadata\**\*.cs" />
|
||||
<Compile Include="linker\cecil\Mono.Cecil.PE\**\*.cs" />
|
||||
<Compile Include="linker\cecil\Mono.Collections.Generic\**\*.cs*" />
|
||||
<Compile Include="linker\cecil\symbols\mdb\Mono.Cecil.Mdb\**\*.cs*" />
|
||||
<Compile Include="linker\cecil\symbols\mdb\Mono.CompilerServices.SymbolWriter\**\*.cs*" />
|
||||
<Compile Include="linker\cecil\symbols\pdb\Microsoft.Cci.Pdb\**\*.cs*" />
|
||||
<Compile Include="linker\cecil\symbols\pdb\Mono.Cecil.Pdb\**\*.cs*" />
|
||||
<Compile Include="linker\cecil\Mono\**\*.cs" />
|
||||
|
||||
<Compile Remove="linker\cecil\symbols\mdb\Mono.Cecil.Mdb\AssemblyInfo.cs" />
|
||||
<Compile Remove="linker\cecil\symbols\pdb\Mono.Cecil.Pdb\AssemblyInfo.cs" />
|
||||
<Compile Remove="linker\linker\Linker\Driver.cs" />
|
||||
<Compile Remove="linker\linker\Linker\AssemblyInfo.cs" />
|
||||
<Compile Remove="linker\cecil\Mono.Cecil\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="Templates\Index.html" />
|
||||
<None Remove="WasmScripts\uno-bootstrap.js" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="build\Uno.Wasm.Bootstrap.targets">
|
||||
<Pack>true</Pack>
|
||||
<PackagePath>build</PackagePath>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="WasmScripts\uno-bootstrap.js" />
|
||||
<EmbeddedResource Include="Templates\Index.html" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,122 @@
|
|||
var debug = false;
|
||||
|
||||
|
||||
function unoWasmMain(mainAsmName, mainNamespace, mainClassName, mainMethodName, assemblies, isDebug) {
|
||||
Module.entryPoint = { "a": mainAsmName, "n": mainNamespace, "t": mainClassName, "m": mainMethodName };
|
||||
Module.assemblies = assemblies;
|
||||
debug = isDebug;
|
||||
}
|
||||
|
||||
var Module = {
|
||||
onRuntimeInitialized: function () {
|
||||
if (debug) console.log("Done with WASM module instantiation.");
|
||||
|
||||
Module.FS_createPath("/", "managed", true, true);
|
||||
|
||||
var pending = 0;
|
||||
this.assemblies.forEach(function (asm_name) {
|
||||
if (debug) console.log("Loading", asm_name);
|
||||
++pending;
|
||||
fetch("managed/" + asm_name, { credentials: 'same-origin' }).then(function (response) {
|
||||
if (!response.ok)
|
||||
throw "failed to load Assembly '" + asm_name + "'";
|
||||
return response['arrayBuffer']();
|
||||
}).then(function (blob) {
|
||||
var asm = new Uint8Array(blob);
|
||||
Module.FS_createDataFile("managed/" + asm_name, null, asm, true, true, true);
|
||||
--pending;
|
||||
if (pending == 0)
|
||||
Module.bclLoadingDone();
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
bclLoadingDone: function () {
|
||||
if (debug) console.log("Done loading the BCL.");
|
||||
MonoRuntime.init();
|
||||
}
|
||||
};
|
||||
|
||||
var MonoRuntime = {
|
||||
init: function () {
|
||||
this.load_runtime = Module.cwrap('mono_wasm_load_runtime', null, ['string', 'number']);
|
||||
this.assembly_load = Module.cwrap('mono_wasm_assembly_load', 'number', ['string']);
|
||||
this.find_class = Module.cwrap('mono_wasm_assembly_find_class', 'number', ['number', 'string', 'string']);
|
||||
this.find_method = Module.cwrap('mono_wasm_assembly_find_method', 'number', ['number', 'string', 'number']);
|
||||
this.invoke_method = Module.cwrap('mono_wasm_invoke_method', 'number', ['number', 'number', 'number']);
|
||||
this.mono_string_get_utf8 = Module.cwrap('mono_wasm_string_get_utf8', 'number', ['number']);
|
||||
this.mono_string = Module.cwrap('mono_wasm_string_from_js', 'number', ['string']);
|
||||
|
||||
this.load_runtime("managed", 1);
|
||||
|
||||
if (debug) console.log("Done initializing the runtime.");
|
||||
|
||||
WebAssemblyApp.init();
|
||||
},
|
||||
|
||||
conv_string: function (mono_obj) {
|
||||
if (mono_obj == 0)
|
||||
return null;
|
||||
var raw = this.mono_string_get_utf8(mono_obj);
|
||||
var res = Module.UTF8ToString(raw);
|
||||
Module._free(raw);
|
||||
|
||||
return res;
|
||||
},
|
||||
|
||||
call_method: function (method, this_arg, args) {
|
||||
var args_mem = Module._malloc(args.length * 4);
|
||||
var eh_throw = Module._malloc(4);
|
||||
for (var i = 0; i < args.length; ++i)
|
||||
Module.setValue(args_mem + i * 4, args[i], "i32");
|
||||
Module.setValue(eh_throw, 0, "i32");
|
||||
|
||||
var res = this.invoke_method(method, this_arg, args_mem, eh_throw);
|
||||
|
||||
var eh_res = Module.getValue(eh_throw, "i32");
|
||||
|
||||
Module._free(args_mem);
|
||||
Module._free(eh_throw);
|
||||
|
||||
if (eh_res != 0) {
|
||||
var msg = this.conv_string(res);
|
||||
throw new Error(msg);
|
||||
}
|
||||
|
||||
return res;
|
||||
},
|
||||
};
|
||||
|
||||
var WebAssemblyApp = {
|
||||
init: function () {
|
||||
this.loading = document.getElementById("loading");
|
||||
|
||||
this.findMethods();
|
||||
|
||||
this.runApp();
|
||||
|
||||
this.loading.hidden = true;
|
||||
},
|
||||
|
||||
runApp: function () {
|
||||
try {
|
||||
MonoRuntime.call_method(this.main_method, null, []);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
},
|
||||
|
||||
findMethods: function () {
|
||||
this.main_module = MonoRuntime.assembly_load(Module.entryPoint.a);
|
||||
if (!this.main_module)
|
||||
throw "Could not find Main Module " + Module.entryPoint.a + ".dll";
|
||||
|
||||
this.main_class = MonoRuntime.find_class(this.main_module, Module.entryPoint.n, Module.entryPoint.t)
|
||||
if (!this.main_class)
|
||||
throw "Could not find Program class in main module";
|
||||
|
||||
this.main_method = MonoRuntime.find_method(this.main_class, Module.entryPoint.m, -1)
|
||||
if (!this.main_method)
|
||||
throw "Could not find Main method";
|
||||
},
|
||||
};
|
|
@ -0,0 +1,26 @@
|
|||
<Project>
|
||||
|
||||
<PropertyGroup>
|
||||
<_packageBinaryPath>$(MSBuildThisFileDirectory)../tools/Uno.Wasm.Bootstrap.v0.dll</_packageBinaryPath>
|
||||
|
||||
<WasmShellTasksPath Condition="!Exists('$(_packageBinaryPath)')">$(MSBuildThisFileDirectory)../bin/$(Configuration)/netstandard2.0</WasmShellTasksPath>
|
||||
<WasmShellTasksPath Condition="Exists('$(_packageBinaryPath)')">../tools</WasmShellTasksPath>
|
||||
|
||||
<MonoWasmRuntimeConfiguration Condition="'$(WasmRuntimeConfiguration)'==''">release</MonoWasmRuntimeConfiguration>
|
||||
<MonoRuntimeDebugLogging Condition="'$(WasmRuntimeDebug)'==''">false</MonoRuntimeDebugLogging>
|
||||
</PropertyGroup>
|
||||
|
||||
<UsingTask AssemblyFile="$(WasmShellTasksPath)/Uno.Wasm.Bootstrap.v0.dll" TaskName="Uno.Wasm.Bootstrap.ShellTask_v0" />
|
||||
|
||||
<Target Name="BuildDist" AfterTargets="AfterBuild">
|
||||
<ShellTask_v0
|
||||
Assembly="$(IntermediateOutputPath)$(TargetFileName)"
|
||||
OutputPath="$(OutputPath)"
|
||||
LinkerDescriptors="@(LinkerDescriptor)"
|
||||
RuntimeConfiguration="$(MonoWasmRuntimeConfiguration)"
|
||||
RuntimeDebugLogging="$(MonoRuntimeDebugLogging)"
|
||||
Assets="@(Content)"
|
||||
ReferencePath="@(ReferencePath)" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 08277b61d8c00aa3f5ab069d45fa17e4a318809b
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 1.4 KiB |
|
@ -0,0 +1,5 @@
|
|||
<linker>
|
||||
<assembly fullname="Uno.Wasm.Sample">
|
||||
<namespace fullname="Uno.Wasm.Sample" />
|
||||
</assembly>
|
||||
</linker>
|
|
@ -0,0 +1,45 @@
|
|||
// ******************************************************************
|
||||
// Copyright <20> 2015-2018 nventive inc. All rights reserved.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// ******************************************************************
|
||||
using System;
|
||||
using System.Collections.Immutable;
|
||||
|
||||
namespace Uno.Wasm.Sample
|
||||
{
|
||||
public static class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
Console.WriteLine("Main!");
|
||||
|
||||
try
|
||||
{
|
||||
NewMethod();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void NewMethod()
|
||||
{
|
||||
ImmutableDictionary<string, string> s = ImmutableDictionary<string, string>.Empty;
|
||||
Console.WriteLine($"test new method {s.Count}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<OutputType>Exe</OutputType>
|
||||
<IsPackable>false</IsPackable>
|
||||
<StartupObject>Uno.Wasm.Sample.Program</StartupObject>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.Collections.Immutable" Version="1.4.0" />
|
||||
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="..\Uno.Wasm.Bootstrap\build\Uno.Wasm.Bootstrap.targets" />
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="WasmScripts\**\*.js" />
|
||||
<None Include="WasmCSS\**\*.css" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="WasmScripts\**\*.js" />
|
||||
<EmbeddedResource Include="WasmCSS\**\*.css" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<LinkerDescriptor Include="LinkerDescriptors.xml" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="Content\**" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,53 @@
|
|||
/* http://meyerweb.com/eric/tools/css/reset/
|
||||
v2.0 | 20110126
|
||||
License: none (public domain)
|
||||
*/
|
||||
|
||||
html, body, div, span, applet, object, iframe,
|
||||
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
||||
a, abbr, acronym, address, big, cite, code,
|
||||
del, dfn, em, img, ins, kbd, q, s, samp,
|
||||
small, strike, strong, sub, sup, tt, var,
|
||||
b, u, i, center,
|
||||
dl, dt, dd, ol, ul, li,
|
||||
fieldset, form, label, legend,
|
||||
table, caption, tbody, tfoot, thead, tr, th, td,
|
||||
article, aside, canvas, details, embed,
|
||||
figure, figcaption, footer, header, hgroup,
|
||||
menu, nav, output, ruby, section, summary,
|
||||
time, mark, audio, video {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
font-size: 100%;
|
||||
font: inherit;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
/* HTML5 display-role reset for older browsers */
|
||||
article, aside, details, figcaption, figure,
|
||||
footer, header, hgroup, menu, nav, section {
|
||||
display: block;
|
||||
}
|
||||
|
||||
body {
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
ol, ul {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
blockquote, q {
|
||||
quotes: none;
|
||||
}
|
||||
|
||||
blockquote:before, blockquote:after,
|
||||
q:before, q:after {
|
||||
content: '';
|
||||
content: none;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
window.onload = function () {
|
||||
var txt = document.createTextNode("Loaded !");
|
||||
var parent = document.getElementById('uno-body');
|
||||
parent.insertBefore(txt, parent.lastChild);
|
||||
}
|
Загрузка…
Ссылка в новой задаче