├── .gitignore ├── Class.html ├── Delay.html ├── Element.html ├── Entrance.html ├── LICENSE.md ├── Layout.html ├── LoadPackages.js ├── MVC.html ├── Navigation.html ├── README.md ├── Razor.html ├── Resource.html ├── Script ├── Class.js ├── GacUI │ ├── Elements │ │ ├── Basic.js │ │ ├── ColorizedText.js │ │ ├── Document.js │ │ └── Interface.js │ ├── Layout │ │ ├── Basic.js │ │ ├── Misc.js │ │ ├── Stack.js │ │ └── Table.js │ └── Types.js ├── Html │ ├── Events.js │ ├── MVC.js │ ├── Navigation.js │ ├── Razor.js │ ├── ResizeEvent.js │ └── RunAfterWindowLoaded.js ├── IO │ ├── Delay.js │ ├── Resource.js │ └── Wildcard.js ├── Package.js └── Test.js ├── Test ├── MVC │ ├── Home.razor.html │ ├── Loading.razor.html │ ├── Post_1.razor.html │ ├── Post_2.razor.html │ ├── Post_3.razor.html │ ├── Posts.razor.html │ └── Root.razor.html ├── a.json ├── a.txt └── a.xml ├── TestPage.css ├── TestPage.js ├── Wildcard.html └── web.config /.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vczh-libraries/GacJS/320d0f960c9ed538d56f22d38862863c7380c205/.gitignore -------------------------------------------------------------------------------- /Delay.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Delay 5 | 6 | 7 | 8 | 9 | 10 | 17 | 30 | 45 | 60 | 75 | 90 | 100 | 110 | 124 | 138 | 161 | 189 | 209 | 212 | 213 | 214 | -------------------------------------------------------------------------------- /Element.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Element 6 | 7 | 8 | 9 | 10 | 34 | 35 | 38 | 39 |
40 |
41 |
Borders
42 |
Backgrounds
43 |
3D
44 |
Gradient
45 |
Label
46 |
Others
47 |
48 | 49 |
50 |
51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 |
DescriptionResult
SolidBorder (Rectangle)
SolidBorder (Ellipse)
RoundBorder
69 |
70 | 98 | 99 |
100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 |
DescriptionResult
SolidBackground (Rectangle)
SolidBackground (Ellipse)
114 |
115 | 129 | 130 |
131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 |
DescriptionResult
3DBorder
3DSplitter (Horizontal)
3DSplitter (Vertical)
149 |
150 | 175 | 176 |
177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 |
DescriptionResult
GradientBackground (Horizontal)
GradientBackground (Vertical)
GradientBackground (Slash)
GradientBackground (Backslash)
199 |
200 | 221 | 222 |
223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 250 | 251 |
DescriptionResult
SolidLabel (Alignments) 231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 |
Ellipse: falseEllipse: trueHeight && !Ellipse
Multiline: falseWrapLine: false
WrapLine: true
Multiline: trueWrapLine: false
WrapLine: true
286 |
287 | 355 | 356 |
357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 |
DescriptionResult
ImageFrame
Polygon
ColorizedText
Document
379 |
380 | 382 | 383 |
384 |
385 | 386 | 391 | 392 | 393 | -------------------------------------------------------------------------------- /Entrance.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | git@github.com:vczh-libraries/GacJS 5 | 6 | 7 |

Class.js Test Cases

8 |

Html/Navigation.js Test Cases

9 |

Html/Razor.js Test Cases

10 |

Html/MVC.js Test Cases

11 |

IO/Delay.js Test Cases

12 |

IO/Wildcard.js Test Cases

13 |

IO/Resource.js Test Cases

14 |

Element Test Cases

15 |

Layout Test Cases

16 | 17 | 18 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | See https://github.com/vczh-libraries/License/blob/master/README.md for the detail. 2 | -------------------------------------------------------------------------------- /Layout.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Layout 6 | 7 | 8 | 9 | 10 | 71 | 72 | 75 | 76 |
77 |
78 |
Bounds
79 |
Table
80 |
Stack
81 |
SideAligned
82 |
PartialView
83 |
84 | 85 |
86 |
87 | Bounds 88 |
89 | 91 | 92 |
93 | Table 94 |
95 | 97 | 98 |
99 | Stack 100 |
101 | 103 | 104 |
105 | SideAligned 106 |
107 | 109 | 110 |
111 | PartialView 112 |
113 | 115 |
116 | 117 |
118 | 119 | 124 | 125 | 126 | -------------------------------------------------------------------------------- /LoadPackages.js: -------------------------------------------------------------------------------- 1 | var AllJavaScriptPackages = [ 2 | "./Script/Package.js", 3 | "./Script/Test.js", 4 | "./Script/Html/Events.js", 5 | "./Script/Html/RunAfterWindowLoaded.js", 6 | "./Script/Html/ResizeEvent.js", 7 | "./Script/Html/Navigation.js", 8 | "./Script/Html/Razor.js", 9 | "./Script/Html/MVC.js", 10 | "./Script/IO/Delay.js", 11 | "./Script/IO/Wildcard.js", 12 | "./Script/IO/Resource.js", 13 | "./Script/GacUI/Layout/Basic.js", 14 | "./Script/GacUI/Layout/Stack.js", 15 | "./Script/GacUI/Layout/Table.js", 16 | "./Script/GacUI/Layout/Misc.js", 17 | "./Script/GacUI/Elements/Interface.js", 18 | "./Script/GacUI/Elements/Basic.js", 19 | "./Script/GacUI/Elements/ColorizedText.js", 20 | "./Script/GacUI/Elements/Document.js", 21 | "./Script/GacUI/Types.js", 22 | "./Script/Class.js", 23 | ]; 24 | 25 | for (var i = 0; i < AllJavaScriptPackages.length; i++) { 26 | var currentJavaScriptPackage = JSON.stringify(AllJavaScriptPackages[i]); 27 | document.write(""); 28 | } -------------------------------------------------------------------------------- /MVC.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | MVC 5 | 6 | 7 | 8 | 9 | 10 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Navigation.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Navigation 6 | 7 | 8 | 9 | 10 | 19 | 20 | 30 | 31 | 41 | 42 | 62 | 63 | 101 | 102 | 145 | 146 | 176 | 177 | 186 | 187 | 209 | 210 | 244 | 245 | 248 | 249 |
250 |
251 |
Home
252 |
Tutorial
253 |
Download
254 |
Demos
255 |
Document
256 |
About
257 |
258 | 259 |
260 |
261 |
262 |
263 |
Vlpp
264 |
Workflow
265 |
GacUI
266 |
GacJS
267 |
268 | 269 |
270 |
271 | Welcome to Vlpp! 272 |
273 | 274 |
275 | Welcome to Workflow! 276 |
277 | 278 |
279 | Welcome to GacUI! 280 |
281 | 282 |
283 | Welcome to GacJS! 284 |
285 |
286 |
287 |
288 | 289 |
290 | Tutorial 291 |
292 | 293 |
294 |
295 |
296 |
Windows
297 |
Linux
298 |
Mac
299 |
Html
300 |
301 | 302 |
303 |
304 | Download GacUI for Windows 305 |
306 | 307 |
308 | Download GacUI for Linux 309 |
310 | 311 |
312 | Download GacUI for Mac OS 313 |
314 | 315 |
316 | Download GacUI for Browsers! 317 |
318 |
319 |
320 |
321 | 322 |
323 | Demos 324 |
325 | 326 |
327 | Document 328 |
329 | 330 |
331 | About 332 |
333 |
334 |
335 | 336 | 343 | 344 | 345 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GacJS 2 | 3 | **Read the [LICENSE](https://github.com/vczh-libraries/GacJS/blob/master/LICENSE.md) first.** 4 | 5 | Running GacUI in Browsers! 6 | 7 | ## Source code is abondoned. This repo will be used to port GacUI to WebAssembly. All content will be deleted later. 8 | 9 | ## Notice 10 | 11 | Some content is under development. I will keep all code compatible across browsers by only testing the code using the **latest version of IE, Firefox and Chrome**. After Windows 10 releases, Edge will be included. 12 | 13 | In the future, GacGen.exe can translate GacUI XML resource files to javascript codes, mapping all classes to javascript. You can just create an instance of your control class and plug it in the DOM tree at wherever you want, and the UI will appear in the web page. 14 | 15 | This project's priority is not very high. The first step is to re-implement GacUI's layout system using javascript, and then use it to develop the GacUI document generator with C++ and XML comments. 16 | 17 | ## Running test pages 18 | 19 | Running test pages is very simple, just follow the steps: 20 | * Clone this repo to your disk. 21 | * Create a web site on the cloned folder using IIS. 22 | * Launch http://127.0.0.1:< port >/Entrance.html according to your configuration. 23 | 24 | ## Content 25 | 26 | * **[Package.js](https://github.com/vczh-libraries/GacJS/blob/master/Script/Package.js)** : A package infrastructure. All JavaScript components in this project will be build as packages. You don't need to worry about the order -- except that **Package.js** should be the first one -- when including coupled JavaScript files in your HTML document. 27 | * **[Test.js](https://github.com/vczh-libraries/GacJS/blob/master/Script/Test.js)** : A very simple unit test framework, that only me will use it. 28 | * **[Class.js](https://github.com/vczh-libraries/GacJS/blob/master/Script/Class.js)** : An object oriented type definition library for translating Workflow script to Javascript, including 29 | * Inheritance and virtual inheritance. 30 | * Virtual, Override and New functions. 31 | * Private, Protected and Public functions. Which means that, inside the class all code can see private and protected members, but outside the class only public members are visible. 32 | * Properties and Events. 33 | * POD 34 | * Enum 35 | * Unit test for Class.js in **[Class.html](https://github.com/vczh-libraries/GacJS/blob/master/Class.html)**. 36 | * **[Html/](https://github.com/vczh-libraries/GacJS/tree/master/Script/Html)** : HTML related packages. 37 | * **[Events.js](https://github.com/vczh-libraries/GacJS/blob/master/Script/Html/Events.js)** : A general custom event framework. 38 | * **[RunAfterWindowLoaded.js](https://github.com/vczh-libraries/GacJS/blob/master/Script/Html/RunAfterWindowLoaded.js)** : Execute a function. If window is not loaded then delay the execution. 39 | * **[ResizeEvent.js](https://github.com/vczh-libraries/GacJS/blob/master/Script/Html/ResizeEvent.js)** : ConnectionToBodyChanged and Resize custom event that works on every elements. 40 | * **[Navigation.js](https://github.com/vczh-libraries/GacJS/blob/master/Script/Html/Navigation.js)** : A pure front-end navigation system driven by hash in the url. Test page: **[Navigation.html](https://github.com/vczh-libraries/GacJS/blob/master/Navigation.html)**. 41 | * **[Razor.js](https://github.com/vczh-libraries/GacJS/blob/master/Script/Html/Razor.js)** : Razor template engine driven by JavaScript. Test page: **[Razor.html](https://github.com/vczh-libraries/GacJS/blob/master/Razor.html)**. 42 | * **[IO/](https://github.com/vczh-libraries/GacJS/tree/master/Script/IO)** : IO related packages. 43 | * **[Delay.js](https://github.com/vczh-libraries/GacJS/blob/master/Script/IO/Delay.js)** : A delay execution framework. Test page: **[Navigation.html](https://github.com/vczh-libraries/GacJS/blob/master/Delay.html)**. 44 | * **[Wildcard.js](https://github.com/vczh-libraries/GacJS/blob/master/Script/IO/Wildcard.js)** : Convert wildcards to regular expressions. Test page: **[Navigation.html](https://github.com/vczh-libraries/GacJS/blob/master/Wildcard.html)**. 45 | * **[Resource.js](https://github.com/vczh-libraries/GacJS/blob/master/Script/IO/Resource.js)** : A delay static resource loader. Test page: **[Navigation.html](https://github.com/vczh-libraries/GacJS/blob/master/Resource.html)**. 46 | * **[GacUI/](https://github.com/vczh-libraries/GacJS/tree/master/Script/GacUI)** : GacUI in Browsers!. 47 | * **[Types.js](https://github.com/vczh-libraries/GacJS/blob/master/Script/GacUI/Types.js)** : Basic types that used in GacJS. 48 | * **[Elements/](https://github.com/vczh-libraries/GacJS/tree/master/Script/GacUI/Elements)** : GacUI Predefined Graphic Elements. Test page: **[Element.html](https://github.com/vczh-libraries/GacJS/blob/master/Element.html)**. 49 | * **[Interface.js](https://github.com/vczh-libraries/GacJS/blob/master/Script/GacUI/Elements/Interface.js)** 50 | * **[Basic.js](https://github.com/vczh-libraries/GacJS/blob/master/Script/GacUI/Elements/Basic.js)** 51 | * **[ColorizedText.js](https://github.com/vczh-libraries/GacJS/blob/master/Script/GacUI/Elements/ColorizedText.js)** 52 | * **[Document.js](https://github.com/vczh-libraries/GacJS/blob/master/Script/GacUI/Elements/Document.js)** 53 | * **[GacUI/Layout/](https://github.com/vczh-libraries/GacJS/tree/master/Script/GacUI/Layout)** : GacUI Predefined Layout Components. Test page: **[Layout.html](https://github.com/vczh-libraries/GacJS/blob/master/Layout.html)**. 54 | * **[Basic.js](https://github.com/vczh-libraries/GacJS/blob/master/Script/GacUI/Layout/Basic.js)** 55 | * **[Bounds.js](https://github.com/vczh-libraries/GacJS/blob/master/Script/GacUI/Layout/Bounds.js)** 56 | * **[Stack.js](https://github.com/vczh-libraries/GacJS/blob/master/Script/GacUI/Layout/Stack.js)** 57 | * **[Table.js](https://github.com/vczh-libraries/GacJS/blob/master/Script/GacUI/Layout/Table.js)** 58 | * **[Misc.js](https://github.com/vczh-libraries/GacJS/blob/master/Script/GacUI/Layout/Misc.js)** 59 | * **Templates.js** 60 | * **Controls.js** 61 | -------------------------------------------------------------------------------- /Razor.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Razor 6 | 7 | 8 | 9 | 10 | 11 |
12 |
13 |
Expressions
14 |
Statements
15 |
Functions
16 |
Codes
17 |
Errors
18 |
19 | 20 |
21 | 24 |
25 | 39 | 56 | 68 |
69 | 72 |
73 | 89 | 107 | 121 | 137 | 154 | 177 |
178 | 181 |
182 | 208 | 251 |
252 | 255 |
256 | 287 |
288 | 291 |
292 | 300 | 308 | 314 | 319 | 327 | 335 | 343 | 348 | 353 | 358 | 363 | 368 | 373 | 378 | 383 | 388 | 393 | 398 | 403 | 408 |
409 |
410 | 411 |
412 | 413 | 439 | 440 | 549 | 550 | 551 | -------------------------------------------------------------------------------- /Resource.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Resource 5 | 6 | 7 | 8 | 9 | 10 | 16 | 23 | 30 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /Script/GacUI/Elements/Basic.js: -------------------------------------------------------------------------------- 1 | Packages.Define("GacUI.Elements.Basic", ["Class", "GacUI.Types", "Html.ResizeEvent", "GacUI.Elements.Interface"], function (__injection__) { 2 | eval(__injection__); 3 | 4 | function FQN(name) { 5 | return "vl::presentation::elements::Gui" + name + "Element"; 6 | } 7 | 8 | var ElementShape = Enum("vl::presentation::elements::ElementShape", { 9 | Rectangle: 0, 10 | Ellipse: 1, 11 | }); 12 | 13 | /******************************************************************************** 14 | SolidBorder 15 | ********************************************************************************/ 16 | 17 | var SolidBorder = Class(FQN("SolidBorder"), IElement, { 18 | 19 | color: Protected(new Color()), 20 | shape: Protected(ElementShape.Description.Rectangle), 21 | 22 | UpdateStyle: Protected(function () { 23 | this.htmlElement.style.borderColor = this.color.__ToString(); 24 | switch (this.shape) { 25 | case ElementShape.Description.Rectangle: 26 | this.htmlElement.style.borderRadius = ""; 27 | break; 28 | case ElementShape.Description.Ellipse: 29 | this.htmlElement.style.borderRadius = "50%"; 30 | break; 31 | } 32 | }), 33 | 34 | __Constructor: Public(function () { 35 | this.htmlElement = document.createElement("div"); 36 | this.htmlElement.style.display = "block"; 37 | this.htmlElement.style.position = "relative"; 38 | this.htmlElement.style.width = "calc(100% - 2px)"; 39 | this.htmlElement.style.height = "calc(100% - 2px)"; 40 | this.htmlElement.style.borderStyle = "solid"; 41 | this.htmlElement.style.borderWidth = "1px"; 42 | this.UpdateStyle(); 43 | }), 44 | 45 | GetColor: Public.StrongTyped(Color, [], function () { 46 | return this.color; 47 | }), 48 | SetColor: Public.StrongTyped(__Void, [Color], function (value) { 49 | this.color = value; 50 | this.UpdateStyle(); 51 | }), 52 | Color: Public.Property({}), 53 | 54 | GetShape: Public.StrongTyped(ElementShape, [], function () { 55 | return this.shape; 56 | }), 57 | SetShape: Public.StrongTyped(__Void, [ElementShape], function (value) { 58 | this.shape = value; 59 | this.UpdateStyle(); 60 | }), 61 | Shape: Public.Property({}), 62 | }); 63 | 64 | /******************************************************************************** 65 | RoundBorder 66 | ********************************************************************************/ 67 | 68 | var RoundBorder = Class(FQN("RoundBorder"), IElement, { 69 | 70 | color: Protected(new Color()), 71 | radius: Protected(0.0), 72 | 73 | UpdateStyle: Protected(function () { 74 | this.htmlElement.style.borderColor = this.color.__ToString(); 75 | this.htmlElement.style.borderRadius = this.radius + "px"; 76 | }), 77 | 78 | __Constructor: Public(function () { 79 | this.htmlElement = document.createElement("div"); 80 | this.htmlElement.style.display = "block"; 81 | this.htmlElement.style.position = "relative"; 82 | this.htmlElement.style.width = "calc(100% - 2px)"; 83 | this.htmlElement.style.height = "calc(100% - 2px)"; 84 | this.htmlElement.style.borderStyle = "solid"; 85 | this.htmlElement.style.borderWidth = "1px"; 86 | this.UpdateStyle(); 87 | }), 88 | 89 | GetColor: Public.StrongTyped(Color, [], function () { 90 | return this.color; 91 | }), 92 | SetColor: Public.StrongTyped(__Void, [Color], function (value) { 93 | this.color = value; 94 | this.UpdateStyle(); 95 | }), 96 | Color: Public.Property({}), 97 | 98 | GetRadius: Public.StrongTyped(__Number, [], function () { 99 | return this.radius; 100 | }), 101 | SetRadius: Public.StrongTyped(__Void, [__Number], function (value) { 102 | this.radius = value; 103 | this.UpdateStyle(); 104 | }), 105 | Radius: Public.Property({}), 106 | }); 107 | 108 | /******************************************************************************** 109 | ThreeDBorder 110 | ********************************************************************************/ 111 | 112 | var ThreeDBorder = Class(FQN("3DBorder"), IElement, { 113 | 114 | color1: Protected(new Color()), 115 | color2: Protected(new Color()), 116 | 117 | UpdateStyle: Protected(function () { 118 | this.htmlElement.style.borderLeftColor = this.color1.__ToString(); 119 | this.htmlElement.style.borderTopColor = this.color1.__ToString(); 120 | this.htmlElement.style.borderRightColor = this.color2.__ToString(); 121 | this.htmlElement.style.borderBottomColor = this.color2.__ToString(); 122 | }), 123 | 124 | __Constructor: Public(function () { 125 | this.htmlElement = document.createElement("div"); 126 | this.htmlElement.style.display = "block"; 127 | this.htmlElement.style.position = "relative"; 128 | this.htmlElement.style.width = "calc(100% - 2px)"; 129 | this.htmlElement.style.height = "calc(100% - 2px)"; 130 | this.htmlElement.style.borderStyle = "solid"; 131 | this.htmlElement.style.borderWidth = "1px"; 132 | this.UpdateStyle(); 133 | }), 134 | 135 | GetColor1: Public.StrongTyped(Color, [], function () { 136 | return this.color1; 137 | }), 138 | SetColor1: Public.StrongTyped(__Void, [Color], function (value) { 139 | this.color1 = value; 140 | this.UpdateStyle(); 141 | }), 142 | Color1: Public.Property({}), 143 | 144 | GetColor2: Public.StrongTyped(Color, [], function () { 145 | return this.color2; 146 | }), 147 | SetColor2: Public.StrongTyped(__Void, [Color], function (value) { 148 | this.color2 = value; 149 | this.UpdateStyle(); 150 | }), 151 | Color2: Public.Property({}), 152 | 153 | SetColors: Public.StrongTyped(__Void, [Color, Color], function (value1, value2) { 154 | this.color1 = value1; 155 | this.color2 = value2; 156 | this.UpdateStyle(); 157 | }), 158 | }); 159 | 160 | /******************************************************************************** 161 | ThreeDSplitter 162 | ********************************************************************************/ 163 | 164 | var ThreeDSplitterDirection = Enum("vl::presentation::elements::Gui3DSplitterElement::Direction", { 165 | Horizontal: 0, 166 | Vertical: 1, 167 | }); 168 | 169 | var ThreeDSplitter = Class(FQN("3DSplitter"), IElement, { 170 | 171 | splitterHtmlElement: Protected(null), 172 | color1: Protected(new Color()), 173 | color2: Protected(new Color()), 174 | direction: Protected(ThreeDSplitterDirection.Description.Horizontal), 175 | 176 | UpdateStyle: Protected(function () { 177 | this.splitterHtmlElement.style.borderLeftColor = this.color1.__ToString(); 178 | this.splitterHtmlElement.style.borderTopColor = this.color1.__ToString(); 179 | this.splitterHtmlElement.style.borderRightColor = this.color2.__ToString(); 180 | this.splitterHtmlElement.style.borderBottomColor = this.color2.__ToString(); 181 | switch (this.direction) { 182 | case ThreeDSplitterDirection.Description.Horizontal: 183 | this.htmlElement.style.flexDirection = "column"; 184 | this.splitterHtmlElement.style.width = "calc(100% - 2px)"; 185 | this.splitterHtmlElement.style.height = "0"; 186 | break; 187 | case ThreeDSplitterDirection.Description.Vertical: 188 | this.htmlElement.style.flexDirection = "row"; 189 | this.splitterHtmlElement.style.width = "0"; 190 | this.splitterHtmlElement.style.height = "calc(100% - 2px)"; 191 | break; 192 | } 193 | }), 194 | 195 | __Constructor: Public(function () { 196 | this.htmlElement = document.createElement("div"); 197 | this.htmlElement.style.display = "flex"; 198 | this.htmlElement.style.justifyContent = "center"; 199 | this.htmlElement.style.position = "relative"; 200 | this.htmlElement.style.width = "100%"; 201 | this.htmlElement.style.height = "100%"; 202 | 203 | this.splitterHtmlElement = document.createElement("div"); 204 | this.splitterHtmlElement.style.display = "block"; 205 | this.splitterHtmlElement.style.position = "relative"; 206 | this.splitterHtmlElement.style.borderStyle = "solid"; 207 | this.splitterHtmlElement.style.borderWidth = "1px"; 208 | this.htmlElement.appendChild(this.splitterHtmlElement); 209 | this.UpdateStyle(); 210 | }), 211 | 212 | GetColor1: Public.StrongTyped(Color, [], function () { 213 | return this.color1; 214 | }), 215 | SetColor1: Public.StrongTyped(__Void, [Color], function (value) { 216 | this.color1 = value; 217 | this.UpdateStyle(); 218 | }), 219 | Color1: Public.Property({}), 220 | 221 | GetColor2: Public.StrongTyped(Color, [], function () { 222 | return this.color2; 223 | }), 224 | SetColor2: Public.StrongTyped(__Void, [Color], function (value) { 225 | this.color2 = value; 226 | this.UpdateStyle(); 227 | }), 228 | Color2: Public.Property({}), 229 | 230 | SetColors: Public.StrongTyped(__Void, [Color, Color], function (value1, value2) { 231 | this.color1 = value1; 232 | this.color2 = value2; 233 | this.UpdateStyle(); 234 | }), 235 | 236 | GetDirection: Public.StrongTyped(ThreeDSplitterDirection, [], function () { 237 | return this.direction; 238 | }), 239 | SetDirection: Public.StrongTyped(__Void, [ThreeDSplitterDirection], function (value) { 240 | this.direction = value; 241 | this.UpdateStyle(); 242 | }), 243 | Direction: Public.Property({}), 244 | }); 245 | 246 | /******************************************************************************** 247 | SolidBackground 248 | ********************************************************************************/ 249 | 250 | var SolidBackground = Class(FQN("SolidBackground"), IElement, { 251 | 252 | color: Protected(new Color()), 253 | shape: Protected(ElementShape.Description.Rectangle), 254 | 255 | UpdateStyle: Protected(function () { 256 | this.htmlElement.style.backgroundColor = this.color.__ToString(); 257 | switch (this.shape) { 258 | case ElementShape.Description.Rectangle: 259 | this.htmlElement.style.borderRadius = ""; 260 | break; 261 | case ElementShape.Description.Ellipse: 262 | this.htmlElement.style.borderRadius = "50%"; 263 | break; 264 | } 265 | }), 266 | 267 | __Constructor: Public(function () { 268 | this.htmlElement = document.createElement("div"); 269 | this.htmlElement.style.display = "block"; 270 | this.htmlElement.style.position = "relative"; 271 | this.htmlElement.style.width = "100%"; 272 | this.htmlElement.style.height = "100%"; 273 | this.htmlElement.style.backgroundStyle = "solid"; 274 | this.UpdateStyle(); 275 | }), 276 | 277 | GetColor: Public.StrongTyped(Color, [], function () { 278 | return this.color; 279 | }), 280 | SetColor: Public.StrongTyped(__Void, [Color], function (value) { 281 | this.color = value; 282 | this.UpdateStyle(); 283 | }), 284 | Color: Public.Property({}), 285 | 286 | GetShape: Public.StrongTyped(ElementShape, [], function () { 287 | return this.shape; 288 | }), 289 | SetShape: Public.StrongTyped(__Void, [ElementShape], function (value) { 290 | this.shape = value; 291 | this.UpdateStyle(); 292 | }), 293 | Shape: Public.Property({}), 294 | }); 295 | 296 | /******************************************************************************** 297 | GradientBackground 298 | ********************************************************************************/ 299 | 300 | var GradientBackgroundrDirection = Enum("vl::presentation::elements::GuiGradientBackgroundElement::Direction", { 301 | Horizontal: 0, 302 | Vertical: 1, 303 | Slash: 2, 304 | Backslash: 2, 305 | }); 306 | 307 | var GradientBackground = Class(FQN("GradientBackground"), IElement, { 308 | 309 | color1: Protected(new Color()), 310 | color2: Protected(new Color()), 311 | direction: Protected(GradientBackgroundrDirection.Description.Horizontal), 312 | shape: Protected(ElementShape.Description.Rectangle), 313 | 314 | UpdateStyle: Protected(function () { 315 | var colorStop1 = this.color1.__ToString(); 316 | var colorStop2 = this.color2.__ToString(); 317 | switch (this.direction) { 318 | case GradientBackgroundrDirection.Description.Horizontal: 319 | var side = "right"; 320 | break; 321 | case GradientBackgroundrDirection.Description.Vertical: 322 | var side = "bottom"; 323 | break; 324 | case GradientBackgroundrDirection.Description.Slash: 325 | var side = "left bottom"; 326 | break; 327 | case GradientBackgroundrDirection.Description.Backslash: 328 | var side = "right bottom"; 329 | break; 330 | } 331 | this.htmlElement.style.background = "linear-gradient(to " + side + ", " + colorStop1 + " 0%, " + colorStop2 + " 100%)"; 332 | switch (this.shape) { 333 | case ElementShape.Description.Rectangle: 334 | this.htmlElement.style.borderRadius = ""; 335 | break; 336 | case ElementShape.Description.Ellipse: 337 | this.htmlElement.style.borderRadius = "50%"; 338 | break; 339 | } 340 | }), 341 | 342 | __Constructor: Public(function () { 343 | this.htmlElement = document.createElement("div"); 344 | this.htmlElement.style.display = "block"; 345 | this.htmlElement.style.position = "relative"; 346 | this.htmlElement.style.width = "100%"; 347 | this.htmlElement.style.height = "100%"; 348 | this.htmlElement.style.backgroundStyle = "solid"; 349 | this.UpdateStyle(); 350 | }), 351 | 352 | GetColor1: Public.StrongTyped(Color, [], function () { 353 | return this.color1; 354 | }), 355 | SetColor1: Public.StrongTyped(__Void, [Color], function (value) { 356 | this.color1 = value; 357 | this.UpdateStyle(); 358 | }), 359 | Color1: Public.Property({}), 360 | 361 | GetColor2: Public.StrongTyped(Color, [], function () { 362 | return this.color2; 363 | }), 364 | SetColor2: Public.StrongTyped(__Void, [Color], function (value) { 365 | this.color2 = value; 366 | this.UpdateStyle(); 367 | }), 368 | Color2: Public.Property({}), 369 | 370 | SetColors: Public.StrongTyped(__Void, [Color, Color], function (value1, value2) { 371 | this.color1 = value1; 372 | this.color2 = value2; 373 | this.UpdateStyle(); 374 | }), 375 | 376 | GetDirection: Public.StrongTyped(GradientBackgroundrDirection, [], function () { 377 | return this.direction; 378 | }), 379 | SetDirection: Public.StrongTyped(__Void, [GradientBackgroundrDirection], function (value) { 380 | this.direction = value; 381 | this.UpdateStyle(); 382 | }), 383 | Direction: Public.Property({}), 384 | 385 | GetShape: Public.StrongTyped(ElementShape, [], function () { 386 | return this.shape; 387 | }), 388 | SetShape: Public.StrongTyped(__Void, [ElementShape], function (value) { 389 | this.shape = value; 390 | this.UpdateStyle(); 391 | }), 392 | Shape: Public.Property({}), 393 | }); 394 | 395 | /******************************************************************************** 396 | SolidLabel 397 | ********************************************************************************/ 398 | 399 | var SolidLabel = Class(FQN("SolidLabel"), IElement, { 400 | 401 | color: Protected(new Color()), 402 | font: Protected(new FontProperties()), 403 | text: Protected(""), 404 | horizontalAlignment: Protected(Alignment.Description.Left), 405 | verticalAlignment: Protected(Alignment.Description.Top), 406 | wrapLine: Protected(false), 407 | ellipse: Protected(false), 408 | multiline: Protected(false), 409 | wrapLineHeightCalculation: Protected(false), 410 | 411 | horizontalHtmlFlexElement: Protected(null), 412 | verticalHtmlFlexElement: Protected(null), 413 | textHtmlElement: Protected(null), 414 | referenceHtmlElement: Protected(null), 415 | measuringHtmlElement: Protected(null), 416 | 417 | enabledMinSizeNotify: Protected(false), 418 | measuringMinSize: Protected(false), 419 | measuringHtmlElementSizeChanged: Protected(false), 420 | suppressMeasuringHtmlElementSizeChanged: Protected(false), 421 | 422 | UpdateMinSize: Protected(function () { 423 | var x = 0; 424 | var y = 0; 425 | if (this.measuringMinSize) { 426 | if (!this.wrapLine) { 427 | x = this.measuringHtmlElement.offsetWidth; 428 | } 429 | y = this.measuringHtmlElement.offsetHeight; 430 | } 431 | 432 | if (this.minSize.cx !== x || this.minSize.cy !== y) { 433 | this.minSize = new Size(x, y); 434 | this.gacjs_MinSizeChanged.Execute(); 435 | } 436 | }), 437 | 438 | UpdateMinSizeMeasuringState: Protected(function () { 439 | var newMeasuringMinSize = this.enabledMinSizeNotify && !this.ellipse && (!this.wrapLine || this.wrapLineHeightCalculation); 440 | if (this.measuringMinSize !== newMeasuringMinSize) { 441 | this.measuringMinSize = newMeasuringMinSize; 442 | 443 | } 444 | 445 | if (this.measuringMinSize) { 446 | this.measuringHtmlElement.style.width = this.textHtmlElement.style.width; 447 | } 448 | else { 449 | this.measuringHtmlElement.style.width = "0"; 450 | } 451 | }), 452 | 453 | UpdateStyleInternal: Protected(function (textElement, forDisplay) { 454 | textElement.innerHTML = ""; 455 | if (this.multiline) { 456 | if (this.ellipse && !this.wrapLine) { 457 | // Internet Explorer 11.0 458 | var lines = this.text.split(/\r?\n/); 459 | for (var i = 0; i < lines.length; i++) { 460 | var div = document.createElement("div"); 461 | if (forDisplay) { 462 | div.style.overflow = "hidden"; 463 | div.style.textOverflow = "ellipsis"; 464 | } 465 | div.appendChild(document.createTextNode(lines[i])); 466 | textElement.appendChild(div); 467 | } 468 | } 469 | else { 470 | textElement.appendChild(document.createTextNode(this.text)); 471 | } 472 | } 473 | else { 474 | if (forDisplay) { 475 | textElement.style.textOverflow = (this.ellipse && !this.wrapLine ? "ellipsis" : ""); 476 | } 477 | textElement.appendChild(document.createTextNode(this.text.replace(/\r?\n/, " "))); 478 | } 479 | 480 | textElement.style.color = this.color.__ToString(); 481 | textElement.style.fontFamily = "'" + this.font.fontFamily + "'"; 482 | textElement.style.fontSize = this.font.size + "px"; 483 | textElement.style.fontWeight = (this.font.bold ? "bold" : "normal"); 484 | textElement.style.fontStyle = (this.font.italic ? "italic" : "normal"); 485 | textElement.style.textDecoration = (this.font.underline ? "underline" : ""); 486 | textElement.style.whiteSpace = (this.wrapLine ? "pre-wrap" : "pre"); 487 | }), 488 | 489 | UpdateStyle: Protected(function () { 490 | this.suppressMeasuringHtmlElementSizeChanged = true; 491 | 492 | switch (this.horizontalAlignment) { 493 | case Alignment.Description.Left: 494 | this.horizontalHtmlFlexElement.style.justifyContent = "flex-start"; 495 | break; 496 | case Alignment.Description.Right: 497 | this.horizontalHtmlFlexElement.style.justifyContent = "flex-end"; 498 | break; 499 | default: 500 | this.horizontalHtmlFlexElement.style.justifyContent = "center"; 501 | break; 502 | } 503 | 504 | switch (this.verticalAlignment) { 505 | case Alignment.Description.Top: 506 | this.verticalHtmlFlexElement.style.justifyContent = "flex-start"; 507 | break; 508 | case Alignment.Description.Bottom: 509 | this.verticalHtmlFlexElement.style.justifyContent = "flex-end"; 510 | break; 511 | default: 512 | this.verticalHtmlFlexElement.style.justifyContent = "center"; 513 | break; 514 | } 515 | 516 | this.htmlElement.style.color = this.color.__ToString(); 517 | this.htmlElement.style.textDecoration = (this.font.strikeline ? "line-through" : ""); 518 | this.UpdateStyleInternal(this.textHtmlElement, true); 519 | this.UpdateStyleInternal(this.referenceHtmlElement, false); 520 | this.UpdateStyleInternal(this.measuringHtmlElement, false); 521 | this.UpdateMinSizeMeasuringState(); 522 | 523 | this.suppressMeasuringHtmlElementSizeChanged = false; 524 | if (this.measuringHtmlElementSizeChanged) { 525 | this.UpdateMinSize(); 526 | this.measuringHtmlElementSizeChanged = false; 527 | } 528 | }), 529 | 530 | measuringHtmlElement_OnResize: Protected(function () { 531 | if (!this.suppressMeasuringHtmlElementSizeChanged) { 532 | this.UpdateMinSize(); 533 | } 534 | else { 535 | this.measuringHtmlElementSizeChanged = true; 536 | } 537 | }), 538 | 539 | HtmlElement_OnResize: Protected(function () { 540 | var referenceWidth = this.referenceHtmlElement.offsetWidth; 541 | var displayWidth = this.htmlElement.offsetWidth; 542 | if (this.wrapLine || this.ellipse) { 543 | var width = (Math.min(referenceWidth, displayWidth) + 1) + "px"; 544 | } 545 | else { 546 | var width = referenceWidth + "px"; 547 | } 548 | if (this.textHtmlElement.style.width !== width) { 549 | this.textHtmlElement.style.width = width; 550 | this.UpdateMinSizeMeasuringState(); 551 | } 552 | }), 553 | 554 | gacjs_EnableMinSizeNotify: Public.Override.StrongTyped(__Void, [__Boolean], function (enabled) { 555 | this.enabledMinSizeNotify = enabled; 556 | this.UpdateMinSizeMeasuringState(); 557 | }), 558 | 559 | __Constructor: Public(function () { 560 | this.horizontalHtmlFlexElement = document.createElement("div"); 561 | this.horizontalHtmlFlexElement.style.position = "relative"; 562 | this.horizontalHtmlFlexElement.style.display = "flex"; 563 | this.horizontalHtmlFlexElement.style.flexDirection = "row"; 564 | this.horizontalHtmlFlexElement.style.height = "100%"; 565 | 566 | this.verticalHtmlFlexElement = document.createElement("div"); 567 | this.verticalHtmlFlexElement.style.position = "relative"; 568 | this.verticalHtmlFlexElement.style.display = "flex"; 569 | this.verticalHtmlFlexElement.style.flexDirection = "column"; 570 | 571 | this.textHtmlElement = document.createElement("div"); 572 | this.textHtmlElement.style.display = "block"; 573 | this.textHtmlElement.style.position = "relative"; 574 | this.textHtmlElement.style.overflow = "hidden"; 575 | 576 | this.referenceHtmlElement = document.createElement("div"); 577 | this.referenceHtmlElement.style.display = "block"; 578 | this.referenceHtmlElement.style.position = "fixed"; 579 | this.referenceHtmlElement.style.visibility = "hidden"; 580 | this.referenceHtmlElement.style.left = "0"; 581 | this.referenceHtmlElement.style.top = "0"; 582 | 583 | this.measuringHtmlElement = document.createElement("div"); 584 | this.measuringHtmlElement.style.display = "block"; 585 | this.measuringHtmlElement.style.position = "fixed"; 586 | this.measuringHtmlElement.style.visibility = "hidden"; 587 | this.measuringHtmlElement.style.left = "0"; 588 | this.measuringHtmlElement.style.top = "0"; 589 | 590 | this.horizontalHtmlFlexElement.appendChild(this.verticalHtmlFlexElement); 591 | this.verticalHtmlFlexElement.appendChild(this.textHtmlElement); 592 | this.verticalHtmlFlexElement.appendChild(this.referenceHtmlElement); 593 | this.verticalHtmlFlexElement.appendChild(this.measuringHtmlElement); 594 | this.htmlElement = this.horizontalHtmlFlexElement; 595 | this.UpdateStyle(); 596 | 597 | var self = this; 598 | DetectResize(this.htmlElement, function () { 599 | self.HtmlElement_OnResize(); 600 | }); 601 | DetectResize(this.measuringHtmlElement, function () { 602 | self.measuringHtmlElement_OnResize(); 603 | }); 604 | }), 605 | 606 | GetColor: Public(function () { 607 | return this.color; 608 | }), 609 | SetColor: Public(function (value) { 610 | this.color = value; 611 | this.UpdateStyle(); 612 | }), 613 | Color: Public.Property({}), 614 | 615 | GetFont: Public(function () { 616 | return this.font; 617 | }), 618 | SetFont: Public(function (value) { 619 | this.font = value; 620 | this.UpdateStyle(); 621 | }), 622 | Font: Public.Property({}), 623 | 624 | GetText: Public(function () { 625 | return this.text; 626 | }), 627 | SetText: Public(function (value) { 628 | this.text = value; 629 | this.UpdateStyle(); 630 | }), 631 | Text: Public.Property({}), 632 | 633 | GetHorizontalAlignment: Public(function () { 634 | return this.horizontalAlignment; 635 | }), 636 | SetHorizontalAlignment: Public(function (value) { 637 | this.horizontalAlignment = value; 638 | this.UpdateStyle(); 639 | }), 640 | HorizontalAlignment: Public.Property({}), 641 | 642 | GetVerticalAlignment: Public(function () { 643 | return this.verticalAlignment; 644 | }), 645 | SetVerticalAlignment: Public(function (value) { 646 | this.verticalAlignment = value; 647 | this.UpdateStyle(); 648 | }), 649 | VerticalAlignment: Public.Property({}), 650 | 651 | SetAlignments: Public(function (horizontal, vertical) { 652 | this.horizontalAlignment = horizontal; 653 | this.verticalAlignment = vertical; 654 | this.UpdateStyle(); 655 | }), 656 | 657 | GetWrapLine: Public(function () { 658 | return this.wrapLine; 659 | }), 660 | SetWrapLine: Public(function (value) { 661 | this.wrapLine = value; 662 | this.UpdateStyle(); 663 | }), 664 | WrapLine: Public.Property({}), 665 | 666 | GetEllipse: Public(function () { 667 | return this.ellipse; 668 | }), 669 | SetEllipse: Public(function (value) { 670 | this.ellipse = value; 671 | this.UpdateStyle(); 672 | }), 673 | Ellipse: Public.Property({}), 674 | 675 | GetMultiline: Public(function () { 676 | return this.multiline; 677 | }), 678 | SetMultiline: Public(function (value) { 679 | this.multiline = value; 680 | this.UpdateStyle(); 681 | }), 682 | Multiline: Public.Property({}), 683 | 684 | GetWrapLineHeightCalculation: Public(function () { 685 | return this.wrapLineHeightCalculation; 686 | }), 687 | SetWrapLineHeightCalculation: Public(function (value) { 688 | this.wrapLineHeightCalculation = value; 689 | this.UpdateStyle(); 690 | }), 691 | WrapLineHeightCalculation: Public.Property({}), 692 | }); 693 | 694 | /******************************************************************************** 695 | ImageFrame 696 | ********************************************************************************/ 697 | 698 | var ImageFrameElement = Class(FQN("ImageFrame"), IElement, { 699 | 700 | image: Protected(""), 701 | horizontalAlignment: Protected(Alignment.Description.Left), 702 | verticalAlignment: Protected(Alignment.Description.Top), 703 | stretch: Protected(false), 704 | enabled: Protected(false), 705 | 706 | UpdateStyle: Protected(function () { 707 | throw new Error("Not Implemented."); 708 | }), 709 | 710 | __Constructor: Public(function () { 711 | this.htmlElement = document.createElement("div"); 712 | this.htmlElement.style.display = "block"; 713 | this.htmlElement.style.position = "relative"; 714 | this.htmlElement.style.width = "100%"; 715 | this.htmlElement.style.height = "100%"; 716 | this.UpdateStyle(); 717 | }), 718 | 719 | GetImage: Public(function () { 720 | return this.image; 721 | }), 722 | SetImage: Public(function (value) { 723 | this.image = value; 724 | this.UpdateStyle(); 725 | }), 726 | Image: Public.Property({}), 727 | 728 | GetHorizontalAlignment: Public(function () { 729 | return this.horizontalAlignment; 730 | }), 731 | SetHorizontalAlignment: Public(function (value) { 732 | this.horizontalAlignment = value; 733 | this.UpdateStyle(); 734 | }), 735 | HorizontalAlignment: Public.Property({}), 736 | 737 | GetVerticalAlignment: Public(function () { 738 | return this.verticalAlignment; 739 | }), 740 | SetVerticalAlignment: Public(function (value) { 741 | this.verticalAlignment = value; 742 | this.UpdateStyle(); 743 | }), 744 | VerticalAlignment: Public.Property({}), 745 | 746 | SetAlignments: Public(function (horizontal, vertical) { 747 | this.horizontalAlignment = horizontal; 748 | this.verticalAlignment = vertical; 749 | this.UpdateStyle(); 750 | }), 751 | 752 | GetStretch: Public(function () { 753 | return this.stretch; 754 | }), 755 | SetStretch: Public(function (value) { 756 | this.stretch = value; 757 | this.UpdateStyle(); 758 | }), 759 | Stretch: Public.Property({}), 760 | 761 | GetEnabled: Public(function () { 762 | return this.enabled; 763 | }), 764 | SetEnabled: Public(function (value) { 765 | this.enabled = value; 766 | this.UpdateStyle(); 767 | }), 768 | Enabled: Public.Property({}), 769 | }); 770 | 771 | /******************************************************************************** 772 | Polygon 773 | ********************************************************************************/ 774 | 775 | var PolygonElement = Class(FQN("Polygon"), IElement, { 776 | 777 | __Constructor: Public(function () { 778 | this.htmlElement = document.createElement("div"); 779 | this.htmlElement.style.display = "block"; 780 | this.htmlElement.style.position = "relative"; 781 | this.htmlElement.style.width = "100%"; 782 | this.htmlElement.style.height = "100%"; 783 | this.UpdateStyle(); 784 | }), 785 | }); 786 | 787 | /******************************************************************************** 788 | Package 789 | ********************************************************************************/ 790 | 791 | return { 792 | ElementShape: ElementShape, 793 | SolidBorder: SolidBorder, 794 | RoundBorder: RoundBorder, 795 | ThreeDBorder: ThreeDBorder, 796 | ThreeDSplitter: ThreeDSplitter, 797 | ThreeDSplitterDirection: ThreeDSplitterDirection, 798 | SolidBackground: SolidBackground, 799 | GradientBackground: GradientBackground, 800 | GradientBackgroundrDirection: GradientBackgroundrDirection, 801 | SolidLabel: SolidLabel, 802 | ImageFrameElement: ImageFrameElement, 803 | PolygonElement: PolygonElement, 804 | } 805 | }); -------------------------------------------------------------------------------- /Script/GacUI/Elements/ColorizedText.js: -------------------------------------------------------------------------------- 1 | Packages.Define("GacUI.Elements.ColorizedText", ["Class", "GacUI.Types", "GacUI.Elements.Interface"], function (__injection__) { 2 | eval(__injection__); 3 | 4 | function FQN(name) { 5 | return "vl::presentation::elements::Gui" + name + "Element"; 6 | } 7 | 8 | /******************************************************************************** 9 | ColorizedText 10 | ********************************************************************************/ 11 | 12 | var ColorizedTextElement = Class(FQN("ColorizedText"), IElement, { 13 | 14 | __Constructor: Public(function () { 15 | this.htmlElement = document.createElement("div"); 16 | this.htmlElement.style.display = "block"; 17 | this.htmlElement.style.position = "relative"; 18 | this.htmlElement.style.width = "100%"; 19 | this.htmlElement.style.height = "100%"; 20 | this.UpdateStyle(); 21 | }), 22 | }); 23 | 24 | /******************************************************************************** 25 | Package 26 | ********************************************************************************/ 27 | 28 | return { 29 | ColorizedTextElement: ColorizedTextElement, 30 | } 31 | }); -------------------------------------------------------------------------------- /Script/GacUI/Elements/Document.js: -------------------------------------------------------------------------------- 1 | Packages.Define("GacUI.Elements.Document", ["Class", "GacUI.Types", "GacUI.Elements.Interface"], function (__injection__) { 2 | eval(__injection__); 3 | 4 | function FQN(name) { 5 | return "vl::presentation::elements::Gui" + name + "Element"; 6 | } 7 | 8 | /******************************************************************************** 9 | Document 10 | ********************************************************************************/ 11 | 12 | var DocumentElement = Class(FQN("Document"), IElement, { 13 | 14 | __Constructor: Public(function () { 15 | this.htmlElement = document.createElement("div"); 16 | this.htmlElement.style.display = "block"; 17 | this.htmlElement.style.position = "relative"; 18 | this.htmlElement.style.width = "100%"; 19 | this.htmlElement.style.height = "100%"; 20 | this.UpdateStyle(); 21 | }), 22 | }); 23 | 24 | /******************************************************************************** 25 | Package 26 | ********************************************************************************/ 27 | 28 | return { 29 | DocumentElement: DocumentElement, 30 | } 31 | }); -------------------------------------------------------------------------------- /Script/GacUI/Elements/Interface.js: -------------------------------------------------------------------------------- 1 | Packages.Define("GacUI.Elements.Interface", ["Class", "GacUI.Types", "Html.ResizeEvent"], function (__injection__) { 2 | eval(__injection__); 3 | 4 | var IElement = Class("vl::presentation::elements::IGuiGraphicsElement", { 5 | 6 | htmlElement: Protected(null), 7 | minSize: Protected(new Size(0, 0)), 8 | 9 | gacjs_InstallElement: Public.Virtual(function (graphElement) { 10 | graphElement.appendChild(this.htmlElement); 11 | }), 12 | 13 | gacjs_UninstallElement: Public.Virtual(function (graphElement) { 14 | grapyElement.removeChild(this.htmlElement); 15 | }), 16 | 17 | gacjs_MinSizeChanged: Public.Event(), 18 | 19 | gacjs_EnableMinSizeNotify: Public.Virtual.StrongTyped(__Void, [__Boolean], function (enabled) { 20 | }), 21 | 22 | gacjs_GetMinSize: Public.StrongTyped(Size, [], function () { 23 | return this.minSize; 24 | }), 25 | }); 26 | 27 | /******************************************************************************** 28 | Package 29 | ********************************************************************************/ 30 | 31 | return { 32 | IElement: IElement, 33 | } 34 | }); -------------------------------------------------------------------------------- /Script/GacUI/Layout/Basic.js: -------------------------------------------------------------------------------- 1 | Packages.Define("GacUI.Layout.Basic", ["Class", "GacUI.Types", "GacUI.Elements.Interface"], function (__injection__) { 2 | eval(__injection__); 3 | 4 | function FQN(name) { 5 | return "vl::presentation::compositions::Gui" + name + "Composition"; 6 | } 7 | 8 | var MinSizeLimitation = Enum("vl::presentation::compositions::GuiGraphicsComposition::MinSizeLimitation", { 9 | NoLimit: 0, 10 | LimitToElement: 1, 11 | LimitToElementAndChildren: 2, 12 | }); 13 | 14 | /******************************************************************************** 15 | GuiGraphicsComposition 16 | ********************************************************************************/ 17 | 18 | var Layout = Class(FQN("Graphics"), function () { 19 | return { 20 | boundsHtmlElement: Protected(null), 21 | graphHtmlElement: Protected(null), 22 | containerHtmlElement: Protected(null), 23 | 24 | GetBoundsHtmlElement: Public(function () { 25 | return this.boundsHtmlElement; 26 | }), 27 | BoundsHtmlElement: Public.Property({}), 28 | 29 | GetGraphHtmlElement: Public(function () { 30 | return this.graphHtmlElement; 31 | }), 32 | GraphHtmlElement: Public.Property({}), 33 | 34 | GetContainerHtmlElement: Public(function () { 35 | return this.containerHtmlElement; 36 | }), 37 | ContainerHtmlElement: Public.Property({}), 38 | 39 | __Constructor: Public(function () { 40 | this.children = []; 41 | 42 | this.boundsHtmlElement = document.createElement("div"); 43 | this.boundsHtmlElement.gacjs_Layout = this.__ExternalReference; 44 | this.boundsHtmlElement.style.display = "block"; 45 | this.boundsHtmlElement.style.position = "absolute"; 46 | 47 | this.graphHtmlElement = document.createElement("div"); 48 | this.boundsHtmlElement.appendChild(this.graphHtmlElement); 49 | this.graphHtmlElement.style.display = "block"; 50 | this.graphHtmlElement.style.position = "relative"; 51 | this.graphHtmlElement.style.width = "100%"; 52 | this.graphHtmlElement.style.height = "100%"; 53 | this.graphHtmlElement.style.overflow = "hidden"; 54 | }), 55 | 56 | ////////////////////////////////////////////////////// 57 | 58 | visible: Protected(true), 59 | minSizeLimitation: Protected(MinSizeLimitation.Description.NoLimit), 60 | margin: Protected(new Margin(-1, -1, -1, -1)), 61 | internalMargin: Protected(new Margin(-1, -1, -1, -1)), 62 | preferredMinSize: Public(new Size(0, 0)), 63 | 64 | NeedMinSizeNotify: Protected(function (minSizeLimitation) { 65 | return !minSizeLimitation.__Equals(MinSizeLimitation.Description.NoLimit); 66 | }), 67 | 68 | UpdateMinSize: Protected(function () { 69 | if (this.element !== null && this.NeedMinSizeNotify(this.minSizeLimitation)) { 70 | var minSize = this.element.gacjs_GetMinSize(); 71 | this.boundsHtmlElement.style.minWidth = minSize.cx + "px"; 72 | this.boundsHtmlElement.style.minHeight = minSize.cy + "px"; 73 | } 74 | else { 75 | this.boundsHtmlElement.style.minWidth = ""; 76 | this.boundsHtmlElement.style.minHeight = ""; 77 | } 78 | }), 79 | 80 | UpdateStyle: Protected.Virtual(function () { 81 | // throw new Error("Not Implemented."); 82 | }), 83 | 84 | ////////////////////////////////////////////////////// 85 | 86 | GetVisible: Public(function () { 87 | return this.visible; 88 | }), 89 | SetVisible: Public(function (value) { 90 | this.visible = value; 91 | this.UpdateStyle(); 92 | }), 93 | Visible: Public.Property({}), 94 | 95 | GetMinSizeLimitation: Public(function () { 96 | return this.minSizeLimitation; 97 | }), 98 | SetMinSizeLimitation: Public(function (value) { 99 | if (!this.minSizeLimitation.__Equals(value)) { 100 | var oldValue = this.minSizeLimitation; 101 | this.minSizeLimitation = value; 102 | 103 | if (this.element !== null) { 104 | var oldNotify = this.NeedMinSizeNotify(oldValue); 105 | var newNotify = this.NeedMinSizeNotify(value); 106 | if (oldNotify !== newNotify) { 107 | this.element.gacjs_EnableMinSizeNotify(newNotify); 108 | this.UpdateMinSize(); 109 | } 110 | } 111 | } 112 | this.UpdateStyle(); 113 | }), 114 | MinSizeLimitation: Public.Property({}), 115 | 116 | GetMargin: Public(function () { 117 | return this.margin; 118 | }), 119 | SetMargin: Public(function (value) { 120 | this.margin = value; 121 | this.UpdateStyle(); 122 | }), 123 | Margin: Public.Property({}), 124 | 125 | GetInternalMargin: Public(function () { 126 | return this.internalMargin; 127 | }), 128 | SetInternalMargin: Public(function (value) { 129 | this.internalMargin = value; 130 | this.UpdateStyle(); 131 | }), 132 | InternalMargin: Public.Property({}), 133 | 134 | GetPreferredMinSize: Public(function () { 135 | return this.preferredMinSize; 136 | }), 137 | SetPreferredMinSize: Public(function (value) { 138 | this.preferredMinSize = value; 139 | this.UpdateStyle(); 140 | }), 141 | PreferredMinSize: Public.Property({}), 142 | 143 | ////////////////////////////////////////////////////// 144 | 145 | element: Protected(null), 146 | parent: Protected(null), 147 | children: Protected(null), 148 | 149 | GetParent: Public.StrongTyped(Layout, [], function () { 150 | return this.parent; 151 | }), 152 | gacjs_SetParent: Public.StrongTyped(__Void, [Layout], function (value) { 153 | this.parent = value; 154 | }), 155 | Parent: Public.Property({ readonly: true }), 156 | 157 | GetChildren: Public(function () { 158 | return this.children; 159 | }), 160 | Children: Public.Property({ readonly: true }), 161 | 162 | AddChild: Public.StrongTyped(__Boolean, [Layout], function (child) { 163 | if (this.children.indexOf(child) !== -1) { 164 | return false; 165 | } 166 | this.children.push(child); 167 | child.gacjs_SetParent(this.__ExternalReference); 168 | return true; 169 | }), 170 | InsertChild: Public.StrongTyped(__Boolean, [__Number, Layout], function (index, child) { 171 | if (this.children.indexOf(child) !== -1) { 172 | return false; 173 | } 174 | if (index < 0 || index > this.children.length) { 175 | return false; 176 | } 177 | this.children.splice(index, 0, child); 178 | child.gacjs_SetParent(this.__ExternalReference); 179 | return true; 180 | }), 181 | RemoveChild: Public.StrongTyped(__Boolean, [Layout], function (child) { 182 | var index = this.children.indexOf(child); 183 | if (index === -1) { 184 | return false; 185 | } 186 | this.children.splice(index, 1); 187 | child.gacjs_SetParent(null); 188 | return true; 189 | }), 190 | MoveChild: Public.StrongTyped(__Boolean, [Layout, __Number], function (child, newIndex) { 191 | if (newIndex < 0 || newIndex >= this.children.length) { 192 | return false; 193 | } 194 | var index = this.children.indexOf(child); 195 | if (index === -1) { 196 | return false; 197 | } 198 | this.children.splice(index, 1); 199 | this.children.splice(newIndex, 0, child); 200 | return true; 201 | }), 202 | 203 | elementMinSizeChangedHandler: Protected(null), 204 | 205 | element_OnMinSizeChanged: Protected(function () { 206 | this.UpdateMinSize(); 207 | }), 208 | 209 | GetOwnedElement: Public.StrongTyped(IElement, [], function () { 210 | return this.element; 211 | }), 212 | SetOwnedElement: Public.StrongTyped(__Void, [IElement], function (value) { 213 | if (this.element !== null) { 214 | this.element.gacjs_MinSizeChanged.Detach(this.elementMinSizeChangedHandler); 215 | this.elementMinSizeChangedHandler = null; 216 | this.element.gacjs_EnableMinSizeNotify(false); 217 | this.element.gacjs_UninstallElement(this.graphHtmlElement); 218 | } 219 | this.element = value; 220 | if (this.element !== null) { 221 | this.element.gacjs_InstallElement(this.graphHtmlElement); 222 | this.element.gacjs_EnableMinSizeNotify(this.NeedMinSizeNotify(this.minSizeLimitation)); 223 | 224 | var self = this; 225 | this.elementMinSizeChangedHandler = this.element.gacjs_MinSizeChanged.Attach(function () { 226 | self.element_OnMinSizeChanged(); 227 | }); 228 | } 229 | this.UpdateMinSize(); 230 | }), 231 | OwnedElement: Public.Property({}), 232 | 233 | ////////////////////////////////////////////////////// 234 | 235 | GetClientArea: Public(function () { 236 | throw new Error("Not Implemented."); 237 | }), 238 | ClientArea: Public.Property({}), 239 | 240 | ForceCalculateSizeImmediately: Public(function () { 241 | }), 242 | 243 | GetMinPreferredClientSize: Public(function () { 244 | throw new Error("Not Implemented."); 245 | }), 246 | MinPreferredClientSize: Public.Property({}), 247 | 248 | GetPreferredBounds: Public(function () { 249 | throw new Error("Not Implemented."); 250 | }), 251 | PreferredBounds: Public.Property({}), 252 | 253 | GetBounds: Public(function () { 254 | throw new Error("Not Implemented."); 255 | }), 256 | 257 | GetGlobalBounds: Public(function () { 258 | throw new Error("Not Implemented."); 259 | }), 260 | GlobalBounds: Public.Property({ readonly: true }), 261 | 262 | ////////////////////////////////////////////////////// 263 | 264 | GetAssociatedCursor: Public(function () { 265 | throw new Error("Not Implemented."); 266 | }), 267 | SetAssociatedCursor: Public(function (value) { 268 | throw new Error("Not Implemented."); 269 | }), 270 | AssociatedCursor: Public.Property({}), 271 | 272 | GetAssociatedControl: Public(function () { 273 | throw new Error("Not Implemented."); 274 | }), 275 | SetAssociatedControl: Public(function () { 276 | throw new Error("Not Implemented."); 277 | }), 278 | AssociatedControl: Public.Property({}), 279 | 280 | GetAssociatedHitTestResult: Public(function () { 281 | throw new Error("Not Implemented."); 282 | }), 283 | SetAssociatedHitTestResult: Public(function (value) { 284 | throw new Error("Not Implemented."); 285 | }), 286 | AssociatedHitTestResult: Public.Property({}), 287 | 288 | GetRelatedControl: Public(function () { 289 | throw new Error("Not Implemented."); 290 | }), 291 | RelatedControl: Public.Property({ readonly: true }), 292 | 293 | GetRelatedControlHost: Public(function () { 294 | throw new Error("Not Implemented."); 295 | }), 296 | RelatedControlHost: Public.Property({ readonly: true }), 297 | 298 | GetRelatedCursor: Public(function () { 299 | throw new Error("Not Implemented."); 300 | }), 301 | RelatedCursor: Public.Property({ readonly: true }), 302 | }; 303 | }); 304 | 305 | /******************************************************************************** 306 | GuiGraphicsSiteComposition 307 | ********************************************************************************/ 308 | 309 | var SiteLayout = Class(FQN("GraphicsSite"), Layout, { 310 | Bounds: Public.Property({ readonly: true }), 311 | }); 312 | 313 | /******************************************************************************** 314 | GuiWindowComposition 315 | ********************************************************************************/ 316 | 317 | var WindowLayout = Class(FQN("Window"), SiteLayout, { 318 | }); 319 | 320 | /******************************************************************************** 321 | GuiBoundsComposition 322 | ********************************************************************************/ 323 | 324 | var BoundsLayout = Class(FQN("Bounds"), Layout, { 325 | 326 | UpdateStyle: Protected.Override(function () { 327 | this.__Dynamic(Layout).UpdateStyle(); 328 | throw new Error("Not Implemented."); 329 | }), 330 | 331 | bounds: Protected(new Rect()), 332 | 333 | SetBounds: Public(function (value) { 334 | this.bounds = value; 335 | this.UpdateStyle(); 336 | }), 337 | Bounds: Public.Property({}), 338 | 339 | alignmentToParent: Protected(new Margin(-1, -1, -1, -1)), 340 | GetAlignmentToParent: Public(function () { 341 | return this.alignmentToParent; 342 | }), 343 | SetAlignmentToParent: Public(function (value) { 344 | this.alignmentToParent = value; 345 | this.UpdateStyle(); 346 | }), 347 | AlignmentToParent: Public.Property({}), 348 | }); 349 | 350 | /******************************************************************************** 351 | Package 352 | ********************************************************************************/ 353 | 354 | return { 355 | MinSizeLimitation: MinSizeLimitation, 356 | Layout: Layout, 357 | SiteLayout: SiteLayout, 358 | WindowLayout: WindowLayout, 359 | BoundsLayout: BoundsLayout, 360 | } 361 | }); -------------------------------------------------------------------------------- /Script/GacUI/Layout/Misc.js: -------------------------------------------------------------------------------- 1 | Packages.Define("GacUI.Layout.Misc", ["Class", "GacUI.Types", "GacUI.Layout.Basic"], function (__injection__) { 2 | eval(__injection__); 3 | 4 | function FQN(name) { 5 | return "vl::presentation::compositions::Gui" + name + "Composition"; 6 | } 7 | 8 | /******************************************************************************** 9 | GuiSideAlignedComposition 10 | ********************************************************************************/ 11 | 12 | var SideAlignedLayout = Class(FQN("SideAligned"), SiteLayout, { 13 | }); 14 | 15 | /******************************************************************************** 16 | GuiPartialViewComposition 17 | ********************************************************************************/ 18 | 19 | var PartialViewLayout = Class(FQN("PartialView"), SiteLayout, { 20 | }); 21 | 22 | /******************************************************************************** 23 | Package 24 | ********************************************************************************/ 25 | 26 | return { 27 | SideAlignedLayout: SideAlignedLayout, 28 | PartialViewLayout: PartialViewLayout, 29 | } 30 | }); -------------------------------------------------------------------------------- /Script/GacUI/Layout/Stack.js: -------------------------------------------------------------------------------- 1 | Packages.Define("GacUI.Layout.Stack", ["Class", "GacUI.Types", "GacUI.Layout.Basic"], function (__injection__) { 2 | eval(__injection__); 3 | 4 | function FQN(name) { 5 | return "vl::presentation::compositions::Gui" + name + "Composition"; 6 | } 7 | 8 | /******************************************************************************** 9 | GuiStackComposition 10 | ********************************************************************************/ 11 | 12 | var StackLayout = Class(FQN("Stack"), BoundsLayout, { 13 | }); 14 | 15 | /******************************************************************************** 16 | GuiStackItemComposition 17 | ********************************************************************************/ 18 | 19 | var StackItemLayout = Class(FQN("StackItem"), SiteLayout, { 20 | }); 21 | 22 | /******************************************************************************** 23 | Package 24 | ********************************************************************************/ 25 | 26 | return { 27 | StackLayout: StackLayout, 28 | StackItemLayout: StackItemLayout, 29 | } 30 | }); -------------------------------------------------------------------------------- /Script/GacUI/Layout/Table.js: -------------------------------------------------------------------------------- 1 | Packages.Define("GacUI.Layout.Table", ["Class", "GacUI.Types", "GacUI.Layout.Basic"], function (__injection__) { 2 | eval(__injection__); 3 | 4 | function FQN(name) { 5 | return "vl::presentation::compositions::Gui" + name + "Composition"; 6 | } 7 | 8 | /******************************************************************************** 9 | GuiTableComposition 10 | ********************************************************************************/ 11 | 12 | var TableLayout = Class(FQN("Table"), BoundsLayout, { 13 | }); 14 | 15 | /******************************************************************************** 16 | GuiCellComposition 17 | ********************************************************************************/ 18 | 19 | var CellLayout = Class(FQN("Cell"), SiteLayout, { 20 | }); 21 | 22 | /******************************************************************************** 23 | Package 24 | ********************************************************************************/ 25 | 26 | return { 27 | TableLayout: TableLayout, 28 | CellLayout: CellLayout, 29 | } 30 | }); -------------------------------------------------------------------------------- /Script/GacUI/Types.js: -------------------------------------------------------------------------------- 1 | Packages.Define("GacUI.Types", ["Class"], function (__injection__) { 2 | eval(__injection__); 3 | 4 | var Alignment = Enum("vl::presentation::Alignment", { 5 | Left: 0, 6 | Top: 1, 7 | Center: 2, 8 | Right: 3, 9 | Bottom: 4, 10 | }); 11 | 12 | var TextPos = Struct("vl::presentation::TextPos", { 13 | row: 0, 14 | column: 0, 15 | }); 16 | 17 | var GridPos = Struct("vl::presentation::GridPos", { 18 | row: 0, 19 | column: 0, 20 | }); 21 | 22 | var Point = Struct("vl::presentation::Point", { 23 | x: 0, 24 | y: 0, 25 | }); 26 | 27 | var Size = Struct("vl::presentation::Size", { 28 | cx: 0, 29 | cy: 0, 30 | }); 31 | 32 | var Rect = Struct("vl::presentation::Rect", { 33 | x1: 0, 34 | y1: 0, 35 | x2: 0, 36 | y2: 0, 37 | }); 38 | 39 | var __Hex = "0123456789ABCDEF"; 40 | 41 | function __HexToInt(c) { 42 | var i = c.charCodeAt(0); 43 | if (48 <= i && i <= 57) return i - 48; 44 | if (65 <= i && i <= 70) return i - 55; 45 | throw new Error("\"" + c + "\" is not a valid hex number."); 46 | } 47 | 48 | function __ByteToHex(b) { 49 | if (0 <= b && b <= 255) { 50 | return __Hex[(b / 16) | 0] + __Hex[b % 16]; 51 | } 52 | else { 53 | throw new Error("\"" + b + "\" is out of range [0, 255]."); 54 | } 55 | } 56 | 57 | var __PrintColor = function () { 58 | return "#" + 59 | __ByteToHex(this.r) + 60 | __ByteToHex(this.g) + 61 | __ByteToHex(this.b) + 62 | (this.a == 255 ? "" : __ByteToHex(this.a)) 63 | ; 64 | } 65 | 66 | var __ParseColor = function (text) { 67 | if (text.length != 7 && text.length != 9 && text[0] != '#') { 68 | throw new Error("\"" + text + "\" is not a valid string representation for type \"" + Color.FullName + "\"."); 69 | } 70 | 71 | var color = new Color( 72 | __HexToInt(text[1]) * 16 + __HexToInt(text[2]), 73 | __HexToInt(text[3]) * 16 + __HexToInt(text[4]), 74 | __HexToInt(text[5]) * 16 + __HexToInt(text[6]), 75 | (text.length == 7 ? 255 : __HexToInt(text[7]) * 16 + __HexToInt(text[8])) 76 | ); 77 | return color; 78 | } 79 | 80 | var Color = Struct("vl::presentation::Color", { 81 | r: 0, 82 | g: 0, 83 | b: 0, 84 | a: 255, 85 | }, __PrintColor, __ParseColor); 86 | 87 | var Margin = Struct("vl::presentation::Margin", { 88 | left: 0, 89 | top: 0, 90 | right: 0, 91 | bottom: 0, 92 | }); 93 | 94 | var FontProperties = Struct("vl::presentation::FontProperties", { 95 | fontFamily: "", 96 | size: 0, 97 | bold: false, 98 | italic: false, 99 | underline: false, 100 | strikeline: false, 101 | antialias: true, 102 | verticalAntialias: false, 103 | }); 104 | 105 | return { 106 | Alignment: Alignment, 107 | TextPos: TextPos, 108 | GridPos: GridPos, 109 | Point: Point, 110 | Size: Size, 111 | Rect: Rect, 112 | Color: Color, 113 | Margin: Margin, 114 | FontProperties: FontProperties, 115 | } 116 | }); -------------------------------------------------------------------------------- /Script/Html/Events.js: -------------------------------------------------------------------------------- 1 | /* 2 | API: 3 | AttachGeneralEvent(element, eventName, callback, initialize); 4 | DetachGeneralEvent(element, eventName, callback, finalize); 5 | */ 6 | Packages.Define("Html.Events", ["Class"], function (__injection__) { 7 | eval(__injection__); 8 | 9 | function AttachGeneralEvent(element, eventName, callback, initialize) { 10 | var fieldName = "gacjs_" + eventName + "Handlers"; 11 | var eventContainer = element[fieldName]; 12 | 13 | if (eventContainer === undefined) { 14 | eventContainer = new __Event(); 15 | element[fieldName] = eventContainer; 16 | initialize(eventContainer); 17 | } 18 | return eventContainer.Attach(callback); 19 | } 20 | 21 | function DetachGeneralEvent(element, eventName, handler, finalize) { 22 | var fieldName = "gacjs_" + eventName + "Handlers"; 23 | var eventContainer = element[fieldName]; 24 | 25 | if (eventContainer !== undefined) { 26 | eventContainer.Detach(handler); 27 | 28 | if (eventContainer.IsEmpty()) { 29 | finalize(); 30 | delete element[fieldName]; 31 | } 32 | } 33 | } 34 | 35 | return { 36 | AttachGeneralEvent: AttachGeneralEvent, 37 | DetachGeneralEvent: DetachGeneralEvent, 38 | } 39 | }); -------------------------------------------------------------------------------- /Script/Html/MVC.js: -------------------------------------------------------------------------------- 1 | /* 2 | API: 3 | 4 | class MvcController : INavigationController 5 | { 6 | protected: 7 | virtual object GetModel() { return this; } 8 | virtual void OnLoaded() {} 9 | public: 10 | MvcController(string razorUrl, string renderPageId); 11 | 12 | string RazorUrl { get; } 13 | Razor Razor { get; } 14 | string RazorText { get; } 15 | 16 | void Load(); 17 | } 18 | 19 | Type CreateMvcControllerType(string name, string razorUrl, { property : defaultValue }, additionalDefinitions); 20 | void InitializeMvc(string hashFlag, string rootRazorUrl, string loadingRazorUrl, { property : defaultValue }); 21 | */ 22 | Packages.Define("Html.MVC", ["Class", "Html.Navigation", "Html.Razor", "IO.Resource", "IO.Wildcard", "Html.MVCRazorHelper.Internal"], function (__injection__) { 23 | eval(__injection__); 24 | 25 | /******************************************************************************** 26 | MvcController 27 | ********************************************************************************/ 28 | 29 | var MvcController = Class(PQN("MvcController"), INavigationController, { 30 | 31 | //--------------------------------------------------------------------- 32 | 33 | GetModel: Protected.Virtual(function () { 34 | return this.__ExternalReference; 35 | }), 36 | Model: Public.Property({ readonly: true }), 37 | 38 | razorUrl: Private(null), 39 | GetRazorUrl: Private(function () { 40 | return this.razorUrl; 41 | }), 42 | RazorUrl: Public.Property({ readonly: true }), 43 | 44 | razor: Private(null), 45 | GetRazor: Private(function () { 46 | return this.razor.Razor; 47 | }), 48 | Razor: Public.Property({ readonly: true }), 49 | 50 | GetRazorText: Private(function () { 51 | return this.razor.Text; 52 | }), 53 | RazorText: Public.Property({ readonly: true }), 54 | 55 | renderPageId: Private(null), 56 | GetRenderPageId: Private(function () { 57 | return this.renderPageId; 58 | }), 59 | RenderPageId: Public.Property({ readonly: true }), 60 | 61 | //--------------------------------------------------------------------- 62 | 63 | html: Private(null), 64 | GetHtml: Private(function () { 65 | if (this.html === null) { 66 | try { 67 | SetMvcRenderPageId(this.renderPageId); 68 | this.html = this.Razor(this.GetModel()).RawHtml; 69 | } 70 | catch (ex) { 71 | return "" + ex + ""; 72 | } 73 | } 74 | return this.html; 75 | }), 76 | Html: Public.Property({ readonly: true }), 77 | 78 | //--------------------------------------------------------------------- 79 | 80 | loaded: Private(false), 81 | GetLoaded: Private(function () { 82 | return this.loaded; 83 | }), 84 | Loaded: Public.Property({ readonly: true }), 85 | 86 | OnLoaded: Protected.Virtual(function () { }), 87 | 88 | //--------------------------------------------------------------------- 89 | 90 | razorReadyCallbacks: Private(), 91 | ExecuteAfterRazorReady: Public(function (callback) { 92 | if (this.razor === null) { 93 | this.razorReadyCallbacks.push(callback); 94 | } 95 | else { 96 | callback(); 97 | } 98 | }), 99 | 100 | Load: Public.StrongTyped(__Void, [], function () { 101 | if (this.loaded === true) { 102 | return; 103 | } 104 | 105 | this.loaded = true; 106 | var self = this; 107 | 108 | GetResourceAsync(this.razorUrl).Then(function (razor) { 109 | self.razor = razor; 110 | self.OnLoaded(); 111 | if (self.SubController !== null) { 112 | self.DelayInstallSubControllerPage(); 113 | } 114 | 115 | for (var i = 0; i < self.razorReadyCallbacks.length; i++) { 116 | self.razorReadyCallbacks[i](); 117 | } 118 | self.razorReadyCallbacks = null; 119 | }); 120 | }), 121 | 122 | //--------------------------------------------------------------------- 123 | 124 | ReplaceSubControllerPage: Private(function (html) { 125 | var span = document.getElementById(this.renderPageId); 126 | if (span !== null) { 127 | span.innerHTML = html; 128 | } 129 | }), 130 | 131 | DelayInstallSubControllerPage: Private(function () { 132 | this.ReplaceSubControllerPage(loadingRazor({ Url: this.SubController.RazorUrl }).RawHtml); 133 | 134 | var self = this; 135 | this.SubController.ExecuteAfterRazorReady(function () { 136 | self.InstallSubControllerPage(); 137 | }); 138 | }), 139 | 140 | //--------------------------------------------------------------------- 141 | 142 | InstallSubControllerPage: Private(function () { 143 | this.ReplaceSubControllerPage(this.SubController.Html); 144 | }), 145 | 146 | UninstallSubControllerPage: Private(function () { 147 | this.ReplaceSubControllerPage(""); 148 | }), 149 | 150 | OnSubControllerInstalled: Public.Override.StrongTyped(__Void, [INavigationController], function (controller) { 151 | if (this.loaded) { 152 | this.DelayInstallSubControllerPage(); 153 | } 154 | }), 155 | 156 | OnSubControllerUninstalled: Public.Override.StrongTyped(__Void, [INavigationController], function (controller) { 157 | this.UninstallSubControllerPage(); 158 | }), 159 | 160 | //--------------------------------------------------------------------- 161 | 162 | __Constructor: Public.StrongTyped(__Void, [__String, __String], function (razorUrl, renderPageId) { 163 | this.razorUrl = razorUrl; 164 | this.renderPageId = renderPageId; 165 | this.razorReadyCallbacks = []; 166 | this.Load(); 167 | }), 168 | }); 169 | 170 | /******************************************************************************** 171 | CreateMvcControllerType 172 | ********************************************************************************/ 173 | 174 | function CreateMvcControllerType(name, razorUrl, properties, additionalDefinitions) { 175 | var def = { 176 | __Constructor: Public.StrongTyped(__Void, [], function () { 177 | this.__InitBase(MvcController, [razorUrl, GenerateMvcRenderPageId()]); 178 | }), 179 | }; 180 | 181 | if (properties !== undefined) { 182 | for (var i in properties) { 183 | def[i] = Public(properties[i]); 184 | } 185 | } 186 | 187 | if (additionalDefinitions !== undefined) { 188 | for (var i in additionalDefinitions) { 189 | if (i === "__Constructor") { 190 | throw Error("You cannot define __Constructor in CreateMvcControllerType."); 191 | } 192 | else { 193 | def[i] = additionalDefinitions[i]; 194 | } 195 | } 196 | } 197 | 198 | return Class(name, MvcController, def); 199 | } 200 | 201 | /******************************************************************************** 202 | InitializeMvc 203 | ********************************************************************************/ 204 | 205 | var loadingRazor = null; 206 | 207 | function InitializeMvc(hashFlag, rootRazorUrl, loadingRazorUrl, rootRazorProperties) { 208 | loadingRazor = GetResourceAsync(loadingRazorUrl, false).Result.Razor; 209 | document.body.innerHTML = loadingRazor({ Url: rootRazorUrl }).RawHtml; 210 | 211 | var rootRazorControllerType = CreateMvcControllerType( 212 | PQN("RootMvcRazorController"), 213 | rootRazorUrl, 214 | rootRazorProperties, 215 | { 216 | OnLoaded: Protected.Override(function () { 217 | document.body.innerHTML = this.Html; 218 | }), 219 | }); 220 | InitializeNavigation(hashFlag, rootRazorControllerType); 221 | } 222 | 223 | /******************************************************************************** 224 | RazorResourceDeserializer 225 | ********************************************************************************/ 226 | 227 | var RazorResourceDeserializer = Class(PQN("RazorResourceDeserializer"), IResourceDeserializer, { 228 | GetName: Public.Override(function () { 229 | return "Razor"; 230 | }), 231 | 232 | GetPriorDeserializerName: Public.Override(function () { 233 | return "Text"; 234 | }), 235 | 236 | Deserialize: Public.Override(function (resource) { 237 | return CompileRazor(resource, ["Html.MVCRazorHelper"]); 238 | }), 239 | }); 240 | RegisterDeserializer(new RazorResourceDeserializer()); 241 | RegisterResource(WildcardToRegExp("*.razor.html"), "Razor"); 242 | 243 | /******************************************************************************** 244 | Package 245 | ********************************************************************************/ 246 | 247 | return { 248 | MvcController: MvcController, 249 | CreateMvcControllerType: CreateMvcControllerType, 250 | InitializeMvc: InitializeMvc, 251 | } 252 | }) 253 | 254 | Packages.Define("Html.MVCRazorHelper.Internal", ["Html.RazorHelper"], function (__injection__) { 255 | eval(__injection__); 256 | 257 | var index = 0; 258 | var id = null; 259 | 260 | function GenerateMvcRenderPageId() { 261 | return "HTML_MVC_RENDER_PAGE_ID_" + (++index); 262 | } 263 | 264 | function SetMvcRenderPageId(newId) { 265 | id = newId; 266 | } 267 | 268 | function RenderPage() { 269 | return new RazorHtml(""); 270 | } 271 | 272 | /******************************************************************************** 273 | Package 274 | ********************************************************************************/ 275 | 276 | return { 277 | GenerateMvcRenderPageId: GenerateMvcRenderPageId, 278 | SetMvcRenderPageId: SetMvcRenderPageId, 279 | RenderPage: RenderPage, 280 | } 281 | }) 282 | 283 | Packages.Define("Html.MVCRazorHelper", ["Html.MVCRazorHelper.Internal"], function (__injection__) { 284 | eval(__injection__); 285 | 286 | /******************************************************************************** 287 | Package 288 | ********************************************************************************/ 289 | 290 | return { 291 | RenderPage: RenderPage, 292 | } 293 | }) -------------------------------------------------------------------------------- /Script/Html/ResizeEvent.js: -------------------------------------------------------------------------------- 1 | /* 2 | API: 3 | AttachParentChangedEvent(element, callback); 4 | DetachParentChangedEvent(element, callback); 5 | AttachResizeEvent(element, callback); 6 | DetachResizeEvent(element, callback); 7 | */ 8 | 9 | Packages.Define("Html.ResizeEvent", ["Html.Events", "Html.RunAfterWindowLoaded"], function (__injection__) { 10 | eval(__injection__); 11 | 12 | function AttachConnectionToBodyChangedEvent(element, callback) { 13 | return AttachGeneralEvent(element, "ConnectionToBodyChanged", callback, function (eventContainer) { 14 | 15 | function ElementListContainsElement(records, element) { 16 | for (var i = 0; i < records.length; i++) { 17 | if (records[i] === element) { 18 | return true; 19 | } 20 | } 21 | return false; 22 | } 23 | 24 | function RecordContainsElement(record, element) { 25 | if (ElementListContainsElement(record.addedNodes, element)) { 26 | return true; 27 | } 28 | if (ElementListContainsElement(record.removedNodes, element)) { 29 | return true; 30 | } 31 | return false; 32 | } 33 | 34 | function RecordContainsParentLine(record) { 35 | var current = element; 36 | while (current !== null) { 37 | if (RecordContainsElement(record, current)) { 38 | return true; 39 | } 40 | current = current.parentElement; 41 | } 42 | return false; 43 | } 44 | 45 | var observer = new MutationObserver(function (records) { 46 | function ExecuteEvent() { 47 | eventContainer.Execute(); 48 | } 49 | 50 | if (records.filter(RecordContainsParentLine).length > 0) { 51 | RunAfterWindowLoaded(ExecuteEvent); 52 | } 53 | }); 54 | observer.observe(document.body, { childList: true, subtree: true }); 55 | element.gacjs_BodySubTreeObserver = observer; 56 | }); 57 | } 58 | 59 | function DetachConnectionToBodyChangedEvent(element, handler) { 60 | return DetachGeneralEvent(element, "ConnectionToBodyChanged", handler, function () { 61 | element.gacjs_BodySubTreeObserver.disconnect(); 62 | delete element.gacjs_BodySubTreeObserver; 63 | }); 64 | } 65 | 66 | // This function is enhanced and modified to my coding style from 67 | // https://github.com/marcj/css-element-queries/ 68 | function AttachResizeEvent(element, callback) { 69 | return AttachGeneralEvent(element, "Resize", callback, function (eventContainer) { 70 | 71 | function SetStyle(element, forContainer) { 72 | element.style.position = "absolute"; 73 | element.style.left = "0"; 74 | element.style.top = "0"; 75 | 76 | if (forContainer) { 77 | element.style.right = "0"; 78 | element.style.bottom = "0"; 79 | element.style.overflow = "scroll"; 80 | element.style.zIndex = "-1"; 81 | element.style.visibility = "hidden"; 82 | } 83 | else { 84 | element.style.width = "200%"; 85 | element.style.height = "200%"; 86 | } 87 | 88 | } 89 | 90 | var expand = document.createElement("div"); 91 | SetStyle(expand, true); 92 | 93 | var expandChild = document.createElement("div"); 94 | SetStyle(expandChild, false); 95 | 96 | var shrink = document.createElement("div"); 97 | SetStyle(shrink, true); 98 | 99 | var shrinkChild = document.createElement("div"); 100 | SetStyle(shrinkChild, false); 101 | 102 | expand.appendChild(expandChild); 103 | shrink.appendChild(shrinkChild); 104 | 105 | element.appendChild(expand); 106 | element.appendChild(shrink); 107 | 108 | element.gacjs_ResizeExpand = expand; 109 | element.gacjs_ResizeShrink = shrink; 110 | 111 | var lastWidth = null; 112 | var lastHeight = null; 113 | 114 | function Reset() { 115 | expandChild.style.width = expand.offsetWidth + 10 + "px"; 116 | expandChild.style.height = expand.offsetHeight + 10 + "px"; 117 | expand.scrollLeft = expand.scrollWidth; 118 | expand.scrollTop = expand.scrollHeight; 119 | shrink.scrollLeft = shrink.scrollWidth; 120 | shrink.scrollTop = shrink.scrollHeight; 121 | lastWidth = element.offsetWidth; 122 | lastHeight = element.offsetHeight; 123 | } 124 | 125 | Reset(); 126 | 127 | expand.addEventListener("scroll", function (event) { 128 | if (element.offsetWidth > lastWidth || element.offsetHeight > lastHeight) { 129 | eventContainer.Execute(); 130 | } 131 | Reset(); 132 | }, false); 133 | 134 | shrink.addEventListener("scroll", function (event) { 135 | if (element.offsetWidth < lastWidth || element.offsetHeight < lastHeight) { 136 | eventContainer.Execute(); 137 | } 138 | Reset(); 139 | }, false); 140 | }); 141 | } 142 | 143 | function DetachResizeEvent(element, handler) { 144 | return DetachGeneralEvent(element, "Resize", handler, function () { 145 | element.removeChild(element.gacjs_ResizeExpand); 146 | element.removeChild(element.gacjs_ResizeShrink); 147 | delete element.gacjs_ResizeExpand; 148 | delete element.gacjs_ResizeShrink; 149 | }); 150 | } 151 | 152 | function DetectResize(element, callback) { 153 | var handler = AttachConnectionToBodyChangedEvent(element, function () { 154 | AttachResizeEvent(element, callback); 155 | DetachConnectionToBodyChangedEvent(element, handler); 156 | callback(); 157 | }, false); 158 | } 159 | 160 | return { 161 | AttachConnectionToBodyChangedEvent: AttachConnectionToBodyChangedEvent, 162 | DetachConnectionToBodyChangedEvent: DetachConnectionToBodyChangedEvent, 163 | AttachResizeEvent: AttachResizeEvent, 164 | DetachResizeEvent: DetachResizeEvent, 165 | DetectResize: DetectResize, 166 | } 167 | }); -------------------------------------------------------------------------------- /Script/Html/RunAfterWindowLoaded.js: -------------------------------------------------------------------------------- 1 | /* 2 | API: 3 | AttachParentChangedEvent(element, callback); 4 | DetachParentChangedEvent(element, callback); 5 | AttachResizeEvent(element, callback); 6 | DetachResizeEvent(element, callback); 7 | */ 8 | 9 | Packages.Define("Html.RunAfterWindowLoaded", function () { 10 | 11 | var windowLoaded = false; 12 | var runAfterWindowLoadedFunctions = []; 13 | 14 | window.addEventListener("load", function (event) { 15 | windowLoaded = true; 16 | for (var i = 0; i < runAfterWindowLoadedFunctions.length; i++) { 17 | runAfterWindowLoadedFunctions[i](); 18 | } 19 | runAfterWindowLoadedFunctions = []; 20 | }, false); 21 | 22 | function RunAfterWindowLoaded(func) { 23 | if (windowLoaded === true) { 24 | func(); 25 | } 26 | else { 27 | runAfterWindowLoadedFunctions.push(func); 28 | } 29 | } 30 | 31 | return { 32 | RunAfterWindowLoaded: RunAfterWindowLoaded, 33 | } 34 | }); -------------------------------------------------------------------------------- /Script/IO/Delay.js: -------------------------------------------------------------------------------- 1 | /* 2 | API: 3 | class DelayException 4 | { 5 | object Exception { get; } 6 | } 7 | 8 | type CombinedValue = DelayException | object | Future; 9 | 10 | class Promise 11 | { 12 | void SetResult(object value); 13 | void SetException(object value); 14 | } 15 | 16 | class Future 17 | { 18 | object Result { get; } 19 | Future SucceededThen(delegate CombinedValue (object)); 20 | Future FailedThen(delegate CombinedValue (object)); 21 | Future Then(delegate CombinedValue (object | DelayException)); 22 | Future ContinueWith(delegate CombinedValue (object)); 23 | } 24 | 25 | void PassResultToPromise((object | DelayException | Future), Promise); 26 | {promise:Promise, future:Future} CreateDelay(); 27 | Future CreateEvaluatedFuture(object value); 28 | Future WaitAll(Future[]); 29 | Future<{index:number, result:object}> WaitAny(Future[]); 30 | Future RepeatFuture(delegate Future (), delegate bool continueRepeating(object | DelayException)); 31 | */ 32 | Packages.Define("IO.Delay", ["Class"], function (__injection__) { 33 | eval(__injection__); 34 | 35 | /******************************************************************************** 36 | Delay 37 | ********************************************************************************/ 38 | 39 | var Delay = Class(PQN("Delay"), { 40 | result: Protected(null), 41 | callbacks: Protected(null), 42 | 43 | __Constructor: Public(function () { 44 | this.callbacks = []; 45 | }), 46 | 47 | GetResult: Public(function () { 48 | if (this.callbacks === null) { 49 | return this.result; 50 | } 51 | else { 52 | throw new Error("Result of a delay has not been assigned yet."); 53 | } 54 | }), 55 | SetResult: Public(function (value) { 56 | if (this.callbacks === null) { 57 | throw new Error("Result of a delay can only be assigned once."); 58 | } 59 | else { 60 | this.result = value; 61 | var callbacks = this.callbacks; 62 | this.callbacks = null; 63 | for (var i = 0; i < callbacks.length; i++) { 64 | callbacks[i](this.result); 65 | } 66 | } 67 | }), 68 | Result: Public.Property({}), 69 | 70 | HasResult: Public(function () { 71 | return this.callbacks === null; 72 | }), 73 | 74 | DelayExecute: Public(function (callback) { 75 | if (this.callbacks === null) { 76 | callback(this.result); 77 | } 78 | else { 79 | this.callbacks.push(callback); 80 | } 81 | }) 82 | }); 83 | 84 | /******************************************************************************** 85 | DelayException 86 | ********************************************************************************/ 87 | 88 | var DelayException = Class(PQN("DelayException"), { 89 | exception: Protected(null), 90 | 91 | GetException: Public(function () { 92 | return this.exception; 93 | }), 94 | Exception: Public.Property({ readonly: true }), 95 | 96 | __Constructor: Public(function (exception) { 97 | this.exception = exception; 98 | }) 99 | }); 100 | 101 | /******************************************************************************** 102 | Promise 103 | ********************************************************************************/ 104 | 105 | var Promise = Class(PQN("Promise"), { 106 | delay: Protected(null), 107 | 108 | __Constructor: Public.StrongTyped(__Void, [Delay], function (delay) { 109 | this.delay = delay; 110 | }), 111 | 112 | SetResult: Public(function (value) { 113 | this.delay.Result = value; 114 | }), 115 | 116 | SetException: Public(function (value) { 117 | this.delay.Result = new DelayException(value); 118 | }), 119 | }); 120 | 121 | /******************************************************************************** 122 | Future 123 | ********************************************************************************/ 124 | 125 | function PassResultToPromise(result, promise) { 126 | if (Future.TestType(result)) { 127 | result.Then(function (value) { 128 | PassResultToPromise(value, promise); 129 | }); 130 | } 131 | else if (DelayException.TestType(result)) { 132 | promise.SetException(result.Exception); 133 | } 134 | else { 135 | promise.SetResult(result); 136 | } 137 | } 138 | 139 | var Future = Class(PQN("Future"), function () { 140 | return { 141 | delay: Protected(null), 142 | 143 | __Constructor: Public.StrongTyped(__Void, [Delay], function (delay) { 144 | this.delay = delay; 145 | }), 146 | 147 | GetResult: Public(function () { 148 | return this.delay.Result; 149 | }), 150 | Result: Public.Property({ readonly: true }), 151 | 152 | HasResult: Public(function () { 153 | return this.delay.HasResult(); 154 | }), 155 | 156 | SucceededThen: Public.StrongTyped(Future, [__Function], function (generator) { 157 | var delay = new Delay(); 158 | var promise = new Promise(delay); 159 | var future = new Future(delay); 160 | this.delay.DelayExecute(function (value) { 161 | if (!DelayException.TestType(value)) { 162 | try { 163 | PassResultToPromise(generator(value), promise); 164 | } 165 | catch (ex) { 166 | promise.SetException(ex); 167 | } 168 | } 169 | }); 170 | return future; 171 | }), 172 | 173 | FailedThen: Public.StrongTyped(Future, [__Function], function (generator) { 174 | var delay = new Delay(); 175 | var promise = new Promise(delay); 176 | var future = new Future(delay); 177 | this.delay.DelayExecute(function (value) { 178 | if (DelayException.TestType(value)) { 179 | try { 180 | PassResultToPromise(generator(value.Exception), promise); 181 | } 182 | catch (ex) { 183 | promise.SetException(ex); 184 | } 185 | } 186 | }); 187 | return future; 188 | }), 189 | 190 | Then: Public.StrongTyped(Future, [__Function], function (generator) { 191 | var delay = new Delay(); 192 | var promise = new Promise(delay); 193 | var future = new Future(delay); 194 | this.delay.DelayExecute(function (value) { 195 | try { 196 | PassResultToPromise(generator(value), promise); 197 | } 198 | catch (ex) { 199 | promise.SetException(ex); 200 | } 201 | }); 202 | return future; 203 | }), 204 | 205 | ContinueWith: Public.StrongTyped(Future, [__Function], function (generator) { 206 | var delay = new Delay(); 207 | var promise = new Promise(delay); 208 | var future = new Future(delay); 209 | this.delay.DelayExecute(function (value) { 210 | try { 211 | if (DelayException.TestType(value)) { 212 | throw value.Exception; 213 | } 214 | PassResultToPromise(generator(value), promise); 215 | } 216 | catch (ex) { 217 | promise.SetException(ex); 218 | } 219 | }); 220 | return future; 221 | }), 222 | } 223 | }); 224 | 225 | /******************************************************************************** 226 | CreateDelay / CreateEvaluatedFuture 227 | ********************************************************************************/ 228 | 229 | function CreateDelay() { 230 | var delay = new Delay(); 231 | var promise = new Promise(delay); 232 | var future = new Future(delay); 233 | return { 234 | promise: promise, 235 | future: future, 236 | } 237 | } 238 | 239 | function CreateEvaluatedFuture(value) { 240 | var delay = CreateDelay(); 241 | PassResultToPromise(value, delay.promise); 242 | return delay.future; 243 | } 244 | 245 | /******************************************************************************** 246 | WaitAll 247 | ********************************************************************************/ 248 | 249 | function WaitAll(futures) { 250 | var count = futures.length; 251 | var finished = 0; 252 | var delay = CreateDelay(); 253 | 254 | function OnReady() { 255 | var result = futures.map(function (future) { 256 | return future.Result; 257 | }); 258 | delay.promise.SetResult(result); 259 | } 260 | 261 | for (var i = 0; i < count; i++) { 262 | var future = futures[i]; 263 | if (future.HasResult()) { 264 | finished++; 265 | } 266 | else { 267 | future.Then(function (value) { 268 | finished++; 269 | if (finished === count) { 270 | OnReady(); 271 | } 272 | }); 273 | } 274 | } 275 | 276 | if (finished === count) { 277 | OnReady(); 278 | } 279 | return delay.future; 280 | } 281 | 282 | /******************************************************************************** 283 | WaitAny 284 | ********************************************************************************/ 285 | 286 | function WaitAny(futures) { 287 | var count = futures.length; 288 | var delay = CreateDelay(); 289 | 290 | function OnReady(index) { 291 | var result = { index: index, result: futures[index].Result }; 292 | delay.promise.SetResult(result); 293 | } 294 | 295 | not_ready: { 296 | for (var i = 0; i < count; i++) { 297 | if (futures[i].HasResult()) { 298 | OnReady(i); 299 | break not_ready; 300 | } 301 | else (function () { 302 | var index = i; 303 | futures[i].Then(function (value) { 304 | if (!delay.future.HasResult()) { 305 | OnReady(index); 306 | } 307 | }) 308 | })(); 309 | } 310 | } 311 | 312 | return delay.future; 313 | } 314 | 315 | /******************************************************************************** 316 | RepeatFuture 317 | ********************************************************************************/ 318 | 319 | function RepeatFutureBody(results, delay, generator, continueRepeating) { 320 | var future = generator(); 321 | future.Then(function (value) { 322 | results.push(value); 323 | try { 324 | if (continueRepeating(value)) { 325 | RepeatFutureBody(results, delay, generator, continueRepeating); 326 | } 327 | else { 328 | delay.promise.SetResult(results); 329 | } 330 | } 331 | catch (ex) { 332 | delay.promise.SetException(ex); 333 | } 334 | }) 335 | } 336 | 337 | function RepeatFuture(generator, continueRepeating) { 338 | var results = []; 339 | var delay = CreateDelay(); 340 | RepeatFutureBody(results, delay, generator, continueRepeating); 341 | return delay.future; 342 | } 343 | 344 | /******************************************************************************** 345 | Package 346 | ********************************************************************************/ 347 | 348 | return { 349 | DelayException: DelayException, 350 | PassResultToPromise: PassResultToPromise, 351 | Promise: Promise, 352 | Future: Future, 353 | CreateDelay: CreateDelay, 354 | CreateEvaluatedFuture: CreateEvaluatedFuture, 355 | WaitAll: WaitAll, 356 | WaitAny: WaitAny, 357 | RepeatFuture: RepeatFuture, 358 | } 359 | }) -------------------------------------------------------------------------------- /Script/IO/Resource.js: -------------------------------------------------------------------------------- 1 | /* 2 | API: 3 | interface IResourceDeserializer 4 | { 5 | string Name { get; } 6 | string PriorDeserializerName { get; } 7 | object Deserialize(object resource); 8 | } 9 | 10 | void RegisterDeserializer(IResourceDeserializer deserializer); 11 | void RegisterResource(string fileNamePattern, string deserializerName); 12 | Future> GetResourceAsync(string path, bool async, int maxRetryCount); 13 | */ 14 | Packages.Define("IO.Resource", ["Class", "IO.Delay", "IO.Wildcard"], function (__injection__) { 15 | eval(__injection__); 16 | 17 | /******************************************************************************** 18 | IResourceDeserializer 19 | ********************************************************************************/ 20 | 21 | var IResourceDeserializer = Class(PQN("IResourceDeserializer"), { 22 | GetName: Public.Abstract(), 23 | Name: Public.Property({ readonly: true }), 24 | 25 | GetPriorDeserializerName: Public.Virtual(function () { 26 | return null; 27 | }), 28 | PriorDeserializerName: Public.Property({ readonly: true }), 29 | 30 | Deserialize: Public.Virtual(function (resource) { 31 | return resource; 32 | }), 33 | }); 34 | 35 | /******************************************************************************** 36 | Text 37 | ********************************************************************************/ 38 | 39 | var TextResourceDeserializer = Class(PQN("TextResourceDeserializer"), IResourceDeserializer, { 40 | GetName: Public.Override(function () { 41 | return "Text"; 42 | }), 43 | 44 | Deserialize: Public.Override(function (resource) { 45 | return resource; 46 | }), 47 | }); 48 | 49 | /******************************************************************************** 50 | XML 51 | ********************************************************************************/ 52 | 53 | var domParser = new DOMParser(); 54 | 55 | var XmlResourceDeserializer = Class(PQN("XmlResourceDeserializer"), IResourceDeserializer, { 56 | GetName: Public.Override(function () { 57 | return "Xml"; 58 | }), 59 | 60 | GetPriorDeserializerName: Public.Override(function () { 61 | return "Text"; 62 | }), 63 | 64 | Deserialize: Public.Override(function (resource) { 65 | return domParser.parseFromString(resource, "text/xml"); 66 | }), 67 | }); 68 | 69 | /******************************************************************************** 70 | Json 71 | ********************************************************************************/ 72 | 73 | var JsonResourceDeserializer = Class(PQN("JsonResourceDeserializer"), IResourceDeserializer, { 74 | GetName: Public.Override(function () { 75 | return "Json"; 76 | }), 77 | 78 | GetPriorDeserializerName: Public.Override(function () { 79 | return "Text"; 80 | }), 81 | 82 | Deserialize: Public.Override(function (resource) { 83 | return JSON.parse(resource); 84 | }), 85 | }); 86 | 87 | /******************************************************************************** 88 | API 89 | ********************************************************************************/ 90 | 91 | deserializers = {}; 92 | resourcePatterns = []; 93 | staticResources = {}; 94 | 95 | /******************************************************************************** 96 | RegisterDeserializer 97 | ********************************************************************************/ 98 | 99 | function RegisterDeserializer(deserializer) { 100 | IResourceDeserializer.RequireType(deserializer); 101 | if (deserializers.hasOwnProperty(deserializer.Name)) { 102 | throw new Error("Resource deserializer \"" + deserializer.Name + "\" already exists."); 103 | } 104 | 105 | var prior = deserializer.PriorDeserializerName; 106 | if (prior !== null && !deserializers.hasOwnProperty(prior)) { 107 | throw new Error("Resource deserializer \"" + prior + "\" does not exist."); 108 | } 109 | 110 | deserializers[deserializer.Name] = deserializer; 111 | } 112 | 113 | /******************************************************************************** 114 | RegisterResource 115 | ********************************************************************************/ 116 | 117 | function RegisterResource(fileNamePattern, deserializerName) { 118 | if (!deserializers.hasOwnProperty(deserializerName)) { 119 | throw new Error("Resource deserializer \"" + deserializerName + "\" does not exist."); 120 | } 121 | resourcePatterns.push({ pattern: fileNamePattern, name: deserializerName }); 122 | } 123 | 124 | /******************************************************************************** 125 | GetResourceAsync 126 | ********************************************************************************/ 127 | 128 | function DeserializeResourceByName(deserializerName, text, result) { 129 | var resource = result[deserializerName]; 130 | if (resource === undefined) { 131 | try { 132 | var deserializer = deserializers[deserializerName]; 133 | if (deserializer.PriorDeserializerName === null) { 134 | resource = deserializer.Deserialize(text); 135 | } 136 | else { 137 | var priorResource = DeserializeResourceByName(deserializer.PriorDeserializerName, text, result); 138 | if (priorResource === null) { 139 | throw Error("Unable to deserialize the resource as \"" + deserializerName + "\" because the deserialization of \"" + deserializer.PriorDeserializerName + "\" failed."); 140 | } 141 | resource = deserializer.Deserialize(priorResource); 142 | } 143 | } 144 | catch (ex) { 145 | resource = ex; 146 | } 147 | result[deserializerName] = resource; 148 | } 149 | return resource instanceof Error ? null : resource; 150 | } 151 | 152 | function DeserializeResource(path, text, result) { 153 | var index = path.lastIndexOf("/"); 154 | if (index !== -1) { 155 | path = path.substring(index + 1, path.length); 156 | } 157 | 158 | for (var i = 0; i < resourcePatterns.length; i++) { 159 | var pattern = resourcePatterns[i]; 160 | var match = pattern.pattern.exec(path); 161 | if (match !== null && match[0] === path) { 162 | DeserializeResourceByName(pattern.name, text, result); 163 | } 164 | } 165 | } 166 | 167 | function GetResourceRetryOnceAsync(path, async) { 168 | var delay = CreateDelay(); 169 | var xhr = new XMLHttpRequest(); 170 | 171 | xhr.onreadystatechange = function () { 172 | if (xhr.readyState === XMLHttpRequest.DONE) { 173 | if (xhr.status === 200) { 174 | var result = {}; 175 | DeserializeResource(path, xhr.responseText, result); 176 | delay.promise.SetResult(result); 177 | } 178 | else { 179 | delay.promise.SetException(xhr.status); 180 | } 181 | } 182 | } 183 | 184 | xhr.open("GET", path, async); 185 | xhr.send(null); 186 | return delay.future; 187 | } 188 | 189 | function GetResourceAsync(path, async, maxRetryCount) { 190 | if (async === undefined) { 191 | async = true; 192 | } 193 | if (maxRetryCount === undefined) { 194 | maxRetryCount = 3; 195 | } 196 | var paths = path.split("/"); 197 | for (var i = 0; i < paths.length; i++) { 198 | paths[i] = encodeURIComponent(paths[i]); 199 | } 200 | path = paths.join("/"); 201 | 202 | var future = staticResources[path]; 203 | if (future === undefined) { 204 | var counter = 0; 205 | 206 | function generator() { 207 | return GetResourceRetryOnceAsync(path, async); 208 | } 209 | 210 | function continueRepeating(value) { 211 | return DelayException.TestType(value) && ++counter === maxRetryCount; 212 | } 213 | 214 | future = RepeatFuture(generator, continueRepeating).ContinueWith(function (value) { 215 | return value[value.length - 1]; 216 | }); 217 | staticResources[path] = future; 218 | } 219 | return future; 220 | } 221 | 222 | /******************************************************************************** 223 | Package 224 | ********************************************************************************/ 225 | 226 | RegisterDeserializer(new TextResourceDeserializer()); 227 | RegisterDeserializer(new XmlResourceDeserializer()); 228 | RegisterDeserializer(new JsonResourceDeserializer()); 229 | RegisterResource(WildcardToRegExp("*.txt"), "Text"); 230 | RegisterResource(WildcardToRegExp("*.xml"), "Xml"); 231 | RegisterResource(WildcardToRegExp("*.json"), "Json"); 232 | 233 | return { 234 | IResourceDeserializer: IResourceDeserializer, 235 | RegisterDeserializer: RegisterDeserializer, 236 | RegisterResource: RegisterResource, 237 | GetResourceAsync: GetResourceAsync, 238 | } 239 | }) -------------------------------------------------------------------------------- /Script/IO/Wildcard.js: -------------------------------------------------------------------------------- 1 | /* 2 | API: 3 | RegExp WildcardToRegExp(string wildcard); 4 | */ 5 | Packages.Define("IO.Wildcard", function (__injection__) { 6 | eval(__injection__); 7 | 8 | function WildcardToRegExp(wildcard) { 9 | var regex = ""; 10 | for (var i = 0; i < wildcard.length; i++) { 11 | var c = wildcard[i]; 12 | switch (c) { 13 | case "*": 14 | regex += ".*"; 15 | break; 16 | case "?": 17 | regex += "."; 18 | break; 19 | case "(": case ")": 20 | case "[": case "]": 21 | case "{": case "}": 22 | case "*": case "+": case "?": case ".": 23 | case "$": case "^": 24 | case "\\": case "/": 25 | regex += "\\" + c; 26 | break; 27 | default: 28 | regex += c; 29 | } 30 | } 31 | return new RegExp(regex); 32 | } 33 | 34 | return { 35 | WildcardToRegExp: WildcardToRegExp, 36 | } 37 | }) -------------------------------------------------------------------------------- /Script/Package.js: -------------------------------------------------------------------------------- 1 | /* 2 | API: 3 | ================================================================================ 4 | 5 | Packages.EnabledRegistering 6 | Packages.Types[fullName] 7 | Packages.Packages[fullName] 8 | Packages.RegisterType(type); 9 | 10 | var package = Packages.Define(fullName, function() { 11 | return { 12 | ExportedSymbol: value, 13 | }; 14 | }); 15 | 16 | var package = Packages.Define(fullName, [dependency1, dependency2, ...], function(__injection__) { 17 | eval(__injection__); 18 | 19 | return { 20 | ExportedSymbol: value, 21 | }; 22 | }); 23 | 24 | var package = Packages.Require(fullName); 25 | eval(Packages.Inject([package1, package2, ...], forceInject)); 26 | */ 27 | 28 | /////////////////////////////////////////////////////////////// 29 | 30 | function Packages() { 31 | } 32 | 33 | Object.defineProperty(Packages, "EnabledRegistering", { 34 | configurable: false, 35 | enumerable: true, 36 | writable: true, 37 | value: true, 38 | }); 39 | 40 | Object.defineProperty(Packages, "Types", { 41 | configurable: false, 42 | enumerable: true, 43 | writable: false, 44 | value: {}, 45 | }); 46 | 47 | Object.defineProperty(Packages, "Packages", { 48 | configurable: false, 49 | enumerable: true, 50 | writable: false, 51 | value: {}, 52 | }); 53 | 54 | Object.defineProperty(Packages, "__PackageDefinitions", { 55 | configurable: false, 56 | enumerable: true, 57 | writable: false, 58 | value: {}, 59 | }); 60 | 61 | Object.defineProperty(Packages, "RegisterType", { 62 | configurable: false, 63 | enumerable: true, 64 | writable: false, 65 | value: function (type) { 66 | if (Packages.EnabledRegistering) { 67 | if (Packages.Types.hasOwnProperty(type.FullName)) { 68 | throw new Error("Type \"" + type.FullName + "\" has already been registered."); 69 | } 70 | Packages.Types[type.FullName] = type; 71 | } 72 | } 73 | }); 74 | 75 | Object.defineProperty(Packages, "__PreparePackage", { 76 | configurable: false, 77 | enumerable: true, 78 | writable: false, 79 | value: function (fullName) { 80 | if (!Packages.__PackageDefinitions.hasOwnProperty(fullName)) { 81 | Packages.__PackageDefinitions[fullName] = { 82 | ReverseDependencies: [], 83 | } 84 | } 85 | } 86 | }); 87 | 88 | Object.defineProperty(Packages, "__TryLoadPackage", { 89 | configurable: false, 90 | enumerable: true, 91 | writable: false, 92 | value: function (fullName) { 93 | var def = Packages.__PackageDefinitions[fullName]; 94 | if (def === undefined) return; 95 | if (def.Loaded === undefined || def.Loaded === true) return; 96 | if (def.Counter < def.RequiredCounter) return; 97 | 98 | def.Loaded = true; 99 | def.Constructor(fullName); 100 | for (var i = 0; i < def.ReverseDependencies.length; i++) { 101 | var name = def.ReverseDependencies[i]; 102 | var rdep = Packages.__PackageDefinitions[name]; 103 | rdep.Counter++; 104 | Packages.__TryLoadPackage(name); 105 | } 106 | } 107 | }); 108 | 109 | Object.defineProperty(Packages, "Define", { 110 | configurable: false, 111 | enumerable: true, 112 | writable: false, 113 | value: function () { 114 | var needInject = arguments.length === 3; 115 | var fullName = arguments[0]; 116 | var dependencies = needInject ? arguments[1] : []; 117 | var constructor = needInject ? arguments[2] : arguments[1]; 118 | 119 | for (var i = 0; i < dependencies.length; i++) { 120 | Packages.__PreparePackage(dependencies[i]); 121 | } 122 | Packages.__PreparePackage(fullName); 123 | 124 | var def = Packages.__PackageDefinitions[fullName]; 125 | if (def.Loaded !== undefined) { 126 | throw new Error("Required package \"" + fullName + "\" already exists."); 127 | } 128 | 129 | for (var i = 0; i < dependencies.length; i++) { 130 | Packages.__PackageDefinitions[dependencies[i]].ReverseDependencies.push(fullName); 131 | } 132 | 133 | def.Dependencies = dependencies; 134 | def.Loaded = false; 135 | def.Counter = 0; 136 | def.RequiredCounter = dependencies.length; 137 | def.Constructor = function (fullName) { 138 | var pkg = {}; 139 | Packages.Packages[fullName] = pkg; 140 | 141 | var obj = constructor(Packages.Inject(dependencies) + "function PQN(name){ return \"<" + fullName + ">::\" + name; }"); 142 | for (var i in obj) { 143 | if (pkg.hasOwnProperty(i)) { 144 | throw new Error("Package \"" + fullName + "\" has already exported symbol \"" + i + "\"."); 145 | } 146 | pkg[i] = obj[i]; 147 | } 148 | 149 | for (var i in pkg) { 150 | var symbol = pkg[i]; 151 | if (symbol.__ForceLoad !== undefined) { 152 | symbol.__ForceLoad(); 153 | } 154 | } 155 | } 156 | 157 | for (var i = 0; i < dependencies.length; i++) { 158 | var dependency = Packages.__PackageDefinitions[dependencies[i]]; 159 | if (dependency.Loaded === true) { 160 | def.Counter++; 161 | } 162 | } 163 | 164 | for (var i in Packages.__PackageDefinitions) { 165 | Packages.__TryLoadPackage(i); 166 | } 167 | } 168 | }); 169 | 170 | Object.defineProperty(Packages, "Require", { 171 | configurable: false, 172 | enumerable: true, 173 | writable: false, 174 | value: function (fullName) { 175 | if (!Packages.Packages.hasOwnProperty(fullName)) { 176 | var def = Packages.__PackageDefinitions[fullName]; 177 | if (def === undefined) { 178 | throw new Error("Required package \"" + fullName + "\" does not exist."); 179 | } 180 | else if (def.Loaded === undefined) { 181 | throw new Error("Required package \"" + fullName + "\" has not loaded because the required javascript file has not been specified."); 182 | } 183 | else { 184 | throw new Error("Required package \"" + fullName + "\" has not loaded because some of its dependencies is not ready."); 185 | } 186 | } 187 | return Packages.Packages[fullName]; 188 | } 189 | }); 190 | 191 | Object.defineProperty(Packages, "Inject", { 192 | configurable: false, 193 | enumerable: true, 194 | writable: false, 195 | value: function (names, forceInject) { 196 | var symbols = {}; 197 | 198 | for (var i = 0; i < names.length; i++) { 199 | var name = names[i]; 200 | var pkg = Packages.Require(name); 201 | for (var j in pkg) { 202 | if (symbols.hasOwnProperty(j)) { 203 | throw new Error("Duplicate name \"" + j + "\" in specified packages."); 204 | } 205 | symbols[j] = pkg[j]; 206 | } 207 | } 208 | 209 | var code = ""; 210 | 211 | if (!forceInject) { 212 | for (var i in names) { 213 | var name = names[i]; 214 | var pkg = Packages.Require(name); 215 | for (var j in pkg) { 216 | code += "if (" + j + " !== undefined) throw new Error(\"Name \\\"" + j + "\\\" already exists.\");\r\n"; 217 | } 218 | } 219 | } 220 | 221 | for (var i in names) { 222 | var name = names[i]; 223 | var pkg = Packages.Require(name); 224 | for (var j in pkg) { 225 | code += "var " + j + " = Packages.Packages[" + JSON.stringify(name) + "][" + JSON.stringify(j) + "];\r\n"; 226 | } 227 | } 228 | 229 | return code; 230 | } 231 | }); 232 | 233 | Object.seal(Packages); -------------------------------------------------------------------------------- /Script/Test.js: -------------------------------------------------------------------------------- 1 | /* 2 | API: 3 | Assert(expression); 4 | EmptyCase(); 5 | 6 | TestCase(name, function() { 7 | // test case 8 | }); 9 | 10 | SummaryTest(); 11 | */ 12 | 13 | Packages.Define("Test", function () { 14 | 15 | function Assert(code) { 16 | if (!code) throw new Error("Fuck"); 17 | } 18 | 19 | var __passedCases = 0; 20 | var __failedCases = 0; 21 | var __emptyCases = 0; 22 | 23 | function TestCase(name, code) { 24 | console.debug("Running: " + name); 25 | 26 | var div = document.createElement("div"); 27 | div.appendChild(document.createTextNode(name)); 28 | document.body.appendChild(div); 29 | 30 | try { 31 | Packages.EnabledRegistering = false; 32 | code(); 33 | div.setAttribute("style", "color: green;"); 34 | __passedCases++; 35 | } 36 | catch (ex) { 37 | if (ex.message === "") { 38 | div.setAttribute("style", "color: purple;"); 39 | __emptyCases++; 40 | } 41 | else { 42 | div.setAttribute("style", "color: red;"); 43 | __failedCases++; 44 | code(); 45 | } 46 | } 47 | finally { 48 | Packages.EnabledRegistering = true; 49 | } 50 | } 51 | 52 | function EmptyCase() { 53 | throw new Error(""); 54 | } 55 | 56 | function SummaryTest() { 57 | var container = document.createElement("div"); 58 | container.setAttribute("style", "margin-top: 1.5em;"); 59 | { 60 | var div = document.createElement("div"); 61 | div.appendChild(document.createTextNode("==================================================")); 62 | div.setAttribute("style", "color: gray;"); 63 | container.appendChild(div); 64 | } 65 | { 66 | var div = document.createElement("div"); 67 | div.appendChild(document.createTextNode("Passed: " + __passedCases)); 68 | div.setAttribute("style", "color: green; float: left"); 69 | container.appendChild(div); 70 | } 71 | { 72 | var div = document.createElement("div"); 73 | div.appendChild(document.createTextNode("\u00A0")); 74 | div.setAttribute("style", "min-width: 4em; float: left"); 75 | container.appendChild(div); 76 | } 77 | { 78 | var div = document.createElement("div"); 79 | div.appendChild(document.createTextNode("Failed: " + __failedCases)); 80 | div.setAttribute("style", "color: red; float: left"); 81 | container.appendChild(div); 82 | } 83 | { 84 | var div = document.createElement("div"); 85 | div.appendChild(document.createTextNode("\u00A0")); 86 | div.setAttribute("style", "min-width: 4em; float: left"); 87 | container.appendChild(div); 88 | } 89 | { 90 | var div = document.createElement("div"); 91 | div.appendChild(document.createTextNode("Empty: " + __emptyCases)); 92 | div.setAttribute("style", "color: purple; float: left"); 93 | container.appendChild(div); 94 | } 95 | { 96 | var div = document.createElement("div"); 97 | div.setAttribute("style", "clear: both"); 98 | container.appendChild(div); 99 | } 100 | document.body.appendChild(container); 101 | } 102 | 103 | return { 104 | Assert: Assert, 105 | TestCase: TestCase, 106 | EmptyCase: EmptyCase, 107 | SummaryTest: SummaryTest, 108 | }; 109 | }); -------------------------------------------------------------------------------- /Test/MVC/Home.razor.html: -------------------------------------------------------------------------------- 1 |

2 | Eam meliore maiestatis id, ne animal commodo definitiones per. Epicurei facilisis vix ne, in vidit vidisse alienum vix. Mei admodum feugait et, vel atqui aeterno hendrerit ei, prima electram abhorreant vel ne. Suas summo repudiare no eam. Modo rebum abhorreant pri ex. Et fabellas maiestatis scriptorem est. 3 | 4 | Ne ullum simul iisque mei, cu eos harum perpetua. At agam legimus sea. Eros posse mediocrem et has, at mucius quodsi recteque has. Diam copiosae placerat mel et, per id perpetua principes. Ad eum euismod tincidunt omittantur. An velit lucilius euripidis est, doctus epicuri reprehendunt ne vis. 5 | 6 | At veritus apeirian repudiare mei. Nam te atqui sonet hendrerit, maiorum suscipiantur in sit. In eos aliquam maiorum epicuri, lucilius molestiae ei vel, cum sale percipit ut. Sea ex debitis pertinax percipitur, malis paulo consequat in vix, meis omnis explicari quo et. Voluptua disputando vim ea. Homero fabellas detraxit est et, cu vix tempor tractatos salutandi. 7 |

-------------------------------------------------------------------------------- /Test/MVC/Loading.razor.html: -------------------------------------------------------------------------------- 1 | Loading @model.Url ... -------------------------------------------------------------------------------- /Test/MVC/Post_1.razor.html: -------------------------------------------------------------------------------- 1 |

Per consul alienum an

2 |

3 | Per consul alienum an, te vel falli possim scaevola. Quo adhuc abhorreant omittantur ea. Nam no malis ullum, ad dolore offendit constituto qui. Eu sit mazim aperiam officiis. Putent molestiae nam no. Id eum alia partiendo, eum erat efficiendi in, et eruditi equidem fierent vis. 4 | 5 | In similique disputationi ius. Odio interpretaris mei id, ea civibus intellegat usu, pri decore aliquam te. Ad nam nibh option, eam modo errem saperet id. Ne eius etiam periculis mel, ad eam dicit eripuit, te cum vitae labores docendi. 6 | 7 | Te tempor dolores duo, stet magna equidem an sea. Eu ignota diceret nec. Vix ex tollit bonorum. Nec ei utinam ancillae oportere, sea veri ceteros maluisset at. Eum ne vocibus appetere, cibo mutat ei sed. 8 | 9 | Malis ullum consequuntur et sea, sea sint eligendi te, an sed libris concludaturque. Animal platonem qui ut, ei duo iusto omnesque adipiscing. Nullam quaerendum mea ne, duo ne ipsum fugit. Ad vel dicat laoreet probatus, cu nisl labore mea. 10 | 11 | Nam ullum utroque perfecto eu. Mel no sint denique invidunt, vivendo volutpat mea an, nam copiosae reformidans et. His graece mnesarchum in, ex movet nobis nonumes mea. Per probatus voluptatum te, error placerat pri an. Graeco invidunt inimicus his no, virtute assueverit an est, mazim perpetua delicatissimi vel no. 12 | 13 | Ex mel amet ceteros, persius detraxit erroribus ad eum, nec ludus partiendo adipiscing at. Aliquip corpora ancillae sed te, ex eos iriure propriae mediocrem. Nonumes veritus voluptatibus duo ea, no qui inermis accusata tractatos, sit eu esse quando verterem. Eum id homero repudiandae consequuntur, solum populo luptatum sit et, voluptua lucilius cum te. Graeco assueverit ex vim. Pro aperiri phaedrum pericula te. 14 | 15 | Usu ut paulo ludus lucilius, eu populo possit eum, at homero libris officiis eum. Te sumo delectus qualisque mei. Congue alterum et est, fabulas ceteros mei an. An sea sumo nullam patrioque, falli mazim at vim. 16 | 17 | His ea vitae prompta salutatus, vim natum audire ancillae id. No nulla docendi vis, cu partiendo repudiare quo. Populo adipisci splendide mea eu, verear offendit sit cu, vel in dolor civibus sententiae. Utinam mollis saperet ex eum. 18 | 19 | Ei est constituto efficiantur. Ad autem docendi pericula vix. Albucius mediocritatem at sit. Nam omnis comprehensam ea. 20 | 21 | Dignissim argumentum referrentur te nec, id qui diceret pericula iracundia. At mel unum eripuit reprehendunt, in eam ignota audire intellegam. Cu vel nemore rationibus, mei case inani putent ea, ex nemore mollis mel. Id duo nulla tractatos, mei ullum tantas expetenda id, te sint accusamus vix. Et pri doctus vulputate, vel in omnis scripserit. Ea suas probatus platonem vel, brute alienum eam ut. 22 |

-------------------------------------------------------------------------------- /Test/MVC/Post_2.razor.html: -------------------------------------------------------------------------------- 1 |

Vim id semper qualisque

2 |

3 | Vim id semper qualisque, detraxit rationibus quaerendum vim ut. Eu semper molestiae sententiae quo, at eam vitae consetetur, usu commodo verterem no. Quo mazim integre habemus no. Ad est tantas iriure voluptaria, volumus apeirian posidonium has in. Mea lucilius qualisque id, populo mnesarchum no vim. Id vix falli hendrerit efficiendi, ut ornatus reprehendunt sed. Legimus perpetua eu pro. 4 | 5 | Vim nemore definitionem te. Delenit evertitur te vix, et alia dicam philosophia has. Ius agam explicari ei, vim cetero reformidans ad. Eam eu ponderum invenire indoctum, instructior theophrastus cum eu, est nullam essent scriptorem ad. Per id cotidieque repudiandae, te sea legimus voluptaria mnesarchum, vidisse indoctum consequat te eum. Sed labore feugiat ei, ut usu summo tamquam. 6 | 7 | Eu vel clita causae patrioque, ad amet singulis forensibus eos. Id duo viris quando dissentiunt, odio novum quidam qui ne, quidam dolorum salutatus an eam. At per prompta facilisis scribentur, in modo quas ius. Ei vim tantas alterum molestie, eu tamquam facilis eam. Et justo facilisis scripserit his, fugit similique cum in. 8 | 9 | In mea audiam splendide constituam, mei at clita delectus, usu at sale regione. Sit in numquam feugiat. Vix graeci argumentum id, quo dicit aperiri at. Quodsi adolescens ei qui. Duo ipsum latine te, eam et hinc ocurreret. 10 | 11 | An pri wisi lucilius volutpat. Eu ius meis novum molestiae, adversarium philosophia ei vis. Quidam essent indoctum eu sit, nulla dolores sit id. No case primis pro. 12 | 13 | Omnes petentium patrioque no sit, sit id ipsum quaerendum. Eros dissentias in per. Qui ut eruditi scripserit, primis dolorem evertitur ut vix. Eligendi appareat intellegebat ut has. Quot solet appetere in quo, quot liber id eos. Pri id quaeque cotidieque, congue dolores adipisci mea ex. Placerat disputando ne pri, per vidisse delectus reprimique ea. 14 | 15 | Mei corpora incorrupte te. His prompta menandri persequeris id. Vim ex oratio perpetua, tation discere inimicus duo id. Dicit admodum albucius nec an, et summo verear maiestatis vis, vitae instructior conclusionemque an nam. Cu erant percipit sit, cu sed eirmod sapientem. 16 | 17 | Pro elitr aeterno petentium at. Ad saepe urbanitas mel, ei cum habeo intellegat, at est verear aperiri ancillae. Cu eius vulputate consectetuer sed, usu petentium voluptatibus ut, vim ad etiam admodum definiebas. Eos nulla aeterno menandri id, partiendo intellegat reformidans qui cu, mei ei ubique tamquam dolorum. 18 | 19 | Nostrum liberavisse cu sea, vis ei nonumes alienum eleifend, in dicant admodum qui. Per putant diceret disputando et, sanctus quaestio platonem at mei, quot utamur platonem id sea. Eu ponderum similique usu. Nostrud corpora sed ei, pri tollit timeam et. His sale repudiandae in, an verterem ullamcorper sit. Erat abhorreant ne pro. 20 | 21 | Cu vix erat omittantur. His errem dictas efficiendi at, novum nullam disputando te eam, vel eu cetero molestie imperdiet. Vel ut hinc mandamus, ei malorum maiestatis vix, ei elitr eruditi salutandi sea. Cetero equidem vim ea, verear fabulas similique ei eam. Cum an duis dolore, vix ne salutatus concludaturque. 22 |

-------------------------------------------------------------------------------- /Test/MVC/Post_3.razor.html: -------------------------------------------------------------------------------- 1 |

Pro ei aliquid offendit concludaturque

2 |

3 | Pro ei aliquid offendit concludaturque, solum bonorum fuisset ea pro. His epicuri adipisci cu, est facer populo ea. Quo at stet docendi urbanitas. Splendide intellegam contentiones ea pri, ad mandamus petentium sea. 4 | 5 | Meis interesset eos ex, pro deleniti lobortis conclusionemque no. Vix an exerci epicuri, ne iusto facilisi usu, sit ut summo nonumes conceptam. Epicurei vulputate an vix. Cu mea dicta nostrum urbanitas. Erant sonet nec ei, ad sit prima consequuntur, ea vim molestiae delicatissimi. Et iuvaret utroque pro, eleifend recteque mnesarchum in vix, veri discere intellegat te pri. 6 | 7 | Putent numquam bonorum mei id, id tollit accusata petentium nam. Cum no ponderum partiendo, nisl noluisse antiopam te eos, sumo tota officiis ei quo. Probo eripuit est ea. Porro postulant suavitate nec et, et aeterno constituto concludaturque vim, vel diam audiam partiendo cu. 8 | 9 | Cu vis hinc exerci, interesset referrentur cum no. Vel porro gubergren deterruisset et, est an illum reprehendunt. Et eius meis minim est, ea mea ullum legere bonorum, solum aliquip persequeris te usu. Deleniti menandri splendide et est. 10 | 11 | Te sit amet graece pertinax. Accumsan liberavisse intellegebat et mei, eum verear convenire no. Mea epicuri hendrerit philosophia ea, ei quis tractatos quo, utinam possit mel ne. Ex vero vulputate mea. 12 | 13 | Graece legendos voluptaria te usu, pro harum possit no. Ius an ullum offendit appellantur, imperdiet democritum elaboraret no vim. Esse eros honestatis vel ne, an nam copiosae consectetuer. Nec modus putent nostro in, quo quis erant deserunt an. Sit euripidis reformidans et, munere splendide elaboraret in eum. 14 | 15 | Vel partem corrumpit ex, quo stet alienum ad. Vim movet integre incorrupte ad, vel ullum recteque qualisque ad. Vim ea vivendo euripidis, nostro insolens temporibus pro ea. Eum ne admodum fabellas, convenire persecuti repudiandae at vix. Cum summo tincidunt adipiscing et, ferri nostrud assueverit duo ut, ei possit nominati eos. 16 | 17 | Vim dolore constituto an, vocent insolens eos ad. Probo expetendis eloquentiam te qui, ius falli scriptorem ut. Ut duo perpetua elaboraret, sonet audiam philosophia in eum. Ea vide placerat indoctum vim, putent verear theophrastus eos ea. Esse habeo perfecto eu eos, te rebum soluta per. 18 | 19 | Et eam copiosae lobortis sententiae, summo patrioque eum an. Eu vix ridens repudiandae. Eos populo iriure detraxit cu. Id ridens aperiri copiosae pro, ea vix graece fastidii. Vide justo iudico vel eu. At mollis singulis per, ut vix soleat dictas vidisse. 20 | 21 | Sed movet mundi ea, putant nonumes officiis est ex, referrentur dissentiunt mea ea. Laoreet laboramus id eam, ei qui modo offendit interpretaris, pro wisi porro in. Ea vis autem omnesque, tacimates vulputate in ius. Laoreet noluisse cu sea. Et probo causae eum, pro audiam persecuti definitionem in. Cu duo dico aperiri. Denique eleifend ut vel. 22 |

-------------------------------------------------------------------------------- /Test/MVC/Posts.razor.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 |
4 |

Per consul alienum an

5 |

Vim id semper qualisque

6 |

Pro ei aliquid offendit concludaturque

7 |
@RenderPage()
-------------------------------------------------------------------------------- /Test/MVC/Root.razor.html: -------------------------------------------------------------------------------- 1 | 2 |

Hi, I am @model.Name. Please click the following hyper-links to test this MVC-razor page.

3 |

Home

4 |

Posts

5 |

@RenderPage()

-------------------------------------------------------------------------------- /Test/a.json: -------------------------------------------------------------------------------- 1 | {"title":"Running GacUI in Browsers!"} -------------------------------------------------------------------------------- /Test/a.txt: -------------------------------------------------------------------------------- 1 | Running GacUI in Browsers! -------------------------------------------------------------------------------- /Test/a.xml: -------------------------------------------------------------------------------- 1 | Running GacUI in Browsers! -------------------------------------------------------------------------------- /TestPage.css: -------------------------------------------------------------------------------- 1 | 2 | body { 3 | font-family: 'Segoe UI'; 4 | font-size: 14px; 5 | } 6 | 7 | .LineDiv:after { 8 | content: " "; 9 | display: block; 10 | clear: both; 11 | } 12 | 13 | .DraggableHandle { 14 | display: block; 15 | width: 10px; 16 | height: 10px; 17 | position: absolute; 18 | cursor: nwse-resize; 19 | border-radius: 5px; 20 | } 21 | 22 | .TabPage table { 23 | margin: 10px; 24 | border-left: 1px solid gray; 25 | border-top: 1px solid gray; 26 | border-spacing: 0px; 27 | border-collapse: separate; 28 | } 29 | 30 | .TabPage th { 31 | text-align: left; 32 | padding: 10px; 33 | border-right: 1px solid gray; 34 | border-bottom: 1px solid gray; 35 | } 36 | 37 | .TabPage td { 38 | text-align: left; 39 | border-right: 1px solid gray; 40 | border-bottom: 1px solid gray; 41 | } 42 | 43 | .TabPage td:after { 44 | content: " "; 45 | display: block; 46 | clear: both; 47 | } 48 | 49 | .TabButtonContainer:after { 50 | content: " "; 51 | display: block; 52 | clear: both; 53 | } 54 | 55 | 56 | .TabButton { 57 | box-shadow: inset 0px 1px 0px 0px #54A3F7; 58 | background: linear-gradient(to bottom, #007DC1 5%, #0061A7 100%); 59 | background-color: #007DC1; 60 | border-radius: 3px; 61 | border: 1px solid #124D77; 62 | display: inline-block; 63 | cursor: pointer; 64 | color: #FFFFFF; 65 | padding: 6px 24px; 66 | text-align: center; 67 | text-decoration: none; 68 | text-shadow: 0px 1px 0px #154682; 69 | margin: 4px; 70 | width: 6em; 71 | display: block; 72 | float: left; 73 | cursor: pointer; 74 | } 75 | 76 | .TabButton:active { 77 | background: linear-gradient(to bottom, #0061A7 5%, #007DC1 100%); 78 | background-color: #0061A7; 79 | } 80 | 81 | .Selected.TabButton { 82 | font-weight: 700; 83 | } 84 | 85 | .Selected.TabButton:before { 86 | content: "<"; 87 | } 88 | 89 | .Selected.TabButton:after { 90 | content: ">"; 91 | } 92 | 93 | .TabPageContainer { 94 | display: block; 95 | position: relative; 96 | } 97 | 98 | .TabPage { 99 | display: block; 100 | position: absolute; 101 | left: 0; 102 | top: 0; 103 | right: 0; 104 | visibility: hidden; 105 | } 106 | 107 | .Selected.TabPage { 108 | visibility: visible; 109 | border: 1px solid red; 110 | } 111 | -------------------------------------------------------------------------------- /TestPage.js: -------------------------------------------------------------------------------- 1 | eval( 2 | Packages.Inject([ 3 | "Test", 4 | "Class", 5 | "Html.ResizeEvent", 6 | "Html.Navigation", 7 | "Html.Razor", 8 | "Html.MVC", 9 | "IO.Delay", 10 | "IO.Resource", 11 | "IO.Wildcard", 12 | "GacUI.Types", 13 | "GacUI.Elements.Interface", 14 | "GacUI.Elements.Basic", 15 | "GacUI.Elements.ColorizedText", 16 | "GacUI.Elements.Document", 17 | "GacUI.Layout.Basic", 18 | "GacUI.Layout.Stack", 19 | "GacUI.Layout.Table", 20 | "GacUI.Layout.Misc"], 21 | true) 22 | ); 23 | 24 | /******************************************************************************** 25 | TabControl 26 | ********************************************************************************/ 27 | 28 | function BuildTabController(name) { 29 | var Controller = Class("::" + name, INavigationController, { 30 | Id: Public(null), 31 | Url: Public(null), 32 | 33 | OnInstalled: Public.Override(function () { 34 | var tabControl = window[this.Id]; 35 | for (var i = 0; i < tabControl.TabButtons.length; i++) { 36 | var tabButton = tabControl.TabButtons[i]; 37 | if (tabButton.getAttribute("data-url") === this.Url) { 38 | ShowTabPage(tabControl, tabButton.TabPage); 39 | break; 40 | } 41 | } 42 | }), 43 | 44 | OnUninstalled: Public.Override(function () { 45 | var tabControl = window[this.Id]; 46 | ShowTabPage(tabControl, null); 47 | }), 48 | }); 49 | return Controller; 50 | } 51 | 52 | var TabRootController = BuildTabController("Root"); 53 | 54 | function ShowTabPage(tabControl, tabPage) { 55 | if (tabControl.CurrentTabPage !== null) { 56 | tabControl.CurrentTabPage.classList.remove("Selected"); 57 | tabControl.CurrentTabPage.TabButton.classList.remove("Selected"); 58 | } 59 | tabControl.CurrentTabPage = tabPage; 60 | if (tabControl.CurrentTabPage !== null) { 61 | tabControl.CurrentTabPage.classList.add("Selected"); 62 | tabControl.CurrentTabPage.TabButton.classList.add("Selected"); 63 | } 64 | } 65 | 66 | function CombineTabPage(tabControl, tabPage, tabButton) { 67 | tabPage.TabControl = tabControl; 68 | tabPage.TabButton = tabButton; 69 | 70 | tabButton.TabPage = tabPage; 71 | if (tabControl.TabControllerType) { 72 | parentControllerType = undefined; 73 | var current = tabButton; 74 | while (current) { 75 | if (current.TabControllerType && current !== tabControl) { 76 | parentControllerType = current.TabControllerType; 77 | break; 78 | } 79 | current = current.parentElement; 80 | } 81 | 82 | var url = tabButton.getAttribute("data-url"); 83 | RegisterNavigationPath( 84 | url, 85 | tabControl.TabControllerType, 86 | { Id: tabControl.id, Url: url }, 87 | parentControllerType 88 | ); 89 | 90 | tabButton.addEventListener("click", function (event) { 91 | var context = GetNavigationContextBefore(tabControl.TabControllerType); 92 | context.push({ type: tabControl.TabControllerType, values: { Id: tabControl.id, Url: url } }); 93 | var path = BuildNavigationPath(context); 94 | NavigateTo(path); 95 | }); 96 | } 97 | else { 98 | tabButton.addEventListener("click", function (event) { 99 | ShowTabPage(tabControl, event.currentTarget.TabPage); 100 | }); 101 | } 102 | } 103 | 104 | function SetupTabControl(tabControl) { 105 | function DirectChild(parent, className) { 106 | var result = []; 107 | var childNodes = parent.childNodes; 108 | for (var i = 0; i < childNodes.length; i++) { 109 | var childNode = childNodes[i]; 110 | if (childNode.className === className) { 111 | result.push(childNode); 112 | } 113 | } 114 | return result; 115 | } 116 | 117 | tabControl.CurrentTabPage = null; 118 | if (tabControl.getAttribute("data-navigation") === "true") { 119 | tabControl.TabControllerType = BuildTabController(tabControl.id); 120 | } 121 | else { 122 | tabControl.TabControllerType = null; 123 | } 124 | 125 | tabControl.TabButtons = DirectChild(DirectChild(tabControl, "TabButtonContainer")[0], "TabButton"); 126 | tabControl.TabPages = DirectChild(DirectChild(tabControl, "TabPageContainer")[0], "TabPage"); 127 | for (var i = 0; i < tabControl.TabButtons.length; i++) { 128 | CombineTabPage(tabControl, tabControl.TabPages[i], tabControl.TabButtons[i]); 129 | } 130 | 131 | if (!tabControl.TabControllerType) { 132 | ShowTabPage(tabControl, tabControl.TabPages[0]); 133 | } 134 | } 135 | 136 | /******************************************************************************** 137 | Draggable Handler 138 | ********************************************************************************/ 139 | 140 | function GetPx(px) { 141 | return +px.substr(0, px.length - 2); 142 | } 143 | 144 | var bodyOnMouseMove = null; 145 | var bodyOnMouseUp = null; 146 | 147 | function TrackMouse(node) { 148 | bodyOnMouseMove = node.data_onMouseMove; 149 | bodyOnMouseUp = node.data_onMouseUp; 150 | DetachMouseEvents(node, false); 151 | } 152 | 153 | function UnTrackMouse(node) { 154 | AttachMouseEvents(node); 155 | bodyOnMouseMove = null; 156 | bodyOnMouseUp = null; 157 | } 158 | 159 | function AttachMouseEvents(node, onMouseDown, onMouseMove, onMouseUp) { 160 | if (onMouseDown) node.data_onMouseDown = onMouseDown; 161 | if (onMouseMove) node.data_onMouseMove = onMouseMove; 162 | if (onMouseUp) node.data_onMouseUp = onMouseUp; 163 | 164 | node.addEventListener("mousedown", node.data_onMouseDown, false); 165 | node.addEventListener("mousemove", node.data_onMouseMove, false); 166 | node.addEventListener("mouseup", node.data_onMouseUp, false); 167 | } 168 | 169 | function DetachMouseEvents(node, removeHandler) { 170 | node.removeEventListener("mousedown", node.data_onMouseDown, false); 171 | node.removeEventListener("mousemove", node.data_onMouseMove, false); 172 | node.removeEventListener("mouseup", node.data_onMouseUp, false); 173 | 174 | if (removeHandler) { 175 | node.data_onMouseDown = undefined; 176 | node.data_onMouseMove = undefined; 177 | node.data_onMouseUp = undefined; 178 | } 179 | } 180 | 181 | function InstallResizer(node, resizeCallback) { 182 | var draggableHandle = document.createElement("div"); 183 | draggableHandle.setAttribute("class", "DraggableHandle"); 184 | draggableHandle.style.right = "1px"; 185 | draggableHandle.style.bottom = "1px"; 186 | draggableHandle.style.backgroundColor = "red"; 187 | node.appendChild(draggableHandle); 188 | 189 | var dragging = false; 190 | var x = 0.0; 191 | var y = 0.0; 192 | 193 | AttachMouseEvents( 194 | draggableHandle, 195 | function (event) { 196 | if (draggableHandle.style.right !== "") { 197 | draggableHandle.style.right = ""; 198 | draggableHandle.style.bottom = ""; 199 | draggableHandle.style.left = (node.offsetWidth - draggableHandle.offsetWidth - 3) + "px"; 200 | draggableHandle.style.top = (node.offsetHeight - draggableHandle.offsetHeight - 3) + "px"; 201 | } 202 | 203 | dragging = true; 204 | x = event.pageX; 205 | y = event.pageY; 206 | TrackMouse(draggableHandle); 207 | }, 208 | function (event) { 209 | if (dragging) { 210 | var dx = event.pageX - x; 211 | var dy = event.pageY - y; 212 | var left = GetPx(draggableHandle.style.left); 213 | var top = GetPx(draggableHandle.style.top); 214 | var width = left + draggableHandle.offsetWidth + 1 + dx; 215 | var height = top + draggableHandle.offsetHeight + 1 + dy; 216 | if (width < 0 || height < 0) { 217 | return; 218 | } 219 | 220 | node.style.minWidth = width + "px"; 221 | node.style.minHeight = height + "px"; 222 | draggableHandle.style.left = left + dx + "px"; 223 | draggableHandle.style.top = top + dy + "px"; 224 | resizeCallback(width, height); 225 | 226 | x = event.pageX; 227 | y = event.pageY; 228 | } 229 | }, 230 | function (event) { 231 | dragging = false; 232 | UnTrackMouse(draggableHandle); 233 | } 234 | ); 235 | } 236 | 237 | function InstallMover(node) { 238 | if (node.style.left === "" || node.style.top === "") { 239 | return; 240 | } 241 | 242 | var draggableHandle = document.createElement("div"); 243 | draggableHandle.setAttribute("class", "DraggableHandle"); 244 | draggableHandle.style.left = "1px"; 245 | draggableHandle.style.top = "1px"; 246 | draggableHandle.style.backgroundColor = "blue"; 247 | node.appendChild(draggableHandle); 248 | 249 | var dragging = false; 250 | var x = 0.0; 251 | var y = 0.0; 252 | 253 | AttachMouseEvents( 254 | draggableHandle, 255 | function (event) { 256 | dragging = true; 257 | x = event.pageX; 258 | y = event.pageY; 259 | TrackMouse(draggableHandle); 260 | }, 261 | function (event) { 262 | if (dragging) { 263 | var dx = event.pageX - x; 264 | var dy = event.pageY - y; 265 | 266 | node.style.left = GetPx(node.style.left) + dx + "px"; 267 | node.style.top = GetPx(node.style.top) + dy + "px"; 268 | 269 | x = event.pageX; 270 | y = event.pageY; 271 | } 272 | }, 273 | function (event) { 274 | dragging = false; 275 | UnTrackMouse(draggableHandle); 276 | } 277 | ); 278 | } 279 | 280 | function InstallDraggableHandlers(node, resizeCallback) { 281 | InstallMover(node); 282 | InstallResizer(node, resizeCallback); 283 | } 284 | 285 | window.addEventListener("mousemove", function (event) { 286 | if (bodyOnMouseMove) { 287 | bodyOnMouseMove(event); 288 | } 289 | }, false); 290 | 291 | window.addEventListener("mouseup", function (event) { 292 | if (bodyOnMouseUp) { 293 | bodyOnMouseUp(event); 294 | } 295 | }, false); 296 | 297 | /******************************************************************************** 298 | Layout Embedder 299 | ********************************************************************************/ 300 | 301 | function CreateLayoutEmbedder(layout, rows, columns) { 302 | if (rows === undefined) rows = 1; 303 | if (columns === undefined) columns = 1; 304 | 305 | var div = document.createElement("div"); 306 | div.style.display = "block"; 307 | div.style.position = "relative"; 308 | div.style.border = "1px solid blue"; 309 | div.style.float = "left"; 310 | div.style.margin = "10px 10px 10px 10px"; 311 | 312 | var child = layout.BoundsHtmlElement; 313 | if (child === undefined) { 314 | child = layout; 315 | } 316 | child.style.position = "relative"; 317 | child.style.width = (columns * 100) + "px"; 318 | child.style.height = (rows * 100) + "px"; 319 | child.style.margin = "10px 10px 10px 10px"; 320 | div.appendChild(child); 321 | 322 | InstallDraggableHandlers(div, function (width, height) { 323 | child.style.width = (width - 20) + "px"; 324 | child.style.height = (height - 20) + "px"; 325 | }); 326 | return div; 327 | } -------------------------------------------------------------------------------- /Wildcard.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Wildcard 5 | 6 | 7 | 8 | 9 | 10 | 18 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /web.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | --------------------------------------------------------------------------------