├── CNAME ├── .gitignore ├── 404.html ├── _includes ├── themes │ ├── awesome │ │ ├── settings.yml │ │ ├── page.html │ │ ├── post.html │ │ └── default.html │ └── twitter │ │ ├── settings.yml │ │ ├── page.html │ │ ├── post.html │ │ └── default.html ├── JB │ ├── sharing │ ├── comments-providers │ │ ├── livefyre │ │ ├── intensedebate │ │ ├── facebook │ │ └── disqus │ ├── analytics │ ├── comments │ ├── analytics-providers │ │ ├── google │ │ ├── getclicky │ │ └── mixpanel │ ├── setup │ ├── tags_list │ ├── categories_list │ ├── liquid_raw │ ├── posts_collate │ └── pages_list └── site │ └── navigation ├── _layouts ├── page.html ├── post.html └── default.html ├── assets ├── images │ ├── tutorial-2 │ │ ├── screen-1.png │ │ └── screen-2.png │ └── tutorial-3 │ │ ├── screen-1.png │ │ └── screen-2.png └── themes │ ├── awesome │ ├── images │ │ ├── arrow-down.png │ │ ├── white-linen.png │ │ ├── octocat-small.png │ │ ├── logo-delimiter.png │ │ ├── awe-flat-icon-logo.png │ │ └── awe-trans-icon-logo.png │ ├── webfonts │ │ ├── 27DDD3_0_0.eot │ │ ├── 27DDD3_0_0.ttf │ │ ├── 27DDD3_0_0.woff │ │ └── MyFontsWebfontsKit.css │ ├── javascripts │ │ └── scale.fix.js │ └── stylesheets │ │ ├── pygment_trac.css │ │ └── styles.css │ └── twitter │ ├── bootstrap │ └── img │ │ ├── glyphicons-halflings.png │ │ └── glyphicons-halflings-white.png │ └── css │ └── style.css ├── sitemap.txt ├── licensing ├── index.md └── licensing-overview.md ├── tutorials ├── index.md ├── tutorial-2-displaying-your-first-page.md ├── tutorial-1-hello-awesomium.md └── tutorial-3-hooking-up-events.md ├── changelogs ├── index.md ├── whats-new-1-7-3.md ├── whats-new-1-7-2.md ├── whats-new-1-7-4.md ├── whats-new-1-7-5.md └── whats-new-1-7-0.md ├── general-use ├── index.md ├── loading-remote-assets.md ├── changing-the-user-agent.md ├── sharing-render-processes-between-web-views.md ├── distributing-awesomium-with-your-application.md ├── reduce-size-of-library.md ├── loading-local-assets.md ├── working-with-windowed-web-views.md ├── handling-child-web-views.md ├── using-web-sessions.md ├── using-data-sources.md ├── using-global-javascript-objects.md ├── porting-to-1-7.md ├── working-with-offscreen-web-views.md ├── declaring-custom-javascript-methods.md ├── introduction-to-web-views.md └── introduction-to-javascript-integration.md ├── getting-started ├── index.md ├── setting-up-on-linux.md ├── setting-up-on-windows.md ├── setting-up-on-macosx.md └── basic-concepts.md ├── index.md ├── atom.xml ├── README.md ├── _plugins └── debug.rb ├── _config.yml └── Rakefile /CNAME: -------------------------------------------------------------------------------- 1 | wiki.awesomium.com -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .DS_Store 3 | -------------------------------------------------------------------------------- /404.html: -------------------------------------------------------------------------------- 1 | Sorry this page does not exist =( 2 | -------------------------------------------------------------------------------- /_includes/themes/awesome/settings.yml: -------------------------------------------------------------------------------- 1 | theme : 2 | name : awesome -------------------------------------------------------------------------------- /_includes/themes/twitter/settings.yml: -------------------------------------------------------------------------------- 1 | theme : 2 | name : twitter -------------------------------------------------------------------------------- /_layouts/page.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 | {% include JB/setup %} 5 | {% include themes/awesome/page.html %} 6 | -------------------------------------------------------------------------------- /_layouts/post.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 | {% include JB/setup %} 5 | {% include themes/awesome/post.html %} 6 | -------------------------------------------------------------------------------- /assets/images/tutorial-2/screen-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/awesomium/wiki/HEAD/assets/images/tutorial-2/screen-1.png -------------------------------------------------------------------------------- /assets/images/tutorial-2/screen-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/awesomium/wiki/HEAD/assets/images/tutorial-2/screen-2.png -------------------------------------------------------------------------------- /assets/images/tutorial-3/screen-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/awesomium/wiki/HEAD/assets/images/tutorial-3/screen-1.png -------------------------------------------------------------------------------- /assets/images/tutorial-3/screen-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/awesomium/wiki/HEAD/assets/images/tutorial-3/screen-2.png -------------------------------------------------------------------------------- /assets/themes/awesome/images/arrow-down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/awesomium/wiki/HEAD/assets/themes/awesome/images/arrow-down.png -------------------------------------------------------------------------------- /assets/themes/awesome/images/white-linen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/awesomium/wiki/HEAD/assets/themes/awesome/images/white-linen.png -------------------------------------------------------------------------------- /_layouts/default.html: -------------------------------------------------------------------------------- 1 | --- 2 | theme : 3 | name : awesome 4 | --- 5 | {% include JB/setup %} 6 | {% include themes/awesome/default.html %} 7 | -------------------------------------------------------------------------------- /assets/themes/awesome/images/octocat-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/awesomium/wiki/HEAD/assets/themes/awesome/images/octocat-small.png -------------------------------------------------------------------------------- /assets/themes/awesome/webfonts/27DDD3_0_0.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/awesomium/wiki/HEAD/assets/themes/awesome/webfonts/27DDD3_0_0.eot -------------------------------------------------------------------------------- /assets/themes/awesome/webfonts/27DDD3_0_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/awesomium/wiki/HEAD/assets/themes/awesome/webfonts/27DDD3_0_0.ttf -------------------------------------------------------------------------------- /assets/themes/awesome/webfonts/27DDD3_0_0.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/awesomium/wiki/HEAD/assets/themes/awesome/webfonts/27DDD3_0_0.woff -------------------------------------------------------------------------------- /assets/themes/awesome/images/logo-delimiter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/awesomium/wiki/HEAD/assets/themes/awesome/images/logo-delimiter.png -------------------------------------------------------------------------------- /assets/themes/awesome/images/awe-flat-icon-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/awesomium/wiki/HEAD/assets/themes/awesome/images/awe-flat-icon-logo.png -------------------------------------------------------------------------------- /assets/themes/awesome/images/awe-trans-icon-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/awesomium/wiki/HEAD/assets/themes/awesome/images/awe-trans-icon-logo.png -------------------------------------------------------------------------------- /assets/themes/twitter/bootstrap/img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/awesomium/wiki/HEAD/assets/themes/twitter/bootstrap/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /assets/themes/twitter/bootstrap/img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/awesomium/wiki/HEAD/assets/themes/twitter/bootstrap/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /_includes/JB/sharing: -------------------------------------------------------------------------------- 1 | {% if site.safe and site.JB.sharing.provider and page.JB.sharing != false %} 2 | 3 | {% case site.JB.sharing.provider %} 4 | {% when "custom" %} 5 | {% include custom/sharing %} 6 | {% endcase %} 7 | 8 | {% endif %} -------------------------------------------------------------------------------- /sitemap.txt: -------------------------------------------------------------------------------- 1 | --- 2 | # Remember to set production_url in your _config.yml file! 3 | title : Sitemap 4 | --- 5 | {% for page in site.pages %} 6 | {{site.production_url}}{{ page.url }}{% endfor %} 7 | {% for post in site.posts %} 8 | {{site.production_url}}{{ post.url }}{% endfor %} -------------------------------------------------------------------------------- /_includes/themes/twitter/page.html: -------------------------------------------------------------------------------- 1 | 4 | 5 |
6 |
7 | {{ content }} 8 |
9 |
10 | -------------------------------------------------------------------------------- /licensing/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title : Category - Licensing 4 | group: Categories 5 | 6 | --- 7 | {% include JB/setup %} 8 | 9 | -------------------------------------------------------------------------------- /tutorials/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title : Category - Tutorials 4 | group: Categories 5 | 6 | --- 7 | {% include JB/setup %} 8 | 9 | -------------------------------------------------------------------------------- /changelogs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title : Category - Changelogs 4 | group: Categories 5 | 6 | --- 7 | {% include JB/setup %} 8 | 9 | -------------------------------------------------------------------------------- /general-use/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title : Category - General Use 4 | group: Categories 5 | 6 | --- 7 | {% include JB/setup %} 8 | 9 | -------------------------------------------------------------------------------- /_includes/JB/comments-providers/livefyre: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /getting-started/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title : Category - Getting Started 4 | group: Categories 5 | 6 | --- 7 | {% include JB/setup %} 8 | 9 | -------------------------------------------------------------------------------- /_includes/JB/comments-providers/intensedebate: -------------------------------------------------------------------------------- 1 | 6 | 7 | -------------------------------------------------------------------------------- /_includes/JB/analytics: -------------------------------------------------------------------------------- 1 | {% if site.safe and site.JB.analytics.provider and page.JB.analytics != false %} 2 | 3 | {% case site.JB.analytics.provider %} 4 | {% when "google" %} 5 | {% include JB/analytics-providers/google %} 6 | {% when "getclicky" %} 7 | {% include JB/analytics-providers/getclicky %} 8 | {% when "mixpanel" %} 9 | {% include JB/analytics-providers/mixpanel %} 10 | {% when "custom" %} 11 | {% include custom/analytics %} 12 | {% endcase %} 13 | 14 | {% endif %} -------------------------------------------------------------------------------- /_includes/JB/comments: -------------------------------------------------------------------------------- 1 | {% if site.JB.comments.provider and page.comments != false %} 2 | 3 | {% case site.JB.comments.provider %} 4 | {% when "disqus" %} 5 | {% include JB/comments-providers/disqus %} 6 | {% when "livefyre" %} 7 | {% include JB/comments-providers/livefyre %} 8 | {% when "intensedebate" %} 9 | {% include JB/comments-providers/intensedebate %} 10 | {% when "facebook" %} 11 | {% include JB/comments-providers/facebook %} 12 | {% when "custom" %} 13 | {% include custom/comments %} 14 | {% endcase %} 15 | 16 | {% endif %} -------------------------------------------------------------------------------- /_includes/JB/analytics-providers/google: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/themes/awesome/javascripts/scale.fix.js: -------------------------------------------------------------------------------- 1 | fixScale = function(doc) { 2 | 3 | var addEvent = 'addEventListener', 4 | type = 'gesturestart', 5 | qsa = 'querySelectorAll', 6 | scales = [1, 1], 7 | meta = qsa in doc ? doc[qsa]('meta[name=viewport]') : []; 8 | 9 | function fix() { 10 | meta.content = 'width=device-width,minimum-scale=' + scales[0] + ',maximum-scale=' + scales[1]; 11 | doc.removeEventListener(type, fix, true); 12 | } 13 | 14 | if ((meta = meta[meta.length - 1]) && addEvent in doc) { 15 | fix(); 16 | scales = [.25, 1.6]; 17 | doc[addEvent](type, fix, true); 18 | } 19 | 20 | }; -------------------------------------------------------------------------------- /_includes/JB/analytics-providers/getclicky: -------------------------------------------------------------------------------- 1 | 12 | 13 | -------------------------------------------------------------------------------- /_includes/JB/comments-providers/facebook: -------------------------------------------------------------------------------- 1 |
2 | 9 |
-------------------------------------------------------------------------------- /changelogs/whats-new-1-7-3.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title : What's New in 1.7.3 4 | group: Changelogs 5 | weight: 7 6 | 7 | --- 8 | {% include JB/setup %} 9 | 10 | > These notes are for the core C++ library, click here for the .NET notes. 11 | 12 | 13 | ### Major Core Changes 14 | 15 | * Fixed bug within WebKit that caused GDI handles to constantly increase in main process. [(issue #4)](https://github.com/awesomium/awesomium-pub/issues/4#issuecomment-27012277) 16 | * Added API to allow users to execute custom JavaScript at the very beginning of every frame. 17 | 18 | ### Major API Changes 19 | 20 | * Added `WebConfig::user_script` 21 | -------------------------------------------------------------------------------- /general-use/loading-remote-assets.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title : Loading Remote Assets 4 | group: General Use 5 | weight: 21 6 | 7 | --- 8 | 9 | ### Remote HTML Assets 10 | 11 | You can load any HTTP URL into a WebView just as you would in a regular browser by using `WebView::LoadURL`. 12 | 13 | For example: 14 | 15 | {% highlight cpp %} 16 | view->LoadURL(WebURL(WSLit("http://www.google.com"))); 17 | {% endhighlight %} 18 | 19 | Please note that you can only load HTML and text files into a WebView at this time. 20 | 21 | ### Same-Origin Policy 22 | 23 | By default, Awesomium uses Chrome's "same-origin" policy to prevent cross-site scripting requests. If you wish to disable this behavior please see `WebPreferences.enable_web_security`. -------------------------------------------------------------------------------- /_includes/JB/analytics-providers/mixpanel: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_includes/themes/awesome/page.html: -------------------------------------------------------------------------------- 1 | 14 | 15 |
16 |
17 |

{{ page.title }} {% if page.tagline %} {{ page.tagline }}{% endif %}

18 |
19 | 20 |
21 | {{ content }} 22 |
23 |
24 | -------------------------------------------------------------------------------- /index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title: Welcome! 4 | groups: 5 | - name: Getting Started 6 | - name: General Use 7 | 8 | --- 9 | {% include JB/setup %} 10 | 11 | Awesomium provides everything you need to start displaying beautiful HTML-powered interfaces and web-content within your C++ or .NET application fast. 12 | 13 | It takes only a minute to get started, begin by following the tutorials below. 14 | 15 | _You are at the C++ Language Wiki, to view the .NET Language Wiki please [click here](http://wiki.awesomium.net). All articles are compatible with version 1.7+ only._ 16 | 17 | {% for g in site.groups %} 18 | ### {{ g.name }} 19 | 20 | {% endfor %} 21 | -------------------------------------------------------------------------------- /general-use/changing-the-user-agent.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title : Changing the User-Agent 4 | group: General Use 5 | 6 | --- 7 | 8 | We supply a default user-agent with 1.7 that is compatible with Chrome 18. 9 | 10 | If you would like override the default user-agent, you can do so using WebConfig when initializing the WebCore, for example: 11 | 12 | {% highlight cpp %} 13 | #include 14 | 15 | using namespace Awesomium; 16 | 17 | int main () { 18 | WebConfig config; 19 | config.user_agent = WSLit("Mozilla/5.0 (iPhone; CPU iPhone OS 5_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9B176 Safari/7534.48.3"); 20 | 21 | WebCore* core = WebCore::Initialize(config); 22 | core->Update(); 23 | core->Shutdown(); 24 | 25 | return 0; 26 | } 27 | {% endhighlight %} -------------------------------------------------------------------------------- /_includes/JB/setup: -------------------------------------------------------------------------------- 1 | {% capture jbcache %} 2 | 5 | {% if site.JB.setup.provider == "custom" %} 6 | {% include custom/setup %} 7 | {% else %} 8 | {% if site.safe and site.JB.BASE_PATH and site.JB.BASE_PATH != '' %} 9 | {% assign BASE_PATH = site.JB.BASE_PATH %} 10 | {% assign HOME_PATH = site.JB.BASE_PATH %} 11 | {% else %} 12 | {% assign BASE_PATH = nil %} 13 | {% assign HOME_PATH = "/" %} 14 | {% endif %} 15 | 16 | {% if site.JB.ASSET_PATH %} 17 | {% assign ASSET_PATH = site.JB.ASSET_PATH %} 18 | {% else %} 19 | {% capture ASSET_PATH %}{{ BASE_PATH }}/assets/themes/{{ page.theme.name }}{% endcapture %} 20 | {% endif %} 21 | {% endif %} 22 | {% endcapture %}{% assign jbcache = nil %} -------------------------------------------------------------------------------- /general-use/sharing-render-processes-between-web-views.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title : Sharing Render Processes Between Web-Views 4 | group: General Use 5 | 6 | --- 7 | 8 |

We'll show you how to reduce memory and active processes by sharing renderers between Web-Views

9 | 10 | Each WebView that you spawn via `WebCore.CreateWebView` gets its own render process (eg, `awesomium_process.exe`) with its own set of resources. This is great for isolation and multi-process rendering but sometimes you need to create boatloads of views and don't want to spend boatloads of resources. 11 | 12 | ### Child Process Trick 13 | 14 | One way to force WebViews to share a render process is to make one master WebView and use it to spawn a bunch of smaller web views (e.g., `window.open()` in JavaScript). Child WebViews will share the same process as the parent. 15 | -------------------------------------------------------------------------------- /atom.xml: -------------------------------------------------------------------------------- 1 | --- 2 | layout: nil 3 | title : Atom Feed 4 | --- 5 | 6 | 7 | 8 | {{ site.title }} 9 | 10 | 11 | {{ site.time | date_to_xmlschema }} 12 | {{ site.production_url }} 13 | 14 | {{ site.author.name }} 15 | {{ site.author.email }} 16 | 17 | 18 | {% for post in site.posts %} 19 | 20 | {{ post.title }} 21 | 22 | {{ post.date | date_to_xmlschema }} 23 | {{ site.production_url }}{{ post.id }} 24 | {{ post.content | xml_escape }} 25 | 26 | {% endfor %} 27 | 28 | -------------------------------------------------------------------------------- /changelogs/whats-new-1-7-2.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title : What's New in 1.7.2 4 | group: Changelogs 5 | weight: 9 6 | 7 | --- 8 | {% include JB/setup %} 9 | 10 | > These notes are for the core C++ library, click here for the .NET notes. 11 | 12 | 13 | ### Major Core Changes 14 | 15 | * Added API to help mitigate unchecked memory usage during long run times. 16 | * Fixed bug with enumeration of global `JSObject` properties. 17 | * Fixed bug with logging behavior (output was not consistent and was occasionally flushed during runtime). 18 | * Fixed bug on Mac OSX so that `/Library/Frameworks` is searched by default when determining package path. 19 | 20 | ### Major API Changes 21 | 22 | * Added `WebSession::ClearCache` 23 | * Added `WebView::ReduceMemoryUsage` 24 | * Added `WebConfig::reduce_memory_usage_on_navigation` 25 | * Added `WebCore::Log` 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Awesomium-Wiki 2 | 3 | This is the online wiki for Awesomium, a Web UI Bridge for Native Apps. 4 | 5 | Check it out at: 6 | 7 | ## To Create a New Category 8 | 9 | Let's make a new category named "My Category" with a path of "/my-category" 10 | 11 | 1. Create a folder named "my-category" in the root of the repo. 12 | 2. Create a file named "index.md" inside this folder 13 | 3. Add the following text to this file (modify it as needed): 14 | 15 | --- 16 | layout: page 17 | title : Category - My Category 18 | group: Categories 19 | 20 | --- 21 | {% include JB/setup %} 22 | 23 | 28 | 4. Open up _config.yml and add your 'name' and 'path' to the 'groups' list. 29 | 5. Start making pages with a group of 'My Category'! 30 | 31 | ## Other Links 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /general-use/distributing-awesomium-with-your-application.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title : Distributing Awesomium With Your Application 4 | group: General Use 5 | weight: 6 6 | --- 7 | 8 | ### What files should I include with my application? 9 | 10 | You should always include the following files from the SDK in your app's working directory: 11 | 12 | * awesomium.dll 13 | * awesomium_process.exe 14 | * avcodec-53.dll 15 | * avformat-53.dll 16 | * avutil-51.dll 17 | * icudt.dll 18 | * libEGL.dll 19 | * libGLESv2.dll 20 | 21 | The following files are optional: 22 | 23 | * inspector.pak (Only needed if you enable the remote inspector) 24 | * awesomium_pak_utility.exe (Utility for creating PAK files to use with DataPakSource) 25 | * awesomium_symbols.pdb (Debug Symbols for awesomium.dll) 26 | * awesomium_process.pdb (Debug Symbols for awesomium_process.exe) 27 | 28 | ### What about Flash? 29 | 30 | If you need to use Flash in your application, you should bundle the Flash installer (the NPAPI build, usually for Firefox) with your application. -------------------------------------------------------------------------------- /_plugins/debug.rb: -------------------------------------------------------------------------------- 1 | # A simple way to inspect liquid template variables. 2 | # Usage: 3 | # Can be used anywhere liquid syntax is parsed (templates, includes, posts/pages) 4 | # {{ site | debug }} 5 | # {{ site.posts | debug }} 6 | # 7 | require 'pp' 8 | module Jekyll 9 | # Need to overwrite the inspect method here because the original 10 | # uses < > to encapsulate the psuedo post/page objects in which case 11 | # the output is taken for HTML tags and hidden from view. 12 | # 13 | class Post 14 | def inspect 15 | "#Jekyll:Post @id=#{self.id.inspect}" 16 | end 17 | end 18 | 19 | class Page 20 | def inspect 21 | "#Jekyll:Page @name=#{self.name.inspect}" 22 | end 23 | end 24 | 25 | end # Jekyll 26 | 27 | module Jekyll 28 | module DebugFilter 29 | 30 | def debug(obj, stdout=false) 31 | puts obj.pretty_inspect if stdout 32 | "
#{obj.class}\n#{obj.pretty_inspect}
" 33 | end 34 | 35 | end # DebugFilter 36 | end # Jekyll 37 | 38 | Liquid::Template.register_filter(Jekyll::DebugFilter) -------------------------------------------------------------------------------- /_includes/JB/comments-providers/disqus: -------------------------------------------------------------------------------- 1 |
2 | 13 | 14 | blog comments powered by Disqus 15 | -------------------------------------------------------------------------------- /general-use/reduce-size-of-library.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title : Reduce the size of the library 4 | group: General Use 5 | 6 | --- 7 | 8 | You can reduce the size of the Awesomium libraries by using **UPX** to compress the individual DLLs of the Awesomium SDK. 9 | 10 | 1. Download the latest version of UPX for your platform, here: [http://upx.sourceforge.net/](http://upx.sourceforge.net/) 11 | 2. Copy the upx executable to the **_build/bin_** folder of the SDK. 12 | 3. Open a Console/Terminal window and navigate to the **_build/bin_** folder of the SDK. 13 | 4. Execute the following commands: 14 | 15 | {% highlight bash %} 16 | upx --best --lzma awesomium.dll 17 | upx --best --lzma icudt.dll 18 | {% endhighlight %} 19 | 20 | You can now delete the copy of the upx executable from the **_build/bin_** folder of the SDK. 21 | 22 | ### Notes 23 | 24 | * It is not necessary to reduce the size of any other libraries of the Awesomium SDK, since they are of relatively small size. 25 | * Do not apply this technique to the managed assemblies or the Awesomium libraries accompanying **Awesomium.NET**; a packed version of Awesomium.NET will be available with the final release of version 1.7. 26 | -------------------------------------------------------------------------------- /general-use/loading-local-assets.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title : Loading Local Assets 4 | group: General Use 5 | weight: 20 6 | 7 | --- 8 | 9 | ### Loading Assets from the Filesystem 10 | 11 | You can load pages and assets into a WebView from the local filesystem by using `WebView::LoadURL` with a local `file:///` URL. 12 | 13 | {% highlight cpp %} 14 | view->LoadURL(WebURL(WSLit("file:///C:/Users/awesomium/Documents/webpage.html"))); 15 | {% endhighlight %} 16 | 17 | This is just like opening a local HTML file into your browser. 18 | 19 | ### Loading Assets from a DataSource 20 | 21 | Instead of putting all of your assets in a local folder alongside your application, we recommend using a DataSource (or even a DataPakSource) to distribute sensitive assets. A DataSource gives you complete control over how the resource is loaded (allowing you to implement encrypted and/or compressed loading schemes). 22 | 23 | **See [this article](using-data-sources.html) for more information on using DataSource.** 24 | 25 | ### Same-Origin Policy 26 | 27 | By default, Awesomium uses Chrome's "same-origin" policy to prevent cross-site scripting requests. If you wish to disable this behavior please see `WebPreferences.enable_web_security`. -------------------------------------------------------------------------------- /general-use/working-with-windowed-web-views.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title : Working with Windowed Web-Views 4 | group: General Use 5 | weight: 4 6 | 7 | --- 8 | 9 | ### Windowed Web-Views 10 | 11 | Windowed Web-Views are a new feature to the 1.7 branch that essentially allow you to render a WebView directly to a platform-specific window (such as a HWND on Windows). 12 | 13 | These Web-Views capture mouse/keyboard input and usually must be attached to some kind of container to be displayed. 14 | 15 | Rendering a WebView directly to a window can dramatically improve performance in situations where a WebView needs to be displayed in a conventional, 'popup' manner (as opposed to layered within a 3D engine or projected non-uniformaly onto a surface). 16 | 17 | ### Creating a Windowed Web-View 18 | 19 | You can create a windowed Web-View via `WebCore::CreateWebView`. Here's an example of how to create such a view on the Windows platform 20 | 21 | {% highlight cpp %} 22 | // Create a windowed WebView with initial size of 500 x 500 23 | WebView* view = web_core->CreateWebView(500, 500, 0, kWebViewType_Window); 24 | 25 | // Attach the window to our parent window container 26 | view->set_parent_window(parent_hwnd); 27 | {% endhighlight %} -------------------------------------------------------------------------------- /changelogs/whats-new-1-7-4.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title : What's New in 1.7.4 4 | group: Changelogs 5 | weight: 6 6 | 7 | --- 8 | {% include JB/setup %} 9 | 10 | > These notes are for the core C++ API, __click here for the .NET notes__. 11 | 12 | 13 | ### Major Core Changes 14 | * Removed quota limit on local storage and session storage 15 | * Fixed issue with `WebConfig::user_script` on Mac OSX 16 | * Fixed issue with `about:blank` being added to history at beginning of `WebView` lifetime 17 | * Fixed issue with PDF files not being downloaded when Adobe Reader is installed 18 | * Fixed crash that occurs when `JSObject::Invoke` fails on executing a callback with invalid JavaScript 19 | * Fixed crash issue when JavaScript is disabled 20 | * Fixed crash issue with `requestQuota` 21 | * Fixed crash when users hit `CTRL+LEFT` at beginning of line 22 | 23 | ### Major API Changes 24 | * Added `WebConfig::asset_protocol` 25 | * Added catch-all rule to `WebSession::AddDataSource` 26 | * Added host and request parameters to `DataSource::OnRequest` 27 | 28 | ### .NET Changes 29 | * Click here for the .NET notes 30 | -------------------------------------------------------------------------------- /assets/themes/awesome/webfonts/MyFontsWebfontsKit.css: -------------------------------------------------------------------------------- 1 | /* @license 2 | * MyFonts Webfont Build ID 2612691, 2013-07-30T17:40:11-0400 3 | * 4 | * The fonts listed in this notice are subject to the End User License 5 | * Agreement(s) entered into by the website owner. All other parties are 6 | * explicitly restricted from using the Licensed Webfonts(s). 7 | * 8 | * You may obtain a valid license at the URLs below. 9 | * 10 | * Webfont: Neo Sans Std Bold by Monotype Imaging 11 | * URL: http://www.myfonts.com/fonts/mti/neo-sans/std-bold/ 12 | * Copyright: Copyright 2004 Monotype Imaging, Inc. All Rights Reserved. 13 | * Licensed pageviews: 250,000 14 | * 15 | * 16 | * License: http://www.myfonts.com/viewlicense?type=web&buildid=2612691 17 | * 18 | * © 2013 MyFonts Inc 19 | */ 20 | 21 | 22 | /* @import must be at top of file, otherwise CSS will not work */ 23 | @import url("//hello.myfonts.net/count/27ddd3"); 24 | 25 | 26 | @font-face {font-family: 'NeoSansStd-Bold';src: url('/assets/themes/awesome/webfonts/27DDD3_0_0.eot');src: url('/assets/themes/awesome/webfonts/27DDD3_0_0.eot?#iefix') format('embedded-opentype'),url('/assets/themes/awesome/webfonts/27DDD3_0_0.woff') format('woff'),url('/assets/themes/awesome/webfonts/27DDD3_0_0.ttf') format('truetype');} -------------------------------------------------------------------------------- /_includes/JB/tags_list: -------------------------------------------------------------------------------- 1 | {% comment %}{% endcomment %} 19 | 20 | {% if site.JB.tags_list.provider == "custom" %} 21 | {% include custom/tags_list %} 22 | {% else %} 23 | {% if tags_list.first[0] == null %} 24 | {% for tag in tags_list %} 25 |
  • {{ tag }} {{ site.tags[tag].size }}
  • 26 | {% endfor %} 27 | {% else %} 28 | {% for tag in tags_list %} 29 |
  • {{ tag[0] }} {{ tag[1].size }}
  • 30 | {% endfor %} 31 | {% endif %} 32 | {% endif %} 33 | {% assign tags_list = nil %} 34 | -------------------------------------------------------------------------------- /_includes/themes/awesome/post.html: -------------------------------------------------------------------------------- 1 | 4 | 5 |
    6 |
    7 | {{ content }} 8 |
    9 | 24 |
    25 | {% include JB/comments %} 26 |
    27 | 28 |
    29 |

    Published

    30 |
    {{ page.date | date_to_long_string }}
    31 | 32 | {% unless page.tags == empty %} 33 |

    Tags

    34 |
      35 | {% assign tags_list = page.tags %} 36 | {% include JB/tags_list %} 37 |
    38 | {% endunless %} 39 |
    40 |
    41 | -------------------------------------------------------------------------------- /_includes/themes/twitter/post.html: -------------------------------------------------------------------------------- 1 | 4 | 5 |
    6 |
    7 | {{ content }} 8 |
    9 | 24 |
    25 | {% include JB/comments %} 26 |
    27 | 28 |
    29 |

    Published

    30 |
    {{ page.date | date_to_long_string }}
    31 | 32 | {% unless page.tags == empty %} 33 |

    Tags

    34 |
      35 | {% assign tags_list = page.tags %} 36 | {% include JB/tags_list %} 37 |
    38 | {% endunless %} 39 |
    40 |
    41 | -------------------------------------------------------------------------------- /_includes/JB/categories_list: -------------------------------------------------------------------------------- 1 | {% comment %}{% endcomment %} 19 | 20 | {% if site.JB.categories_list.provider == "custom" %} 21 | {% include custom/categories_list %} 22 | {% else %} 23 | {% if categories_list.first[0] == null %} 24 | {% for category in categories_list %}
  • {{ category | join: "/" }} {{ site.categories[category].size }}
  • {% endfor %} 25 | {% else %} 26 | {% for category in categories_list %}
  • {{ category[0] | join: "/" }} {{ category[1].size }}
  • {% endfor %} 27 | {% endif %} 28 | {% endif %} 29 | {% assign categories_list = nil %} -------------------------------------------------------------------------------- /changelogs/whats-new-1-7-5.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title : What's New in 1.7.5 4 | group: Changelogs 5 | weight: 5 6 | 7 | --- 8 | {% include JB/setup %} 9 | 10 | > These notes are for the core C++ API, __click here for the .NET notes__. 11 | 12 | ### Features / API Changes 13 | * Added `ResourceRequest::set_ignore_data_source_handler` 14 | * Added `WebPreferences::max_http_cache_storage` 15 | * Added `WebPreferences::user_script` 16 | * Added `WebConfig::user_stylesheet` 17 | * Made it so `user_script` and `user_stylesheet` values in `WebConfig` and `WebPreferences` are concatenated 18 | * Added `WebViewListener::Process::OnLaunch` 19 | * Made `DataSource::SendResponse` buffer param const 20 | 21 | ### Bugfixes 22 | * Fixed crash on Windows XP when using Facebook Connect (and other sites with similar certificate signing modes) 23 | * Fixed crash on Linux when rendering unstyled checkboxes, buttons, and progress bars. _Note: to actually display unstyled checkboxes, radio buttons, or progress bars, users will need to declare global CSS so that these widgets are painted by WebKit instead._ 24 | * Fixed crash that occurs if user unfocuses a textbox during an IME composition 25 | * Fixed crash with very large strings of `user_script` 26 | 27 | ### .NET Changes 28 | * Click here for the .NET notes 29 | -------------------------------------------------------------------------------- /_includes/JB/liquid_raw: -------------------------------------------------------------------------------- 1 | {% comment%}{% endcomment%} 26 | 27 | {% if site.JB.liquid_raw.provider == "custom" %} 28 | {% include custom/liquid_raw %} 29 | {% else %} 30 |
    {{text | replace:"|.", "{" | replace:".|", "}" | replace:">", ">" | replace:"<", "<" }}
    31 | {% endif %} 32 | {% assign text = nil %} -------------------------------------------------------------------------------- /getting-started/setting-up-on-linux.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title : Setting Up on Linux 4 | group: Getting Started 5 | weight: 3 6 | 7 | --- 8 | 9 | > These notes are for developing a C++ application. If you are a developing a .NET/C# application please see our [.NET Wiki](http://wiki.awesomium.net/getting-started/) instead. 10 | 11 | ### Checklist 12 | 13 | Before we begin, you'll need the following: 14 | 15 | * The **Awesomium SDK** (download it [here](http://www.awesomium.com/download)) 16 | * Ubuntu Linux 17 | 18 | ### Install the SDK 19 | 20 | 1. After downloading the SDK, extract it to a folder in your home directory. 21 | 2. Open the Terminal. 22 | 3. Change directories to the SDK files you just extracted. 23 | 4. Run `sudo make all` to install the library to your machine. 24 | 25 | ### Run the Samples 26 | 27 | You should now be able to run the samples. Change directories to the `./bin` folder and run some samples: 28 | 29 | The Hello World example loads up Google and renders it to a JPG on disk: 30 | 31 | ./awesomium_sample_hello 32 | 33 | The WebFlow sample depends on SDL 1.2 and OpenGL, demonstrates a simple 3D browser: 34 | 35 | ./awesomium_sample_webflow 36 | 37 | ### Using Awesomium 38 | 39 | To use most of the Awesomium API in your C++ code, just include the following: 40 | 41 | #include 42 | 43 | To link against Awesomium 1.7.4 in your applications, just add "-lawesomium-1-7" 44 | 45 | g++ main.cpp -lawesomium-1-7 46 | 47 | 48 | ### Read some more articles 49 | * [Basic Concepts](basic-concepts.html) 50 | -------------------------------------------------------------------------------- /_includes/site/navigation: -------------------------------------------------------------------------------- 1 | 5 |

    6 | 7 |

    8 |
    Language:
    9 |
    10 |
    11 |

    12 | 13 | 14 | 44 | 45 |

    Categories

    46 | {% for g in site.groups %} 47 |

    {{ g.name }}

    48 | {% endfor %} 49 | -------------------------------------------------------------------------------- /_includes/JB/posts_collate: -------------------------------------------------------------------------------- 1 | {% comment %}{% endcomment %} 19 | 20 | {% if site.JB.posts_collate.provider == "custom" %} 21 | {% include custom/posts_collate %} 22 | {% else %} 23 | {% for post in posts_collate %} 24 | {% capture this_year %}{{ post.date | date: "%Y" }}{% endcapture %} 25 | {% capture this_month %}{{ post.date | date: "%B" }}{% endcapture %} 26 | {% capture next_year %}{{ post.previous.date | date: "%Y" }}{% endcapture %} 27 | {% capture next_month %}{{ post.previous.date | date: "%B" }}{% endcapture %} 28 | 29 | {% if forloop.first %} 30 |

    {{this_year}}

    31 |

    {{this_month}}

    32 |
      33 | {% endif %} 34 | 35 |
    • {{ post.date | date: "%B %e, %Y" }} » {{ post.title }}
    • 36 | 37 | {% if forloop.last %} 38 |
    39 | {% else %} 40 | {% if this_year != next_year %} 41 | 42 |

    {{next_year}}

    43 |

    {{next_month}}

    44 |
      45 | {% else %} 46 | {% if this_month != next_month %} 47 |
    48 |

    {{next_month}}

    49 |
      50 | {% endif %} 51 | {% endif %} 52 | {% endif %} 53 | {% endfor %} 54 | {% endif %} 55 | {% assign posts_collate = nil %} -------------------------------------------------------------------------------- /general-use/handling-child-web-views.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title : Handling Child Web-Views 4 | group: General Use 5 | 6 | --- 7 | 8 | ### Child Web-Views 9 | 10 | Pages loaded into a WebView may occasionally need to create a new 'window' to display external links (for example, links with `target="_blank"` or calls to `window.open()` in JavaScript). To handle this, each WebView can create a new child WebView that automatically loads content. 11 | 12 | #### Displaying the View 13 | 14 | It is your responsibility to display these child WebViews within your application in some way that makes sense. This usually means making a subclass of `WebViewListener::View`, registering it with your WebView, and handling the `OnShowCreatedWebView` method. 15 | 16 | Here's an example of how the WebFlow sample handles this method: 17 | 18 | {% highlight cpp %} 19 | void Application::OnShowCreatedWebView(Awesomium::WebView* caller, 20 | Awesomium::WebView* new_view, 21 | const Awesomium::WebURL& opener_url, 22 | const Awesomium::WebURL& target_url, 23 | const Awesomium::Rect& initial_pos, 24 | bool is_popup) { 25 | // Resize the new WebView immediately to our container's dimensions 26 | new_view->Resize(WIDTH, HEIGHT); 27 | 28 | // Special overload of the WebTile container class that displays 29 | // an existing WebView on an OpenGL surface. 30 | WebTile* new_tile = new WebTile(new_view, WIDTH, HEIGHT); 31 | 32 | new_view->set_view_listener(this); 33 | new_view->set_load_listener(this); 34 | new_view->set_process_listener(this); 35 | 36 | webTiles.push_back(new_tile); 37 | animateTo(webTiles.size() - 1); 38 | } 39 | {% endhighlight %} 40 | 41 | #### Windowed Child Web-Views 42 | 43 | All windowed Web-Views will create child WebViews that are also windowed. You should make sure to immediately call `WebView::set_parent_window` on the new child WebView within `OnShowCreatedWebView`. 44 | 45 | -------------------------------------------------------------------------------- /_includes/themes/awesome/default.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {{ page.title }} 6 | {% if page.description %}{% endif %} 7 | 8 | 9 | 10 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 38 | 39 | 40 |
      41 | 42 | 43 |
      44 | {% include site/navigation %} 45 |
      46 |
      47 | {{ content }} 48 |
      49 | 50 | 54 |
      55 | 56 | {% include JB/analytics %} 57 | 58 | 59 | -------------------------------------------------------------------------------- /_includes/themes/twitter/default.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {{ page.title }} 6 | {% if page.description %}{% endif %} 7 | 8 | 9 | 10 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 25 | 26 | 27 | 28 | 29 | 41 | 42 |
      43 | 44 |
      45 | {{ content }} 46 |
      47 | 48 | 54 | 55 |
      56 | 57 | {% include JB/analytics %} 58 | 59 | 60 | -------------------------------------------------------------------------------- /changelogs/whats-new-1-7-0.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title : What's New in 1.7.0 4 | group: Changelogs 5 | weight: 10 6 | 7 | --- 8 | {% include JB/setup %} 9 | 10 | ## Changes in Awesomium 1.7.0 (Core) 11 | 12 | ### Major Core Changes 13 | * You can now handle SSL errors and display relevant UI to allow the user to ignore certain certificate errors. See `WebViewListener::Dialog::OnShowCertificateErrorDialog`. 14 | * You can now request SSL info for a certain web-page so that you can display relevant UI (for example, the green "lock" in Chrome for authenticated web-sites). See `WebView::RequestPageInfo` 15 | * Full page zoom has been added, see `WebView::ZoomIn` and `WebView::SetZoom ` 16 | * You can now block certain page navigations (useful for custom blacklist/whitelist behavior). See `ResourceInterceptor::OnFilterNavigation` 17 | * You can now define properties on remote JSObjects asynchronously. This is useful for setting a large number of properties at once. See `JSObject::SetPropertyAsync` 18 | * You can now invoke methods on remote JSObjects asynchronously. See `JSObject::InvokeAsync` 19 | * You can now define a custom hostname for the remote Inspector to listen on (useful if you are behind a router). See `WebConfig::remote_debugging_host` 20 | 21 | ### Major API Changes 22 | 23 | The following methods were added: 24 | 25 | * WebView::RequestPageInfo 26 | * WebView::DidOverrideCertificateError 27 | * WebView::routing_id 28 | * WebView::ZoomIn, ZoomOut, SetZoom, ResetZoom 29 | * WebView::set_sync_message_timeout 30 | * WebConfig::remote_debugging_host 31 | * WebViewListener::Dialog::OnShowPageInfoDialog 32 | * WebViewListener::Dialog::OnShowCertificateErrorDialog 33 | * WebViewListener::View::OnAddConsoleMessage 34 | * ResourceInterceptor:;OnFilterNavigation 35 | * ResourceInterceptor::OnWillDownload 36 | * JSObject::SetPropertyAsync 37 | * JSObject::InvokeAsync 38 | 39 | ### Bugfixes 40 | 41 | The following issues were resolved: 42 | 43 | * Issue with WebSession::AddDataSource not matching uppercase names 44 | * Issue with WebView::DidCancelDownload 45 | * Issue with custom method names not being enumerated within JSObject::GetMethodNames 46 | * Issue with crash upon certain download events. 47 | 48 | __See [this announcement](http://labs.awesomium.com/whats-new-in-1-7-0) for more info about this release.__ 49 | 50 | -------------------------------------------------------------------------------- /general-use/using-web-sessions.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title : Using Web-Sessions 4 | group: General Use 5 | weight: 1 6 | 7 | --- 8 | 9 | ### What is a WebSession? 10 | 11 | A WebSession is responsible for storing all user-generated data (cookies, cache, authentication, etc.). It can either be purely in-memory or saved to disk (you will need to provide a writeable path to store the data at runtime). 12 | 13 | Each WebView must have a WebSession to store its data into, you can associate multiple WebViews with each WebSession. 14 | 15 | ### The Default WebSession 16 | 17 | The WebCore creates a default, in-memory WebSession upon initialization. This session is used for all WebViews unless otherwise specified. 18 | 19 | ### Creating a WebSession 20 | 21 | You can create a WebSession like so: 22 | 23 | {% highlight cpp %} 24 | WebSession* my_session = web_core->CreateWebSession( 25 | WSLit("C:\\Session Data Path"), WebPreferences()); 26 | {% endhighlight %} 27 | 28 | This session will synchronize all of its data to `C:\\Session Data Path\`. 29 | 30 | If you would like to create an in-memory session, just pass an empty path for the first parameter. 31 | 32 | #### Specifying Custom Preferences 33 | You can supply custom preferences for each WebSession via the second parameter. Here's an example: 34 | 35 | {% highlight cpp %} 36 | WebPreferences prefs; 37 | prefs.enable_plugins = false; 38 | prefs.enable_smooth_scrolling = true; 39 | prefs.user_stylesheet = WSLit("* { background-color: yellow !important; }"); 40 | 41 | // Create an in-memory session with our custom preferences 42 | WebSession* my_session = web_core->CreateWebSession(WSLit(""), prefs); 43 | {% endhighlight %} 44 | 45 | ### Destroying the WebSession 46 | It is your responsibility to call WebSession::Release once you are done using the WebSession. If you forget to do this we can't guarantee that your WebSession will be saved to disk upon application exit. 47 | 48 | {% highlight cpp %} 49 | WebSession* my_session = web_core->CreateWebSession( 50 | WSLit(""), WebPreferences()); 51 | 52 | my_session->Release(); 53 | {% endhighlight %} 54 | 55 | The session will not be destroyed until all WebViews associated with it have been destroyed. 56 | 57 | ### Further Reading 58 | 59 | * [Introduction to Web-Views](http://wiki.awesomium.com/general-use/introduction-to-web-views.html) 60 | -------------------------------------------------------------------------------- /general-use/using-data-sources.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title : Using Data-Sources 4 | group: General Use 5 | 6 | --- 7 | 8 | ### What is a DataSource? 9 | 10 | DataSource is a special interface that you can sub-class to define your own resource loader. 11 | 12 | ### Defining Your Own DataSource 13 | 14 | For example, let's create a special DataSource that simply returns one hard-coded HTML string: 15 | 16 | {% highlight cpp %} 17 | #include 18 | 19 | using namespace Awesomium; 20 | 21 | const char* html_str = "

      Hello World

      "; 22 | 23 | class MyDataSource : public DataSource { 24 | public: 25 | MyDataSource() { } 26 | virtual ~MyDataSource { } 27 | 28 | virtual void OnRequest(int request_id, 29 | const Awesomium::ResourceRequest& request, 30 | const Awesomium::WebString& path) { 31 | if (path == WSLit("index.html")) 32 | SendResponse(request_id, 33 | strlen(html_str), 34 | html_str, 35 | WSLit("text/html")); 36 | } 37 | }; 38 | {% endhighlight %} 39 | 40 | #### Asynchronous Request 41 | 42 | You do not have to call `SendResponse` immediately within OnRequest; this event is non-blocking and you can call `SendResponse` at any point later from any other thread. 43 | 44 | ### Binding a DataSource to a WebSession 45 | 46 | To actually use a DataSource for certain URLs, you will need to call `WebSession::AddDataSource`. Here's an example of use: 47 | 48 | {% highlight cpp %} 49 | DataSource* data_source = new MyDataSource(); 50 | web_session->AddDataSource(WSLit("MyApplication"), data_source); 51 | {% endhighlight %} 52 | 53 | This will bind your DataSource with all URLs that start with `asset://MyApplication/`. The `path` parameter of `DataSource::OnRequest` will contain whatever follows the last slash of this URL prefix. 54 | 55 | You can now load the hard-coded page we defined earlier into a WebView via: 56 | 57 | {% highlight cpp %} 58 | view->LoadURL(WebURL(WSLit("asset://MyApplication/index.html"))); 59 | {% endhighlight %} 60 | 61 | ### Using DataPakSource 62 | 63 | We realize that bundling resources with your application is a common problem so we created a simple DataPak format and a DataPak DataSource. 64 | 65 | The general idea is that you create a DataPak from a folder of files (see `WriteDataPak`) before-hand and then use `DataPakSource` to load files from this format. 66 | 67 | {% highlight cpp %} 68 | #include 69 | 70 | DataSource* data_source = new DataPakSource(WSLit("C:\\my_resources.pak")); 71 | web_session->AddDataSource(WSLit("MyApplication"), data_source); 72 | {% endhighlight %} 73 | -------------------------------------------------------------------------------- /general-use/using-global-javascript-objects.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title : Using Global JavaScript Objects 4 | group: General Use 5 | 6 | --- 7 | 8 | Sometimes it's useful to store persistent state between pages. This is where Global JavaScript Objects come in-- these objects are linked to the lifetime of the WebView and never change their remote ID. 9 | 10 | All global objects are 'remote' (their state is stored in the WebView's child-process). 11 | 12 | ### Creating Global JS Objects 13 | 14 | Creating, manipulating, and accessing these objects is very simple in our C++ API. To create an object, simply call `WebView::CreateGlobalJavaScriptObject` with the name that you want the object to appear as in Javascript. 15 | 16 | For example: 17 | 18 | {% highlight cpp %} 19 | JSValue result = web_view->CreateGlobalJavascriptObject( 20 | WSLit("MyObject")); 21 | {% endhighlight %} 22 | 23 | The above would create a global Javascript object that you can access as `MyObject` from any web page loaded into your WebView. 24 | 25 | You can coerce the result into an actual JSObject instance like so: 26 | 27 | {% highlight cpp %} 28 | JSObject& my_object = result.ToObject(); 29 | {% endhighlight %} 30 | 31 | ### Setting Properties 32 | 33 | Of course, creating objects alone isn’t very useful–- to give the object some properties, you can use `JSObject::SetProperty`: 34 | 35 | {% highlight cpp %} 36 | my_object->SetProperty(WSLit("name"), WSLit("foobar")); 37 | my_object->SetProperty(WSLit("color"), WSLit("Blue")); 38 | my_object->SetProperty(WSLit("level"), 25); 39 | {% endhighlight %} 40 | 41 | You can set as many properties as you want, setting a property more than once will replace the previous value. Notice that the last parameter to `SetProperty` accepts a JSValue (more on that later). 42 | 43 | ### Order of Initialization 44 | 45 | You'll need to create your Global Object before loading content into your WebView that references the object. 46 | 47 | All calls for creating the object and setting its properties should be made before calling `WebView::LoadURL`. `WebView::CreateGlobalJavaScriptObject` is a synchronous API call and is guaranteed to be completed once the method call returns. 48 | 49 | ### Limitations of Global Objects 50 | 51 | Global Objects can only contain the following property types: 52 | 53 | - Number 54 | - String 55 | - Array 56 | - Other Global Objects 57 | - Null 58 | - Undefined 59 | 60 | Notice that this does NOT include regular JavaScript Objects (such as DOM objects or any other object defined on a page). This is because these objects are managed by the page's V8 context and will be destroyed at the end of the page's lifetime. If you attempt to add such objects to a Global JavaScript Object, they will be ignored (or filtered out). 61 | 62 | #### Creating a Child of a Global Object 63 | 64 | You can add a child object to a Global JavaScript Object if you declare it as Global as well. 65 | 66 | For example: 67 | {% highlight cpp %} 68 | web_view->CreateGlobalJavascriptObject(WSLit("MyObject")); 69 | web_view->CreateGlobalJavascriptObject(WSLit("MyObject.MyChild")); 70 | {% endhighlight %} 71 | 72 | -------------------------------------------------------------------------------- /_includes/JB/pages_list: -------------------------------------------------------------------------------- 1 | {% comment %}{% endcomment %} 22 | 23 | {% comment %} 24 | 59 | {% endcomment %} 60 | 61 | {% if site.JB.pages_list.provider == "custom" %} 62 | {% include custom/pages_list %} 63 | {% else %} 64 | {% for weight in (1..10) %}{% for node in pages_list %}{% if node.title != null %}{% if node.weight == weight and group == node.group %}{% if page.url == node.url %}
    • {{node.title}}
    • {% else %}
    • {{node.title}}
    • {% endif %}{% endif %}{% endif %}{% endfor %}{% endfor %} 65 | {% for node in pages_list %}{% if node.title != null %}{% if node.weight == null and group == node.group %}{% if page.url == node.url %}
    • {{node.title}}
    • {% else %}
    • {{node.title}}
    • {% endif %}{% endif %}{% endif %}{% endfor %} 66 | {% endif %} 67 | {% assign pages_list = nil %} 68 | {% assign group = nil %} -------------------------------------------------------------------------------- /general-use/porting-to-1-7.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title : Porting to 1.7 4 | group: Changelogs 5 | 6 | --- 7 | 8 | The biggest API changes between 1.6 and 1.7 involve creating WebSessions, displaying the WebView Surface in your application, and integrating JavaScript with your application. 9 | 10 | ## More Control Over Session Data 11 | 12 | You have the option of creating WebViews with the default, in-memory WebSession or creating your own independent sessions. This gives you finer-grained control over cookies, authentication, and any other user-data for each WebView. If you decide to do the latter, you'll need to create a WebSession and use it during the call to CreateWebView. 13 | 14 | WebSessions can be used by more than WebView. It is your responsibility to release the WebSession after all WebViews are done using it. 15 | 16 | ## You Can Now Provide Your Own "RenderBuffer" Implementation 17 | 18 | We decided to allow users to provide their own "RenderBuffer" implementation (now called "Surface") so that they can handle paint/scroll calls directly instead of copying a buffer every frame. 19 | 20 | To provide your own Surface implementation, you'll need to register a new SurfaceFactory with WebCore. Otherwise, if you liked the old way, the default surface is "BitmapSurface" which is very similar to the previous "RenderBuffer". 21 | 22 | ## LoadHTML and LoadFile Removed In Favor Of DataSources 23 | 24 | We now allow you to provide your own resource loader via the DataSource API. You can access resources for a certain DataSource via the following URL syntax: 25 | 26 | `asset://data_source_name/path/goes/here.html` 27 | 28 | We recommend all users to use DataSources for local assets (instead of distributing raw HTML files on disk and loading them with LoadFile). You can still load raw HTML into a WebView by encoding it as a DataURI and passing it to LoadHTML but we recommend against this for performance reasons. 29 | 30 | ## JavaScript Integration Changes 31 | 32 | Our entire JavaScript API has been rewritten so that users can manipulate V8 objects directly across process boundaries. Previously we only allowed "simple" JavaScript types and ignored any complex Objects. This prevented us from returning DOM elements or doing more exotic manipulation of objects on the page. 33 | 34 | We introduced the concept of **"Remote"** and **"Local"** JS Objects in 1.7. 35 | 36 | Local objects only have properties (no custom methods) and are primarily used for declaring data to pass to methods. Local objects can be created using the JSObject constructor. (All JS Objects in 1.6 were Local) 37 | 38 | Remote objects live within the V8 engine in a separate process and can have both Properties and Methods. These can only be returned by the WebView (they actually declared within the script context within the page). 39 | 40 | See this article for more info: [Introduction to JavaScript Integration](http://wiki.awesomium.com/javascript-integration/introduction-to-javascript-integration.html) 41 | 42 | ## Other API Changes 43 | 44 | There are some other API changes (most notably String types and WebPreferences) which you can learn more about in the following articles: 45 | 46 | [Basic Concepts](http://wiki.awesomium.com/getting-started/basic-concepts.html) 47 | 48 | [Introduction to WebViews](http://wiki.awesomium.com/general-use/introduction-to-web-views.html) 49 | -------------------------------------------------------------------------------- /general-use/working-with-offscreen-web-views.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title : Working with Offscreen Web-Views 4 | group: General Use 5 | weight: 3 6 | 7 | --- 8 | 9 | ### Creating an Offscreen Web-View 10 | 11 | You can create an offscreen Web-View via `WebCore::CreateWebView`. Here's an example of how to create such a view: 12 | 13 | {% highlight cpp %} 14 | // Create an offscreen WebView with initial size of 500 x 500 15 | WebView* view = web_core->CreateWebView(500, 500, 0, kWebViewType_Offscreen); 16 | {% endhighlight %} 17 | 18 | ### Displaying the Surface 19 | It is your responsibility to display offscreen WebViews and pass it input within your application. Each WebView has an abstract Surface that you can retrieve via WebView::surface (this instance is owned by the WebView, you shouldn't destroy it): 20 | 21 | {% highlight cpp %} 22 | Surface* surface = my_web_view->surface(); 23 | {% endhighlight %} 24 | 25 | By default, the underlying Surface is of type BitmapSurface (you can specify your own Surface implementation via WebCore::set_surface_factory). It is safe to cast this surface to BitmapSurface to access the pixels: 26 | 27 | {% highlight cpp %} 28 | #include 29 | 30 | BitmapSurface* surface = static_cast(my_web_view->surface()); 31 | surface->SaveToJPEG(WSLit("C:\\bitmap.jpg")); 32 | {% endhighlight %} 33 | 34 | #### Defining Your Own SurfaceFactory 35 | 36 | If you want to intercept Paint/Scroll-Pixel events directly (eg., for writing to an OpenGL surface or streaming to a compressed video format), you can define your own Surface implementation via SurfaceFactory. 37 | 38 | First you'll need to define your own Surface implementation by sub-classing Surface. 39 | 40 | Then, you should define your own SurfaceFactory implementation that creates and destroys an instance of your custom Surface class. 41 | 42 | Next, you should register your SurfaceFactory with `WebCore::set_surface_factory`. 43 | 44 | Now, all WebViews should use your SurfaceFactory to create Surfaces, you should cast `WebView::surface()` to your Surface's type to interact with it. 45 | 46 | ### Passing mouse input 47 | To interact with the WebView, you'll need to pass it mouse events. Here are some quick examples: 48 | 49 | {% highlight cpp %} 50 | // Inject a mouse-movement event to (75, 100) in screen-space (0,0 is top-left of screen) 51 | my_web_view->InjectMouseMove(75, 100); 52 | 53 | // Inject a left-mouse-button down event 54 | my_web_view->InjectMouseDown(kMouseButton_Left); 55 | 56 | // Inject a left-mouse-button up event 57 | my_web_view->InjectMouseUp(kMouseButton_Left); 58 | {% endhighlight %} 59 | 60 | ### Passing keyboard input 61 | To inject keyboard events into a WebView, you will need to create a WebKeyboardEvent and pass it to `WebView::InjectKeyboardEvent`. You can either create a WebKeyboardEvent from a platform-specific keyboard event (eg, MSG, WPARAM, LPARAM on Windows) or synthesize one yourself. See "passing keyboard events" for more information. 62 | 63 | ### Managing input focus 64 | Any time you interact with a WebView, you should first make sure the WebView is focused by calling `WebView::Focus`. If you forget to do this, textboxes may not behave correctly (e.g., carets and selection indicators may not display). 65 | 66 | Similarly, to remove focus from a WebView, you should call `WebView::Unfocus`. -------------------------------------------------------------------------------- /getting-started/setting-up-on-windows.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title : Setting Up on Windows 4 | group: Getting Started 5 | weight: 1 6 | 7 | --- 8 | 9 | > These notes are for developing a C++ application. If you are a developing a .NET/C# application please see our [.NET Wiki](http://wiki.awesomium.net/getting-started/) instead. 10 | 11 | ### Checklist 12 | You will need the following: 13 | 14 | * The latest Awesomium v1.7 SDK for Windows (download it [here](http://www.awesomium.com/download/)) 15 | * Microsoft Visual C++ (there is a free 'Express' version) 16 | 17 | ### Install the SDK 18 | Run the installer and follow the on-screen instructions. Upon success, you should find a folder in your Start Menu with additional links and samples to play with. 19 | 20 | #### Environment Path 21 | 22 | The installer should install the includes and library files under a path which looks like the following: 23 | 24 | `C:\Program Files (x86)\Awesomium Technologies LLC\Awesomium SDK\1.7.2.2` 25 | 26 | To help you reference this path in your projects, an environment variable named `AWE_DIR` should have been defined during installation. 27 | 28 | * __Awesomium Include Path__: `$(AWE_DIR)include` 29 | * __Awesomium Lib Path__: `$(AWE_DIR)build\lib` 30 | * __Awesomium Bin Path__: `$(AWE_DIR)build\bin` 31 | 32 | #### Folder Structure of the SDK 33 | The SDK should contain the following folders in the installation directory: 34 | 35 | * __build/bin__ folder: Contains DLLs that you will need to bundle with your application 36 | * __build/bin/packed__ folder: Contains optional compressed DLLs to use with your application (smaller size, very slight delay in load time). 37 | * __build/lib__ folder: Contains static libraries that you will need to link against your application. 38 | * __include__ folder: Contains headers that you will need to #include in your source files to access our C++ API 39 | 40 | ### Set up your project 41 | #### Configure project settings 42 | 43 | 1. Create a new project in Microsoft Visual C++ (the __Empty Project__ template is recommended). 44 | 2. Add your C++ source files. 45 | 3. Right-click your project name, select __Properties__ to open up the __Property Pages__ dialog. 46 | 4. Add `$(AWE_DIR)include` to __Additional Include Directories__ (should be under Configuration Properties → C/C++ → General) for both Debug and Release configurations. 47 | 5. Add `$(AWE_DIR)build\lib` to __Additional Library Directories__ (should be under Configuration Properties → Linker → General) for all build configurations. 48 | 6. Add `awesomium.lib` to __Additional Dependencies__ (should be under Configuration Properties → Linker → Input) for all build configurations. 49 | 50 | #### Copy files to your build distribution 51 | Before running your executable, __make sure to copy the following files__ from the SDK's __build/bin__ directory to your respective build directories. 52 | 53 | * `avcodec-53.dll` 54 | * `avformat-53.dll` 55 | * `avutil-51.dll` 56 | * `awesomium.dll` 57 | * `awesomium_process.exe` 58 | * `icudt.dll` 59 | * `libEGL.dll` 60 | * `libGLESv2.dll` 61 | * `xinput9_1_0.dll` 62 | 63 | If you wish to use the remote inspector (see `WebConfig`), make sure to also copy `inspector.pak` to your working directory. 64 | 65 | ### Include the API 66 | To include the entire API for Awesomium in your source files, you simply need to include WebCore.h: 67 | 68 | #include 69 | 70 | ### Read some more articles 71 | * [Basic Concepts](basic-concepts.html) 72 | 73 | 74 | -------------------------------------------------------------------------------- /assets/themes/awesome/stylesheets/pygment_trac.css: -------------------------------------------------------------------------------- 1 | .highlight { background: #ffffff; } 2 | .highlight .c { color: #abacb3; } /* Comment */ 3 | .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ 4 | .highlight .k { } /* Keyword */ 5 | .highlight .o { } /* Operator */ 6 | .highlight .cm { color: #abacb3; } /* Comment.Multiline */ 7 | .highlight .cp { color: #a17169; } /* Comment.Preproc */ 8 | .highlight .c1 { color: #abacb3; } /* Comment.Single */ 9 | .highlight .cs { color: #abacb3; ; } /* Comment.Special */ 10 | .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ 11 | .highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */ 12 | .highlight .ge { } /* Generic.Emph */ 13 | .highlight .gr { color: #aa0000 } /* Generic.Error */ 14 | .highlight .gh { color: #999999 } /* Generic.Heading */ 15 | .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ 16 | .highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */ 17 | .highlight .go { color: #888888 } /* Generic.Output */ 18 | .highlight .gp { color: #555555 } /* Generic.Prompt */ 19 | .highlight .gs { } /* Generic.Strong */ 20 | .highlight .gu { color: #800080; ; } /* Generic.Subheading */ 21 | .highlight .gt { color: #aa0000 } /* Generic.Traceback */ 22 | .highlight .kc { } /* Keyword.Constant */ 23 | .highlight .kd { } /* Keyword.Declaration */ 24 | .highlight .kn { } /* Keyword.Namespace */ 25 | .highlight .kp { } /* Keyword.Pseudo */ 26 | .highlight .kr { } /* Keyword.Reserved */ 27 | .highlight .kt { color: #445588; } /* Keyword.Type */ 28 | .highlight .m { color: #009999 } /* Literal.Number */ 29 | .highlight .s { color: #d14 } /* Literal.String */ 30 | .highlight .na { color: #008080 } /* Name.Attribute */ 31 | .highlight .nb { color: #0086B3 } /* Name.Builtin */ 32 | .highlight .nc { color: #445588; } /* Name.Class */ 33 | .highlight .no { color: #008080 } /* Name.Constant */ 34 | .highlight .ni { color: #800080 } /* Name.Entity */ 35 | .highlight .ne { color: #990000; } /* Name.Exception */ 36 | .highlight .nf { color: #990000; } /* Name.Function */ 37 | .highlight .nn { color: #555555 } /* Name.Namespace */ 38 | .highlight .nt { color: #000080 } /* Name.Tag */ 39 | .highlight .nv { color: #008080 } /* Name.Variable */ 40 | .highlight .ow { } /* Operator.Word */ 41 | .highlight .w { color: #bbbbbb } /* Text.Whitespace */ 42 | .highlight .mf { color: #009999 } /* Literal.Number.Float */ 43 | .highlight .mh { color: #009999 } /* Literal.Number.Hex */ 44 | .highlight .mi { color: #009999 } /* Literal.Number.Integer */ 45 | .highlight .mo { color: #009999 } /* Literal.Number.Oct */ 46 | .highlight .sb { color: #d14 } /* Literal.String.Backtick */ 47 | .highlight .sc { color: #d14 } /* Literal.String.Char */ 48 | .highlight .sd { color: #d14 } /* Literal.String.Doc */ 49 | .highlight .s2 { color: #d14 } /* Literal.String.Double */ 50 | .highlight .se { color: #d14 } /* Literal.String.Escape */ 51 | .highlight .sh { color: #d14 } /* Literal.String.Heredoc */ 52 | .highlight .si { color: #d14 } /* Literal.String.Interpol */ 53 | .highlight .sx { color: #d14 } /* Literal.String.Other */ 54 | .highlight .sr { color: #009926 } /* Literal.String.Regex */ 55 | .highlight .s1 { color: #d14 } /* Literal.String.Single */ 56 | .highlight .ss { color: #990073 } /* Literal.String.Symbol */ 57 | .highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */ 58 | .highlight .vc { color: #008080 } /* Name.Variable.Class */ 59 | .highlight .vg { color: #008080 } /* Name.Variable.Global */ 60 | .highlight .vi { color: #008080 } /* Name.Variable.Instance */ 61 | .highlight .il { color: #009999 } /* Literal.Number.Integer.Long */ 62 | 63 | .type-csharp .highlight .k { color: #0000FF } 64 | .type-csharp .highlight .kt { color: #0000FF } 65 | .type-csharp .highlight .nf { color: #000000; font-weight: normal } 66 | .type-csharp .highlight .nc { color: #2B91AF } 67 | .type-csharp .highlight .nn { color: #000000 } 68 | .type-csharp .highlight .s { color: #A31515 } 69 | .type-csharp .highlight .sc { color: #A31515 } 70 | -------------------------------------------------------------------------------- /general-use/declaring-custom-javascript-methods.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title : Declaring Custom JavaScript Methods 4 | group: General Use 5 | 6 | --- 7 | 8 | Another nifty feature of remote JavaScript objects is that you can declare custom methods to be handled in C++ and invoke them from JavaScript. 9 | 10 | ## Declaring Custom Methods 11 | 12 | Here's an example: 13 | 14 | {% highlight cpp %} 15 | my_object->SetCustomMethod(WSLit("myCallback"), false); 16 | {% endhighlight %} 17 | 18 | The above code would add a new method, `myCallback`, to `MyObject` that, when called from the page via Javascript, will invoke `JSMethodHandler::OnMethodCall` with the object's remote ID, the name of the callback, and the arguments passed, if any. 19 | 20 | For example, say you made a button that calls “myCallback” with a single string argument (”hello!”) when clicked: 21 | 22 | {% highlight html %} 23 | 25 | {% endhighlight %} 26 | 27 | You could then intercept this event in `JSMethodHandler::OnMethodCall` (you’ll need to register your JSMethodHandler first via `WebView::set_js_method_handler`): 28 | 29 | {% highlight cpp %} 30 | void MyHandler::OnMethodCall(WebView* caller, 31 | unsigned int remote_object_id, 32 | const WebString& method_name, 33 | const JSArray& args) { 34 | if(remote_object_id == my_object_id && 35 | method_name == WSLit("myCallback")) 36 | WebString value = args[0].toString(); // value is 'hello!' 37 | } 38 | {% endhighlight %} 39 | 40 | ### Remote ID Pitfalls 41 | 42 | Notice that `JSMethodHandler::OnMethodCall` only passes you `remote_object_id`. This is a unique ID for each remote object. If you try to bind a custom method to some temporary DOM object and that object goes away for whatever reason (page navigation, DOM change, etc.) your event may no longer be called. 43 | 44 | If you would like to expose a consistent event API for pages to invoke application-wide events, you should instead create a Global JavaScript Object (which has a consistent remote ID and persists through all pages) and bind custom methods to that. 45 | 46 | ## Declaring Methods with Return Values 47 | 48 | You can also declare custom methods with return values by specifying `true` for the second parameter of `JSObject::SetCustomMethod`: 49 | 50 | {% highlight cpp %} 51 | my_object->SetCustomMethod(WSLit("myCallback2"), true); 52 | {% endhighlight %} 53 | 54 | Now, when a user calls `MyObject.myCallback2` from JavaScript, it will make a synchronous call to `JSMethodHandler::OnMethodCallWithReturnValue`: 55 | 56 | {% highlight cpp %} 57 | JSValue MyHandler::OnMethodCallWithReturnValue(WebView* caller, 58 | unsigned int remote_object_id, 59 | const WebString& method_name, 60 | const JSArray& args) { 61 | if(remote_object_id == my_object_id && 62 | method_name == WSLit("myCallback2")) 63 | return JSValue(WSLit("banana")); 64 | 65 | return JSValue::Undefined(); 66 | } 67 | {% endhighlight %} 68 | 69 | {% highlight js %} 70 | var result = MyObject.myCallback2(); 71 | // result is now 'banana' 72 | {% endhighlight %} 73 | 74 | ### Limitations and Warnings 75 | 76 | You must be extra-careful when using custom methods with return values. 77 | 78 | First, this type of callback is dispatched synchronously and blocks the child-process until the call returns. This is bad for performance (because it must make a round-trip) and can potentially cause deadlocks if you attempt to (directly or indirectly) make a call to a synchronous API method from within the callback. 79 | 80 | You should try to use non-blocking methods (without return values) if at all possible. 81 | 82 | The other limitation of methods with return values is that it __cannot pass any remote JSObjects in the list of arguments__. The reason for this is because all methods of remote JSObjects must be dispatched synchronously to the child-process and so it would prompt a deadlock if we passed these back and you tried to make a call on them. 83 | 84 | -------------------------------------------------------------------------------- /tutorials/tutorial-2-displaying-your-first-page.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title : Tutorial 2 - Displaying Your First Page 4 | group: Tutorials 5 | weight: 2 6 | 7 | --- 8 | 9 |

      In this tutorial, we'll load our own HTML into a WebView and display it within a window.

      10 | 11 | ### Start With This Code 12 | 13 | It's quite a bit of work to set up an empty Windows GDI or Mac OSX Cocoa application. To save some time we've gone ahead and done some of the work for you. 14 | 15 | Start by downloading the framework below and following the README for your platform: 16 | 17 | * [Tutorial Framework for Awesomium (GitHub ZIP)](https://github.com/awesomium/tutorial-framework/archive/master.zip) 18 | 19 | #### Windowed WebViews 20 | 21 | It's important to note that we will be using Windowed WebViews (as opposed to Offscreen WebViews) with the Tutorial Framework. These views render directly to a platform-specific graphics surface and capture input as well. 22 | 23 | ### Loading Custom HTML 24 | 25 | After setting up your project using the tutorial framework, open up `main.cc` and find the following code: 26 | 27 | {% highlight cpp %} 28 | // Inherited from Application::Listener 29 | virtual void OnLoaded() { 30 | view_ = View::Create(500, 300); 31 | // < Set up your View here. > 32 | } 33 | {% endhighlight %} 34 | 35 | The `OnLoaded` method is called within the tutorial framework once the application has finished launching. This is your best chance to set up your WebViews and make them do interesting things. 36 | 37 | The framework uses a special wrapper class called `View` which consists of a platform window and a WebView. Notice the code above creates one View with dimensions of 500x300. 38 | 39 | If you ran this code right now, nothing would be displayed because the WebView contains no content. Let's fix that. 40 | 41 | Replace the `// ` code with the following: 42 | 43 | {% highlight cpp %} 44 | // Inherited from Application::Listener 45 | virtual void OnLoaded() { 46 | view_ = View::Create(500, 300); 47 | 48 | WebURL url(WSLit("data:text/html,

      Hello World

      ")); 49 | view_->web_view()->LoadURL(url); 50 | } 51 | {% endhighlight %} 52 | 53 | If you build and run this code, you should get something that looks likes this: 54 | 55 | ![Screenshot 1](/assets/images/tutorial-2/screen-1.png) 56 | 57 | #### Data URIs 58 | 59 | You'll notice that we used a special type of URL called a "Data URI" to load our custom HTML into our WebView. This is a quick and easy way to pass strings of HTML but it definitely is not the best way. 60 | 61 | #### Local HTML Files 62 | 63 | A better way might be to store our HTML content in a local file alongside our application. 64 | 65 | Create a new HTML file named `app.html` somewhere on your hard drive and add the following content to it: 66 | 67 | {% highlight html %} 68 | 69 | 70 |

      Hello World

      71 | 74 | 75 | 76 | {% endhighlight %} 77 | 78 | Now let's modify our code so that it loads our local HTML file instead, you'll need to edit the path so that it points to your file: 79 | 80 | {% highlight cpp %} 81 | // Inherited from Application::Listener 82 | virtual void OnLoaded() { 83 | view_ = View::Create(500, 300); 84 | 85 | WebURL url(WSLit("file:///C:/Users/awesomium/Documents/app.html")); 86 | view_->web_view()->LoadURL(url); 87 | } 88 | {% endhighlight %} 89 | 90 | If everything went as expected, you should get something similar to the following: 91 | 92 | ![Screenshot 2](/assets/images/tutorial-2/screen-2.png) 93 | 94 | #### Custom Data Sources 95 | 96 | Loading local files is a great solution if you don't mind distributing all of your interface assets in one of your application's folders. 97 | 98 | If you need a little more security or already have your own resource loader, we recommend taking a look at our [DataSource API](/general-use/using-data-sources.html) for a better approach. 99 | 100 | ### Further Reading 101 | 102 | * [Tutorial 3 - Hooking Up Events](/tutorials/tutorial-3-hooking-up-events.html) 103 | -------------------------------------------------------------------------------- /getting-started/setting-up-on-macosx.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title : Setting Up on Mac OSX 4 | group: Getting Started 5 | weight: 2 6 | 7 | --- 8 | 9 | > These notes are for developing a C++ application. If you are a developing a .NET/C# application please see our [.NET Wiki](http://wiki.awesomium.net/getting-started/) instead. 10 | 11 | ### Checklist 12 | 13 | Before we begin, you'll need the following: 14 | 15 | * The latest Awesomium 1.7 SDK for Mac OSX (download it [here](http://www.awesomium.com/download)) 16 | * An Intel Mac running Mac OS X 10.6 (“Snow Leopard”) or higher. 17 | * XCode 3.1.2 or higher 18 | 19 | ### Install the SDK 20 | 21 | Run the installer and follow the on-screen instructions. 22 | 23 | Once installation is complete you should find samples under your `/Applications` directory and a copy of `Awesomium.framework` at `/Library/Frameworks` 24 | 25 | ### Set up your project 26 | 27 | #### Configure project settings 28 | 29 | 1. Create a new project in XCode (either a Cocoa Application or Command Line Tool). 30 | 1. Double click your project to open Project Info and select the **Build** tab. 31 | 1. Select **All Configurations** in the **Configuration** drop-down list. 32 | 1. Under the **Architectures** property, make sure **32-bit Universal** is selected. 33 | 1. Under the **Valid Architectures** property, remove all architectures except **i386**. 34 | 1. Under the **Framework Search Paths** property (you may need to scroll down a bit to find it), add the path that contains the Awesomium.framework you copied earlier. 35 | 36 | #### Link against the framework 37 | 38 | To use Awesomium in your Mac OSX application, you will need to link against the Awesomium framework. 39 | 40 | There are actually a couple of ways you can do this: 41 | 42 | * Drag and drop **Awesomium.framework** onto the name of your project in XCode's **Groups & Files** panel. In the dialog that appears, make sure your project is selected under **Add To Targets**. 43 | * OR double-click the name of your Application under the **Targets** list in XCode's **Groups & Files** panel. Select the **General** tab and then click the **+** symbol under **Linked Libraries**. Click **Add Other** at the bottom of the dialog that appears and then browse to and select **Awesomium.framework**. 44 | 45 | #### Copy the framework to your build distribution 46 | 47 | If you don't wish to install `Awesomium.framework` to your users' `/Library/Frameworks` folder, there are a couple other ways to bundle the framework with your application based on what you're building. 48 | 49 | ##### If your project is using an Application Bundle (e.g., you're creating a **Cocoa Application**): 50 | 51 | 1. Right-click your Application's name under **Targets** in XCode's **Groupes & Files** panel. 52 | 1. Select Add -> New Build Phase -> New Copy Files Build Phase. 53 | 1. In the dialog that appears, select **Frameworks** under the **Destination** drop-down list. 54 | 1. Close the dialog. 55 | 1. Expand your Application's list of build phases (just click the little triangle next to your Application's name under **Targets** to expand the list). 56 | 1. Drag and drop **Awesomium.framework** onto the **Copy Files** build phase that you just created (should be the one at the bottom of the list). 57 | 1. The Awesomium framework should automatically be copied into your Application Bundle every time you build your application. 58 | 59 | ##### If your project is NOT using an Application Bundle (e.g., you're creating a **Shell Tool**): 60 | 61 | 1. Create a folder named **Frameworks** in the directory *above* the directory that contains your built executable (this will usually end up being the `build` directory of your XCode project). 62 | 2. Copy **Awesomium.framework** to the **Frameworks** folder. 63 | 3. Your directory structure should look like the following: 64 | 65 | ¦ 66 | +---SomeDirectory 67 | ¦ +---YourExecutable 68 | ¦ 69 | +---Frameworks 70 | +---Awesomium.framework 71 | 72 | 73 | ### Include the API 74 | 75 | To include the entire API for Awesomium in your source files, you simply need to include **WebCore.h**. 76 | 77 | #include 78 | 79 | ### Further Reading 80 | 81 | * [Basic Concepts](basic-concepts.html) 82 | 83 | 84 | -------------------------------------------------------------------------------- /getting-started/basic-concepts.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title : Basic Concepts 4 | group: Getting Started 5 | weight: 4 6 | 7 | --- 8 | {% include JB/setup %} 9 | 10 | There's only a few key concepts that you'll need to be familiar with to use Awesomium. 11 | 12 | ### Including the API 13 | 14 | To use the majority of the API, you simply need to include one header: 15 | 16 | {% highlight cpp %} 17 | #include 18 | {% endhighlight %} 19 | 20 | ### The WebString 21 | 22 | WebString is used to represent strings throughout our C++ API, it is a UTF-16 container format with some helpers for converting to/from UTF-8. Here's an example of how to create one: 23 | 24 | {% highlight cpp %} 25 | WebString my_string = WebString::CreateFromUTF8("Hello", strlen("Hello")); 26 | size_t len = my_string.length(); // length is 5 27 | {% endhighlight %} 28 | 29 | #### Using WebString with the STL 30 | We provide some additional convenience methods for converting to different string types inside the `STLHelpers.h` header. If your application uses the STL it's a good idea to include this header. Here's an example of use: 31 | 32 | {% highlight cpp %} 33 | #include 34 | 35 | // Initialize my_string with a C-string literal 36 | WebString my_string(WSLit("Hello World!")); 37 | 38 | // Print my_string to the console 39 | std::cout << my_string << std::endl; 40 | 41 | // Convert my_string to a std::string 42 | std::string my_utf8_string = ToString(my_string); 43 | {% endhighlight %} 44 | 45 | ### The WebCore 46 | The WebCore is the "core" of Awesomium-- it manages the lifetime of all WebViews (more on that later) and maintains useful services like resource caching and network connections. 47 | 48 | Generally, you should create an instance of the WebCore at the beginning of your program and then destroy the instance at the end of your program. Here's an example of how to create it: 49 | 50 | {% highlight cpp %} 51 | #include 52 | #include 53 | 54 | using namespace Awesomium; 55 | 56 | int main() { 57 | WebCore* web_core = WebCore::Initialize(WebConfig()); 58 | 59 | WebCore::Shutdown(); 60 | 61 | return 0; 62 | } 63 | {% endhighlight %} 64 | 65 | #### Configuring the WebCore 66 | You can configure the WebCore with some global settings via the first parameter of its constructor. Here's an example with a custom log path: 67 | 68 | {% highlight cpp %} 69 | WebConfig config; 70 | config.log_path = WSLit("C:\\My Documents\\My Custom Log Path"); 71 | config.log_level = kLogLevel_Normal; 72 | 73 | WebCore* web_core = WebCore::Initialize(config); 74 | {% endhighlight %} 75 | 76 | #### Updating the WebCore 77 | In your main program loop, make sure to call WebCore::update to give it a chance to do some behind-the-scenes work. Here's a psuedo-example: 78 | 79 | {% highlight cpp %} 80 | void UpdateApplication() { 81 | web_core->Update(); 82 | // do other application stuff here 83 | } 84 | {% endhighlight %} 85 | 86 | ### The WebSession 87 | A WebSession is responsible for storing all user-generated data (cookies, cache, authentication, etc.). It can either be purely in-memory or saved to disk (you will need to provide a writeable path to store the data at runtime). 88 | 89 | You can create a WebSession like so: 90 | 91 | {% highlight cpp %} 92 | WebSession* my_session = web_core->CreateWebSession( 93 | WSLit("C:\\Session Data Path"), WebPreferences()); 94 | {% endhighlight %} 95 | 96 | > See [this article](/general-use/using-web-sessions.html) for more info about WebSessions. 97 | 98 | ### The WebView 99 | A WebView is like a tab in a browser. You load pages into a WebView, interact with it, and render it on-the-fly to a certain graphics surface. You create WebViews using the WebCore, here's an example: 100 | 101 | {% highlight cpp %} 102 | // Create a new WebView with a width and height of 500px 103 | WebView* my_web_view = web_core->CreateWebView(500, 500); 104 | {% endhighlight %} 105 | 106 | There are two types of WebViews: __offscreen__ and __windowed__. 107 | 108 | > See [this article](/general-use/introduction-to-web-views.html) for more info about WebViews. 109 | 110 | ### Further Reading 111 | 112 | * [Tutorial 1 - Hello Awesomium](/tutorials/tutorial-1-hello-awesomium.html) 113 | 114 | -------------------------------------------------------------------------------- /tutorials/tutorial-1-hello-awesomium.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title : Tutorial 1 - Hello Awesomium 4 | group: Tutorials 5 | weight: 1 6 | 7 | --- 8 | 9 |

      In this tutorial, we'll load a remote page into a WebView and save the result to a JPEG.

      10 | 11 | ### Start With This Code 12 | 13 | > Make sure you've read the [Getting Started](http://wiki.awesomium.com/getting-started/) articles before we begin. 14 | 15 | Create a new file called __main.cc__ and add the following code to it: 16 | 17 | {% highlight cpp %} 18 | // Various included headers 19 | #include 20 | #include 21 | #include 22 | 23 | // Various macro definitions 24 | #define WIDTH 800 25 | #define HEIGHT 600 26 | #define URL "http://www.google.com" 27 | 28 | using namespace Awesomium; 29 | 30 | // Our main program 31 | int main() { 32 | 33 | // Your code goes here. 34 | 35 | return 0; 36 | } 37 | {% endhighlight %} 38 | 39 | 40 | ### Initialize the Framework 41 | 42 | The first thing we need to do in our program is initialize the WebCore. The WebCore singleton is resposible for creating views, loading resources, and dispatching events. 43 | 44 | Let's initialize the WebCore using the default configuration settings, add the following to your `main()`: 45 | 46 | {% highlight cpp %} 47 | // Create the WebCore singleton with default configuration 48 | WebCore* web_core = WebCore::Initialize(WebConfig()); 49 | {% endhighlight %} 50 | 51 | ### Create the WebView 52 | 53 | Now we can create a WebView (similar to a tab in Chrome) using the WebCore we just created. Let's create a WebView with the default settings (offscreen rendering surface, all session data will be stored in memory): 54 | 55 | {% highlight cpp %} 56 | // Create a new WebView instance with a certain width and height 57 | WebView* view = web_core->CreateWebView(WIDTH, HEIGHT); 58 | {% endhighlight %} 59 | 60 | ### Load a Page 61 | 62 | Let's start loading a web-page into our view. It's a good time to mention that most API calls in Awesomium are asynchronous (they are not guaranteed to complete by the time the method returns). 63 | 64 | {% highlight cpp %} 65 | // Load a certain URL into our WebView instance 66 | WebURL url(WSLit(URL)); 67 | view->LoadURL(url); 68 | {% endhighlight %} 69 | 70 | By the way, `WSLit()` is a special helper function that lets you declare __WebString literals__. Most of our API uses UTF-16 strings (wrapped with `WebString`) but we added `WSLit()` so you can declare ASCII C-strings with minimal fuss. 71 | 72 | #### Wait Until the Page Has Finished Loading 73 | 74 | Now we need to wait for the view to finish loading the page. The easiest way to do this is to loop until `WebView::IsLoading` returns false. It's important that you always call `WebCore::Update` within your update loop to give the framework a chance to dispatch events. 75 | 76 | {% highlight cpp %} 77 | // Wait for our WebView to finish loading 78 | while (view->IsLoading()) 79 | web_core->Update(); 80 | 81 | // Sleep a bit and update once more to give scripts and plugins 82 | // on the page a chance to finish loading. 83 | Sleep(300); 84 | web_core->Update(); 85 | {% endhighlight %} 86 | 87 | ### Save the Rendered Page to a JPEG 88 | 89 | Since our WebView is being rendered offscreen, we need to save our rendering surface to a JPEG so we can see the result. 90 | 91 | You can access the surface of all offscreen WebViews by calling `WebView::surface()`. You will need to cast this surface to `BitmapSurface` (the default Surface type) to actually use it. 92 | 93 | {% highlight cpp %} 94 | // Get the WebView's rendering Surface. The default Surface is of 95 | // type 'BitmapSurface', we must cast it before we can use it. 96 | BitmapSurface* surface = (BitmapSurface*)view->surface(); 97 | 98 | // Make sure our surface is not NULL-- it may be NULL if the WebView 99 | // process has crashed. 100 | if (surface != 0) { 101 | // Save our BitmapSurface to a JPEG image in the current 102 | // working directory. 103 | surface->SaveToJPEG(WSLit("./result.jpg")); 104 | } 105 | {% endhighlight %} 106 | 107 | ### Clean Up 108 | 109 | Make sure to clean up everything that you create: 110 | 111 | {% highlight cpp %} 112 | view->Destroy(); 113 | 114 | WebCore::Shutdown(); 115 | {% endhighlight %} 116 | 117 | ### Further Reading 118 | 119 | * [Tutorial 2 - Displaying Your First Page](/tutorials/tutorial-2-displaying-your-first-page.html) 120 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | # This is the default format. 2 | # For more see: https://github.com/mojombo/jekyll/wiki/Permalinks 3 | permalink: /:categories/:year/:month/:day/:title 4 | 5 | exclude: [".rvmrc", ".rbenv-version", "README.md", "Rakefile", "changelog.md"] 6 | auto: true 7 | pygments: true 8 | 9 | # Themes are encouraged to use these universal variables 10 | # so be sure to set them if your theme uses them. 11 | # 12 | title : Awesomium Wiki 13 | tagline: Wiki for Awesomium, an HTML UI Engine for Native Apps 14 | author : 15 | name : Awesomium Team 16 | email : hello@awesomium.com 17 | github : awesomium 18 | twitter : awesomium 19 | 20 | groups: 21 | - name: Getting Started 22 | path: /getting-started 23 | - name: General Use 24 | path: /general-use 25 | - name: Tutorials 26 | path: /tutorials 27 | - name: Changelogs 28 | path: /changelogs 29 | - name: Licensing 30 | path: /licensing 31 | 32 | # The production_url is only used when full-domain names are needed 33 | # such as sitemap.txt 34 | # Most places will/should use BASE_PATH to make the urls 35 | # 36 | # If you have set a CNAME (pages.github.com) set your custom domain here. 37 | # Else if you are pushing to username.github.com, replace with your username. 38 | # Finally if you are pushing to a GitHub project page, include the project name at the end. 39 | # 40 | production_url : http://wiki.awesomium.com 41 | 42 | # All Jekyll-Bootstrap specific configurations are namespaced into this hash 43 | # 44 | JB : 45 | version : 0.2.13 46 | 47 | # All links will be namespaced by BASE_PATH if defined. 48 | # Links in your website should always be prefixed with {{BASE_PATH}} 49 | # however this value will be dynamically changed depending on your deployment situation. 50 | # 51 | # CNAME (http://yourcustomdomain.com) 52 | # DO NOT SET BASE_PATH 53 | # (urls will be prefixed with "/" and work relatively) 54 | # 55 | # GitHub Pages (http://username.github.com) 56 | # DO NOT SET BASE_PATH 57 | # (urls will be prefixed with "/" and work relatively) 58 | # 59 | # GitHub Project Pages (http://username.github.com/project-name) 60 | # 61 | # A GitHub Project site exists in the `gh-pages` branch of one of your repositories. 62 | # REQUIRED! Set BASE_PATH to: http://username.github.com/project-name 63 | # 64 | # CAUTION: 65 | # - When in Localhost, your site will run from root "/" regardless of BASE_PATH 66 | # - Only the following values are falsy: ["", null, false] 67 | # - When setting BASE_PATH it must be a valid url. 68 | # This means always setting the protocol (http|https) or prefixing with "/" 69 | BASE_PATH : false 70 | 71 | # By default, the asset_path is automatically defined relative to BASE_PATH plus the enabled theme. 72 | # ex: [BASE_PATH]/assets/themes/[THEME-NAME] 73 | # 74 | # Override this by defining an absolute path to assets here. 75 | # ex: 76 | # http://s3.amazonaws.com/yoursite/themes/watermelon 77 | # /assets 78 | # 79 | ASSET_PATH : false 80 | 81 | # These paths are to the main pages Jekyll-Bootstrap ships with. 82 | # Some JB helpers refer to these paths; change theme here if needed. 83 | # 84 | archive_path: /archive.html 85 | categories_path : /categories.html 86 | tags_path : /tags.html 87 | 88 | # Settings for comments helper 89 | # Set 'provider' to the comment provider you want to use. 90 | # Set 'provider' to false to turn commenting off globally. 91 | # 92 | comments : 93 | provider : disqus 94 | disqus : 95 | short_name : jekyllbootstrap 96 | livefyre : 97 | site_id : 123 98 | intensedebate : 99 | account : 123abc 100 | facebook : 101 | appid : 123 102 | num_posts: 5 103 | width: 580 104 | colorscheme: light 105 | 106 | # Settings for analytics helper 107 | # Set 'provider' to the analytics provider you want to use. 108 | # Set 'provider' to false to turn analytics off globally. 109 | # 110 | analytics : 111 | provider : google 112 | google : 113 | tracking_id : 'UA-33688566-1' 114 | getclicky : 115 | site_id : 116 | mixpanel : 117 | token : '_MIXPANEL_TOKEN_' 118 | 119 | # Settings for sharing helper. 120 | # Sharing is for things like tweet, plusone, like, reddit buttons etc. 121 | # Set 'provider' to the sharing provider you want to use. 122 | # Set 'provider' to false to turn sharing off globally. 123 | # 124 | sharing : 125 | provider : false 126 | 127 | # Settings for all other include helpers can be defined by creating 128 | # a hash with key named for the given helper. ex: 129 | # 130 | # pages_list : 131 | # provider : "custom" 132 | # 133 | # Setting any helper's provider to 'custom' will bypass the helper code 134 | # and include your custom code. Your custom file must be defined at: 135 | # ./_includes/custom/[HELPER] 136 | # where [HELPER] is the name of the helper you are overriding. 137 | 138 | -------------------------------------------------------------------------------- /general-use/introduction-to-web-views.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title : Introduction to Web-Views 4 | group: General Use 5 | weight: 2 6 | 7 | --- 8 | 9 | ### What is a WebView? 10 | 11 | A WebView is like a tab in a browser. You load pages into a WebView, interact with it, and display it in some pre-defined manner. 12 | 13 | There are two different types of WebViews: 14 | 15 | #### Offscreen Views 16 | 17 | Offscreen Views are rendered continuously to a pixel-buffer surface (see `WebView::surface()`). It is your responsibility to display this surface in your application and pass all mouse/keyboard events. This gives you the flexibility to display web-content in any environment (such as a 3D engine or headless renderer). 18 | 19 | All WebViews are Offscreen by default. 20 | 21 | #### Windowed Views 22 | 23 | Windowed Views are rendered directly to a platform window (HWND, NSView, etc.) and capture all input themselves. 24 | 25 | On MS Windows, you should call `WebView::set_parent_window` immediately after creating this type of WebView (the view cannot create a window until a parent is set). 26 | 27 | On Mac OSX, you will need to retrieve `WebView::window` after creating this type of WebView and add it to your own container to display the view in your application. 28 | 29 | ### Creating a WebView 30 | 31 | You create WebViews using the WebCore, here's an example: 32 | 33 | {% highlight cpp %} 34 | // Create an offscreen WebView 35 | WebView* view = web_core->CreateWebView(500, 500); 36 | {% endhighlight %} 37 | 38 | Here's an example of how to create a windowed WebView on MS Windows: 39 | 40 | {% highlight cpp %} 41 | // Create a windowed WebView 42 | WebView* view = web_core->CreateWebView(500, 500, 0, kWebViewType_Window); 43 | view->set_parent_window(parent_hwnd); 44 | {% endhighlight %} 45 | 46 | ### Loading Content 47 | 48 | The primary way to load content into a WebView is via `WebView::LoadURL`. For example, to begin navigating a WebView to Google, you would call: 49 | 50 | {% highlight cpp %} 51 | WebURL url(WSLit("http://www.google.com")); 52 | view->LoadURL(url); 53 | {% endhighlight %} 54 | 55 | All URLs should be properly formatted before passing it to LoadURL. You can check if a URL is valid via `WebURL::IsValid`: 56 | 57 | {% highlight cpp %} 58 | WebURL url(some_url_string); 59 | if (!url.IsValid()) 60 | std::cerr << "Error! URL was unable to be parsed."; 61 | {% endhighlight %} 62 | 63 | LoadURL makes it really easy to load remote content on the Internet, but what about local resources? 64 | 65 | #### Defining a Custom DataSource 66 | 67 | If you would like to load local resources with your application we recommend using DataSource. This powerful bit of API allows you to provide a custom resource loader for a set of URLs that match a certain prefix. 68 | 69 | > See [this article](using-data-sources.html) for more information on using DataSource. 70 | 71 | ### Asynchronous API 72 | 73 | Awesomium adopts a similar multi-process architecture to Chrome. Each WebView is actually isolated and rendered in a separate process. 74 | 75 | Most method calls are sent via a piped message to the child-process and may not complete immediately. To be notified of different events, see the following section on event listeners. 76 | 77 | You should take extra care with the few methods that are actually synchronous, you can use `WebView::last_error()` to check if there was an error dispatching a synchronous method call. For example, `WebView::ExecuteJavascriptWithResult` is sent synchronously because it must return a value: 78 | 79 | {% highlight cpp %} 80 | JSValue result = view->ExecuteJavascriptWithResult(script, frame); 81 | if (view->last_error()) 82 | std::cerr << "There was an error calling this synchronous method". 83 | {% endhighlight %} 84 | 85 | ### Registering Listeners 86 | 87 | The WebViewListener namespace contains a suite of special classes that you can use to respond to certain events in a WebView. 88 | 89 | For example, to listen for all load-related events, you would simply make your own subclass of WebViewListener::Load and then register an instance of it to a certain WebView using `WebView::set_load_listener`. Here's a psuedo-example: 90 | 91 | {% highlight cpp %} 92 | // Define our WebViewListener::Load subclass 93 | class MyLoadListener : public Awesomium::WebViewListener::Load { 94 | // ... All the overriden WebViewListener::Load methods go here 95 | }; 96 | 97 | // Create an instance of MyLoadListener and register it to a certain WebView 98 | MyLoadListener* my_load_listener = new MyLoadListener(); 99 | my_web_view->set_load_listener(my_load_listener); 100 | {% endhighlight %} 101 | 102 | Please note that all WebViewListener events are dispatched asynchronously (meaning that the event may arrive a few milliseconds after the event actually happened in the child-process). 103 | 104 | ### Cleaning Up 105 | 106 | You should call `WebView::Destroy` once you are done using the WebView. You should try to avoid making this call from one of the WebViewListener or JSMethodHandler callbacks. 107 | -------------------------------------------------------------------------------- /licensing/licensing-overview.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title : Licensing Overview 4 | group: Licensing 5 | weight: 1 6 | 7 | --- 8 | {% include JB/setup %} 9 | 10 | 11 | We currently offer 2 different licenses for Awesomium: 12 | 13 | * A **Free License** for free non-commercial use and free commercial-use by indie developers 14 | * A **Pro License** for use in a single commercial application 15 | 16 | Please see one of the sections below for more information: 17 | 18 | ### Free License 19 | 20 | We recognize the importance of Awesomium and want to get into the hands of as many developers as possible. That’s why we’ve made Awesomium **completely free for indie developers**. If your company made less than $100K in revenue last year, you qualify to use Awesomium for **commercial use** free-of-charge. 21 | 22 | If you are not an indie developer, but are developing an application for **Non-Commercial Use**, you may also use Awesomium for free. 23 | 24 | #### Non-Commercial Use Limitations 25 | 26 | * Cannot be used for products created with the intention for profit 27 | * Cannot be used for resale or other Commercial distribution 28 | * Cannot be used for products created for governmental use 29 | * Cannot be used for products intended to produce works, services, or data for Commercial use 30 | * Cannot be used for products that are either conducted or funded by a person or an entity engaged in the Commercial use, application or exploitation of works similar to the software 31 | 32 | #### Indie Commercial Use Limitations 33 | 34 | If your company ever makes more than $100k in revenue in any subsequent year while using the Free License, you must purchase a Pro License (or other commercial license) to continue using Awesomium in your application. 35 | 36 | ### Pro License 37 | 38 | Our Pro License allows you to use Awesomium in a single commercial application (defined by title), on any platform (Windows and Mac OSX) for a one-time, royalty-free fee of US$2900. 39 | 40 | You may use any version of Awesomium v1.X (eg. 1.6, 1.7, 1.8, etc.) in your application with this license. 41 | 42 | You can buy this license online [here](https://www.awesomium.com/buy/). 43 | 44 | #### Source-Code Access 45 | 46 | For pricing and terms regarding source code access, please [contact us](https://awesomium.wufoo.com/forms/contact-our-sales-team/). 47 | 48 | ### Other Licensing 49 | 50 | For all other licensing, please [contact us](https://awesomium.wufoo.com/forms/contact-our-sales-team/). 51 | 52 | ### Premium Support 53 | 54 | We currently do not offer premium, priority support plans for our commercial licensees. We will announce such plans if they become available in the future. 55 | 56 | ### Licensing for Engines/Libraries 57 | 58 | Our Pro License only allows use of our library within a single application. If you are interested in building a commercial library, framework, or engine with our product, please [contact us](https://awesomium.wufoo.com/forms/contact-our-sales-team/). 59 | 60 | ### Frequently Asked Questions: 61 | 62 | **Q: Do you allow modification / redlines of the Pro license agreement?** 63 | 64 | **A:** No, our license agreement is non-negotiable. 65 | 66 | **Q: Do you offer discounts for purchases of multiple Pro licenses?** 67 | 68 | **A:** We do not offer batch discounts at this time. 69 | 70 | **Q: What are the details of support offered with each license?** 71 | 72 | **A:** We maintain a community forum so that all users of our product can ask questions and get answers. We do not offer paid support or custom engineering plans at this time. 73 | 74 | **Q: Can I use Awesomium in my open-source application / tool / library under the Free License?** 75 | 76 | **A:** Yes, as long as your project is non-commercial (does not create works or services for a profit). If your project is a library that may be used for commercial projects, your users will need to acquire an additional Pro License from us. 77 | 78 | **Q: We're interested in purchasing a license for another custom (end-user).** 79 | 80 | **A:** Please [contact us](https://awesomium.wufoo.com/forms/contact-our-sales-team/). 81 | 82 | **Q: We're interested in becoming a reseller for Awesomium.** 83 | 84 | **A:** We are currently not engaging in any reseller partnerships at this time. 85 | 86 | **Q: What methods of payment do you accept?** 87 | 88 | **A:** For purchases made through our website, we accept Visa, MasterCard, American Express, and Discover. For invoices, we accept payment via wire transfer or business check. 89 | 90 | **Q: Do you accept purchase orders?** 91 | 92 | **A:** Yes, please [contact us](https://awesomium.wufoo.com/forms/contact-our-sales-team/). 93 | 94 | **Q: What happens when you release Awesomium 2.X?** 95 | 96 | **A:** We currently do not expect Awesomium 2.X for quite some time (we release a new 1.X update about once a year). With that being said, we will offer discounts for existing commercial licensees should they choose to upgrade to 2.X. 97 | 98 | **Q: When will you release a 64-bit build for Windows?** 99 | 100 | **A:** It is on our roadmap, no definite date available yet. -------------------------------------------------------------------------------- /assets/themes/twitter/css/style.css: -------------------------------------------------------------------------------- 1 | /* Override some defaults */ 2 | html, body { 3 | background-color: #eee; 4 | } 5 | .navbar { 6 | margin-bottom: 0; 7 | } 8 | .container > footer { 9 | margin-top: 20px; 10 | } 11 | .container > footer p { 12 | text-align: center; /* center align it with the container */ 13 | } 14 | 15 | /* The white background content wrapper */ 16 | .content { 17 | background-color: #fff; 18 | padding: 20px; 19 | margin: 0 -20px; /* negative indent the amount of the padding to maintain the grid system */ 20 | -webkit-border-radius: 0 0 6px 6px; 21 | -moz-border-radius: 0 0 6px 6px; 22 | border-radius: 0 0 6px 6px; 23 | -webkit-box-shadow: 0 1px 2px rgba(0,0,0,.15); 24 | -moz-box-shadow: 0 1px 2px rgba(0,0,0,.15); 25 | box-shadow: 0 1px 2px rgba(0,0,0,.15); 26 | } 27 | 28 | /* Page header tweaks */ 29 | .page-header { 30 | background-color: #f5f5f5; 31 | padding: 20px 20px 10px; 32 | margin: -20px -20px 20px; 33 | } 34 | 35 | .topbar .btn { 36 | border: 0; 37 | } 38 | 39 | 40 | /* tag_box ======================================================== */ 41 | 42 | .tag_box { 43 | list-style:none; 44 | margin:0; 45 | padding:5px 0 ; 46 | overflow:hidden; 47 | } 48 | .tag_box li { 49 | line-height:28px; 50 | } 51 | .tag_box.inline li { 52 | float:left; 53 | } 54 | .tag_box a { 55 | padding: 3px 6px; 56 | margin: 2px; 57 | background: #eee; 58 | color:#005F6B; 59 | border-radius: 3px; 60 | text-decoration:none; 61 | } 62 | .tag_box a span{ 63 | vertical-align:super; 64 | font-size:0.8em; 65 | } 66 | .tag_box a.active { 67 | background:#57A957; 68 | border:1px solid #4C964D; 69 | color:#FFF; 70 | } 71 | .highlight { background: #ffffff; } 72 | .highlight .c { color: #999988; font-style: italic } /* Comment */ 73 | .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ 74 | .highlight .k { font-weight: bold } /* Keyword */ 75 | .highlight .o { font-weight: bold } /* Operator */ 76 | .highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */ 77 | .highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */ 78 | .highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */ 79 | .highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */ 80 | .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ 81 | .highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */ 82 | .highlight .ge { font-style: italic } /* Generic.Emph */ 83 | .highlight .gr { color: #aa0000 } /* Generic.Error */ 84 | .highlight .gh { color: #999999 } /* Generic.Heading */ 85 | .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ 86 | .highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */ 87 | .highlight .go { color: #888888 } /* Generic.Output */ 88 | .highlight .gp { color: #555555 } /* Generic.Prompt */ 89 | .highlight .gs { font-weight: bold } /* Generic.Strong */ 90 | .highlight .gu { color: #aaaaaa } /* Generic.Subheading */ 91 | .highlight .gt { color: #aa0000 } /* Generic.Traceback */ 92 | .highlight .kc { font-weight: bold } /* Keyword.Constant */ 93 | .highlight .kd { font-weight: bold } /* Keyword.Declaration */ 94 | .highlight .kp { font-weight: bold } /* Keyword.Pseudo */ 95 | .highlight .kr { font-weight: bold } /* Keyword.Reserved */ 96 | .highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */ 97 | .highlight .m { color: #009999 } /* Literal.Number */ 98 | .highlight .s { color: #d14 } /* Literal.String */ 99 | .highlight .na { color: #008080 } /* Name.Attribute */ 100 | .highlight .nb { color: #0086B3 } /* Name.Builtin */ 101 | .highlight .nc { color: #445588; font-weight: bold } /* Name.Class */ 102 | .highlight .no { color: #008080 } /* Name.Constant */ 103 | .highlight .ni { color: #800080 } /* Name.Entity */ 104 | .highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */ 105 | .highlight .nf { color: #990000; font-weight: bold } /* Name.Function */ 106 | .highlight .nn { color: #555555 } /* Name.Namespace */ 107 | .highlight .nt { color: #000080 } /* Name.Tag */ 108 | .highlight .nv { color: #008080 } /* Name.Variable */ 109 | .highlight .ow { font-weight: bold } /* Operator.Word */ 110 | .highlight .w { color: #bbbbbb } /* Text.Whitespace */ 111 | .highlight .mf { color: #009999 } /* Literal.Number.Float */ 112 | .highlight .mh { color: #009999 } /* Literal.Number.Hex */ 113 | .highlight .mi { color: #009999 } /* Literal.Number.Integer */ 114 | .highlight .mo { color: #009999 } /* Literal.Number.Oct */ 115 | .highlight .sb { color: #d14 } /* Literal.String.Backtick */ 116 | .highlight .sc { color: #d14 } /* Literal.String.Char */ 117 | .highlight .sd { color: #d14 } /* Literal.String.Doc */ 118 | .highlight .s2 { color: #d14 } /* Literal.String.Double */ 119 | .highlight .se { color: #d14 } /* Literal.String.Escape */ 120 | .highlight .sh { color: #d14 } /* Literal.String.Heredoc */ 121 | .highlight .si { color: #d14 } /* Literal.String.Interpol */ 122 | .highlight .sx { color: #d14 } /* Literal.String.Other */ 123 | .highlight .sr { color: #009926 } /* Literal.String.Regex */ 124 | .highlight .s1 { color: #d14 } /* Literal.String.Single */ 125 | .highlight .ss { color: #990073 } /* Literal.String.Symbol */ 126 | .highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */ 127 | .highlight .vc { color: #008080 } /* Name.Variable.Class */ 128 | .highlight .vg { color: #008080 } /* Name.Variable.Global */ 129 | .highlight .vi { color: #008080 } /* Name.Variable.Instance */ 130 | .highlight .il { color: #009999 } /* Literal.Number.Integer.Long */ 131 | -------------------------------------------------------------------------------- /general-use/introduction-to-javascript-integration.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title : Introduction to JavaScript Integration 4 | group: General Use 5 | weight: 5 6 | 7 | --- 8 | 9 |

      It's easy to communicate with web-pages using JavaScript; here's a quick overview of the classes you'll need to use.

      10 | 11 | ## JSValue Class 12 | 13 | The JSValue class is used as an intermediary to translate C++ types into Javascript variables and vice-versa. To get a better understanding of how this relationship works, here’s how types are mapped between Javascript and C++ using JSValue: 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |
      JavascriptC++
      Numberdouble or int
      Booleanbool
      StringWebString (UTF-16)
      ObjectJSObject
      ArrayJSArray
      NullJSValue::Null()
      UndefinedJSValue::Undefined()
      25 | 26 | 27 | ### JSValue Type: Strings 28 | 29 | You can get the string representation of any JSValue via `JSValue::ToString`. It is safe to call this on a JSValue of any type. 30 | 31 | ### JSValue Type: Objects 32 | 33 | Objects in Javascript are sort of like a "map" or "dictionary". Every key has a "string" type and every value can be any number of types. 34 | 35 | As specified in the table above, these Objects are modeled in C++ with the JSObject class. 36 | 37 | There are two types of JSObjects, **Local** and **Remote**. 38 | 39 | #### Local JSObjects 40 | 41 | Local objects only have properties (no custom methods) and are primarily used for declaring data to pass to methods. Local objects can be created using the JSObject constructor: 42 | 43 | 44 | {% highlight cpp %} 45 | JSObject my_object; 46 | my_object.SetProperty(WSLit("name"), WSLit("Bob")); 47 | my_object.SetProperty(WSLit("age"), 42) 48 | {% endhighlight %} 49 | 50 | #### Remote JSObjects 51 | 52 | Remote objects live within the V8 engine in a separate process and can have both Properties and Methods. 53 | 54 | For example, say you had an object ‘Person’ in JavaScript: 55 | 56 | {% highlight js %} 57 | var Person = { 58 | name: 'Bob', 59 | age: 22, 60 | }; 61 | {% endhighlight %} 62 | 63 | You could then interact with this object in C++: 64 | 65 | {% highlight cpp %} 66 | JSValue my_value = web_view->ExecuteJavascriptWithResult("Person"); 67 | 68 | if(my_value.IsObject()) { 69 | JSObject& person = my_value.ToObject(); 70 | 71 | WebString name = person.GetProperty(WSLit("name")).ToString(); 72 | // value of name is 'Bob' 73 | 74 | int age = person.GetProperty(WSLit("age")).ToInteger(); 75 | // value of age is '22' 76 | } 77 | {% endhighlight %} 78 | 79 | ##### Lifetime of Remote Objects 80 | 81 | All remote objects are reference-counted and collected by the V8 garbage collector. When you return an object to the main process via a JSObject proxy, this ref-count is incremented, and when the JSObject is destroyed, the ref-count is decremented. 82 | 83 | You can think of remote JSObjects as a pointer to a V8 object on the page. Every time you make a copy of a JSObject (via its copy-constructor), only the reference (remote ID) is copied; a deep copy is not made. 84 | 85 | When the V8 object goes away (usually due to a page navigation), the reference will no longer be valid and method calls may fail (see the section below). If you need an object to be persistent, you should create a Global JavaScript Object instead. 86 | 87 | ##### Handling Errors 88 | 89 | Method calls on Remote objects are proxied to the child-process and execute synchronously but may fail for various reasons (see `JSObject::last_error()`). 90 | 91 | {% highlight cpp %} 92 | JSValue foobar = my_object.GetProperty(WSLit("foobar")); 93 | if (my_object.last_error() != kError_None) { 94 | // handle error here (if any) 95 | } 96 | {% endhighlight %} 97 | 98 | ### JSValue Type: Arrays 99 | 100 | On the C++ side, Arrays are modeled as a vector of JSValues (wrapped as JSArray). 101 | 102 | So, for example, if you had the following array in Javascript: 103 | 104 | {% highlight js %} 105 | var myArray = [1, 2, "three", 4, "five"]; 106 | {% endhighlight %} 107 | 108 | You could access it in C++ like so: 109 | 110 | {% highlight cpp %} 111 | JSValue my_value = web_view->ExecuteJavascriptWithResult("myArray"); 112 | 113 | if(my_value.IsArray()) { 114 | JSArray& myArray = myValue.ToArray(); 115 | 116 | int first = myArray[0].ToInteger(); // value is '1' 117 | int second = myArray[1].ToInteger(); // value is '2' 118 | WebString third = myArray[2].ToString(); // value is 'three' 119 | } 120 | {% endhighlight %} 121 | 122 | ### Directly Calling JavaScript Functions 123 | 124 | You can call a Javascript function directly via `JSObject::Invoke`. 125 | 126 | Say you had the following function in Javascript: 127 | 128 | {% highlight js %} 129 | function addChatMessage(nickname, message) { 130 | chat = document.getElementById('chat'); 131 | chat.innerText = nickname + ": " + message; 132 | } 133 | {% endhighlight %} 134 | 135 | You can call it directly from C++ like so: 136 | 137 | {% highlight cpp %} 138 | // Retrieve the global 'window' object from the page 139 | JSValue window = web_view->ExecuteJavascriptWithResult( 140 | WSLit("window"), WSLit("")); 141 | 142 | if (window.IsObject()) { 143 | JSArray args; 144 | args.push_back("Bob"); 145 | args.push_back("Hello world!"); 146 | 147 | window.ToObject().Invoke(WSLit("addChatMessage"), args); 148 | } 149 | {% endhighlight %} 150 | 151 | ## Global JavaScript Objects 152 | 153 | Sometimes you need objects to persist between pages (such as when exposing Application objects to a WebView). In such cases, you should use Global Javascript Objects. 154 | 155 | > See [this article](using-global-javascript-objects.html) for more information on Global JavaScript Objects. 156 | 157 | ## Declaring Custom Method Callbacks 158 | 159 | Another nifty feature of remote Javascript objects is that you can declare custom methods to be handled in C++ and invoke them from JavaScript. 160 | 161 | > See [this article](declaring-custom-javascript-methods.html) for more information on Custom JavaScript Methods. 162 | -------------------------------------------------------------------------------- /tutorials/tutorial-3-hooking-up-events.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title : Tutorial 3 - Hooking Up Events 4 | group: Tutorials 5 | weight: 3 6 | 7 | --- 8 | 9 |

      In this tutorial, we'll show how to hook up events between the page and host application via JavaScript callbacks.

      10 | 11 | ### Start With This Code 12 | 13 | It's quite a bit of work to set up an empty Windows GDI or Mac OSX Cocoa application. To save some time we've gone ahead and done some of the work for you. 14 | 15 | Start by downloading the framework below and following the README for your platform: 16 | 17 | * [Tutorial Framework for Awesomium (GitHub ZIP)](https://github.com/awesomium/tutorial-framework/archive/master.zip) 18 | 19 | ### Create Your HTML Interface 20 | 21 | Create a new HTML file named `app.html` somewhere on your hard drive and add the following content to it: 22 | 23 | {% highlight html %} 24 | 25 | 26 |

      Welcome to My App

      27 | 28 | 29 | 30 | {% endhighlight %} 31 | 32 | ### Load The File 33 | 34 | After setting up your project using the tutorial framework, open up `main.cc` and find the following code: 35 | 36 | {% highlight cpp %} 37 | // Inherited from Application::Listener 38 | virtual void OnLoaded() { 39 | view_ = View::Create(500, 300); 40 | // < Set up your View here. > 41 | } 42 | {% endhighlight %} 43 | 44 | Replace the `// ` code with the following, you'll need to adjust the file path so that it points to your own `app.html`: 45 | 46 | {% highlight cpp %} 47 | // Inherited from Application::Listener 48 | virtual void OnLoaded() { 49 | view_ = View::Create(500, 300); 50 | 51 | WebView* web_view = view_->web_view(); 52 | 53 | WebURL url(WSLit("file:///C:/Users/awesomium/Documents/app.html")); 54 | web_view->LoadURL(url); 55 | } 56 | {% endhighlight %} 57 | 58 | Great, our app should now display the HTML file we created a little earlier. If you build and run now, you should get something that looks like this: 59 | 60 | ![Screenshot 1](/assets/images/tutorial-3/screen-1.png) 61 | 62 | You'll notice if you click the button right now, it won't do anything. We need to modify our application so that it responds to calls from `app.sayHello()` via JavaScript. 63 | 64 | ### Create Global JavaScript Object 65 | 66 | Let's create a special JavaScript object that will stay alive throughout the entire lifetime of our WebView. This will allow us to expose certain methods and properties that our pages can use via JavaScript. 67 | 68 | {% highlight cpp %} 69 | // Inherited from Application::Listener 70 | virtual void OnShutdown() { 71 | } 72 | 73 | void BindMethods(WebView* web_view) { 74 | // Create a global js object named 'app' 75 | JSValue result = web_view->CreateGlobalJavascriptObject(WSLit("app")); 76 | } 77 | {% endhighlight %} 78 | 79 | And then add the following code underneath your LoadURL code: 80 | 81 | {% highlight cpp %} 82 | // Inherited from Application::Listener 83 | virtual void OnLoaded() { 84 | view_ = View::Create(500, 300); 85 | 86 | WebView* web_view = view_->web_view(); 87 | 88 | BindMethods(web_view); 89 | 90 | WebURL url(WSLit("file:///C:/Users/awesomium/Documents/app.html")); 91 | web_view->LoadURL(url); 92 | } 93 | {% endhighlight %} 94 | 95 | ### Custom JavaScript Methods 96 | 97 | We now need to declare a custom method named `sayHello` to JavaScript and then bind this method to a callback in C++. 98 | 99 | To do this, we're going to save some time and use a special helper class included in the tutorial framework called `MethodDispatcher`. 100 | 101 | #### Include MethodDispatcher 102 | 103 | At the top of your application, add `#include "method_dispatcher.h"` underneath `#include "view.h"`: 104 | 105 | {% highlight cpp %} 106 | #include "application.h" 107 | #include "view.h" 108 | #include "method_dispatcher.h" 109 | #include 110 | #include 111 | #ifdef _WIN32 112 | #include 113 | #endif 114 | 115 | using namespace Awesomium; 116 | {% endhighlight %} 117 | 118 | Alright, now we just need to add an instance of `MethodDispatcher` to our application class. 119 | 120 | Find the top of your `TutorialApp` class definition and then go ahead and add `MethodDispatcher method_dispatcher_;` underneath `View* view_;`: 121 | 122 | {% highlight cpp %} 123 | using namespace Awesomium; 124 | 125 | class TutorialApp : public Application::Listener { 126 | Application* app_; 127 | View* view_; 128 | MethodDispatcher method_dispatcher_; 129 | public: 130 | {% endhighlight %} 131 | 132 | #### Define Our Callback 133 | 134 | Let's write the code that will be called by `app.sayHello()`. Add the following code underneath the `BindMethods` definition: 135 | 136 | {% highlight cpp %} 137 | void BindMethods(WebView* web_view) { 138 | // Create a global js object named 'app' 139 | JSValue result = web_view->CreateGlobalJavascriptObject(WSLit("app")); 140 | } 141 | 142 | // Bound to app.sayHello() in JavaScript 143 | void OnSayHello(WebView* caller, 144 | const JSArray& args) { 145 | app_->ShowMessage("Hello!"); 146 | } 147 | {% endhighlight %} 148 | 149 | #### Bind Our Method 150 | 151 | Now we just need to hook everything up using the `MethodDispatcher` instance. 152 | 153 | Replace your `BindMethods` definition with the following: 154 | 155 | {% highlight cpp %} 156 | void BindMethods(WebView* web_view) { 157 | // Create a global js object named 'app' 158 | JSValue result = web_view->CreateGlobalJavascriptObject(WSLit("app")); 159 | if (result.IsObject()) { 160 | // Bind our custom method to it. 161 | JSObject& app_object = result.ToObject(); 162 | method_dispatcher_.Bind(app_object, 163 | WSLit("sayHello"), 164 | JSDelegate(this, &TutorialApp::OnSayHello)); 165 | } 166 | 167 | // Bind our method dispatcher to the WebView 168 | web_view->set_js_method_handler(&method_dispatcher_); 169 | } 170 | {% endhighlight %} 171 | 172 | If you run your application now and click on the `Say Hello` button, you should get a little message box like the following: 173 | 174 | ![Screenshot 1](/assets/images/tutorial-3/screen-2.png) 175 | 176 | Congratulations, you've made your first interactive HTML interface! 177 | 178 | ### Complete Code 179 | 180 | In case you had trouble following the tutorial, the complete code for `main.cc` has been included below (just remember to edit the file path for your `app.html`): 181 | 182 | {% highlight cpp %} 183 | #include "application.h" 184 | #include "view.h" 185 | #include "method_dispatcher.h" 186 | #include 187 | #include 188 | #ifdef _WIN32 189 | #include 190 | #endif 191 | 192 | using namespace Awesomium; 193 | 194 | class TutorialApp : public Application::Listener { 195 | Application* app_; 196 | View* view_; 197 | MethodDispatcher method_dispatcher_; 198 | public: 199 | TutorialApp() 200 | : app_(Application::Create()), 201 | view_(0) { 202 | app_->set_listener(this); 203 | } 204 | 205 | virtual ~TutorialApp() { 206 | if (view_) 207 | app_->DestroyView(view_); 208 | if (app_) 209 | delete app_; 210 | } 211 | 212 | void Run() { 213 | app_->Run(); 214 | } 215 | 216 | // Inherited from Application::Listener 217 | virtual void OnLoaded() { 218 | view_ = View::Create(500, 300); 219 | WebView* web_view = view_->web_view(); 220 | 221 | BindMethods(web_view); 222 | 223 | WebURL url(WSLit("file:///C:/Users/awesomium/Documents/app.html")); 224 | web_view->LoadURL(url); 225 | } 226 | 227 | // Inherited from Application::Listener 228 | virtual void OnUpdate() { 229 | } 230 | 231 | // Inherited from Application::Listener 232 | virtual void OnShutdown() { 233 | } 234 | 235 | void BindMethods(WebView* web_view) { 236 | // Create a global js object named 'app' 237 | JSValue result = web_view->CreateGlobalJavascriptObject(WSLit("app")); 238 | if (result.IsObject()) { 239 | // Bind our custom method to it. 240 | JSObject& app_object = result.ToObject(); 241 | method_dispatcher_.Bind(app_object, 242 | WSLit("sayHello"), 243 | JSDelegate(this, &TutorialApp::OnSayHello)); 244 | } 245 | 246 | // Bind our method dispatcher to the WebView 247 | web_view->set_js_method_handler(&method_dispatcher_); 248 | } 249 | 250 | // Bound to app.sayHello() in JavaScript 251 | void OnSayHello(WebView* caller, 252 | const JSArray& args) { 253 | app_->ShowMessage("Hello!"); 254 | } 255 | }; 256 | 257 | #ifdef _WIN32 258 | int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE, wchar_t*, 259 | int nCmdShow) { 260 | #else 261 | int main() { 262 | #endif 263 | 264 | TutorialApp app; 265 | app.Run(); 266 | 267 | return 0; 268 | } 269 | 270 | {% endhighlight %} 271 | 272 | ### Further Reading 273 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require "rubygems" 2 | require 'rake' 3 | require 'yaml' 4 | require 'time' 5 | 6 | SOURCE = "." 7 | CONFIG = { 8 | 'version' => "0.2.13", 9 | 'themes' => File.join(SOURCE, "_includes", "themes"), 10 | 'layouts' => File.join(SOURCE, "_layouts"), 11 | 'posts' => File.join(SOURCE, "_posts"), 12 | 'post_ext' => "md", 13 | 'theme_package_version' => "0.1.0" 14 | } 15 | 16 | # Path configuration helper 17 | module JB 18 | class Path 19 | SOURCE = "." 20 | Paths = { 21 | :layouts => "_layouts", 22 | :themes => "_includes/themes", 23 | :theme_assets => "assets/themes", 24 | :theme_packages => "_theme_packages", 25 | :posts => "_posts" 26 | } 27 | 28 | def self.base 29 | SOURCE 30 | end 31 | 32 | # build a path relative to configured path settings. 33 | def self.build(path, opts = {}) 34 | opts[:root] ||= SOURCE 35 | path = "#{opts[:root]}/#{Paths[path.to_sym]}/#{opts[:node]}".split("/") 36 | path.compact! 37 | File.__send__ :join, path 38 | end 39 | 40 | end #Path 41 | end #JB 42 | 43 | # Usage: rake post title="A Title" [date="2012-02-09"] 44 | desc "Begin a new post in #{CONFIG['posts']}" 45 | task :post do 46 | abort("rake aborted: '#{CONFIG['posts']}' directory not found.") unless FileTest.directory?(CONFIG['posts']) 47 | title = ENV["title"] || "new-post" 48 | slug = title.downcase.strip.gsub(' ', '-').gsub(/[^\w-]/, '') 49 | begin 50 | date = (ENV['date'] ? Time.parse(ENV['date']) : Time.now).strftime('%Y-%m-%d') 51 | rescue Exception => e 52 | puts "Error - date format must be YYYY-MM-DD, please check you typed it correctly!" 53 | exit -1 54 | end 55 | filename = File.join(CONFIG['posts'], "#{date}-#{slug}.#{CONFIG['post_ext']}") 56 | if File.exist?(filename) 57 | abort("rake aborted!") if ask("#{filename} already exists. Do you want to overwrite?", ['y', 'n']) == 'n' 58 | end 59 | 60 | puts "Creating new post: #{filename}" 61 | open(filename, 'w') do |post| 62 | post.puts "---" 63 | post.puts "layout: post" 64 | post.puts "title: \"#{title.gsub(/-/,' ')}\"" 65 | post.puts 'description: ""' 66 | post.puts "category: " 67 | post.puts "tags: []" 68 | post.puts "---" 69 | post.puts "{% include JB/setup %}" 70 | end 71 | end # task :post 72 | 73 | # Usage: rake page name="about.html" 74 | # You can also specify a sub-directory path. 75 | # If you don't specify a file extention we create an index.html at the path specified 76 | desc "Create a new page." 77 | task :page do 78 | name = ENV["name"] || "new-page.md" 79 | filename = File.join(SOURCE, "#{name}") 80 | filename = File.join(filename, "index.html") if File.extname(filename) == "" 81 | title = File.basename(filename, File.extname(filename)).gsub(/[\W\_]/, " ").gsub(/\b\w/){$&.upcase} 82 | if File.exist?(filename) 83 | abort("rake aborted!") if ask("#{filename} already exists. Do you want to overwrite?", ['y', 'n']) == 'n' 84 | end 85 | 86 | mkdir_p File.dirname(filename) 87 | puts "Creating new page: #{filename}" 88 | open(filename, 'w') do |post| 89 | post.puts "---" 90 | post.puts "layout: page" 91 | post.puts "title: \"#{title}\"" 92 | post.puts 'description: ""' 93 | post.puts "---" 94 | post.puts "{% include JB/setup %}" 95 | end 96 | end # task :page 97 | 98 | desc "Launch preview environment" 99 | task :preview do 100 | system "jekyll --auto --server" 101 | end # task :preview 102 | 103 | # Public: Alias - Maintains backwards compatability for theme switching. 104 | task :switch_theme => "theme:switch" 105 | 106 | namespace :theme do 107 | 108 | # Public: Switch from one theme to another for your blog. 109 | # 110 | # name - String, Required. name of the theme you want to switch to. 111 | # The the theme must be installed into your JB framework. 112 | # 113 | # Examples 114 | # 115 | # rake theme:switch name="the-program" 116 | # 117 | # Returns Success/failure messages. 118 | desc "Switch between Jekyll-bootstrap themes." 119 | task :switch do 120 | theme_name = ENV["name"].to_s 121 | theme_path = File.join(CONFIG['themes'], theme_name) 122 | settings_file = File.join(theme_path, "settings.yml") 123 | non_layout_files = ["settings.yml"] 124 | 125 | abort("rake aborted: name cannot be blank") if theme_name.empty? 126 | abort("rake aborted: '#{theme_path}' directory not found.") unless FileTest.directory?(theme_path) 127 | abort("rake aborted: '#{CONFIG['layouts']}' directory not found.") unless FileTest.directory?(CONFIG['layouts']) 128 | 129 | Dir.glob("#{theme_path}/*") do |filename| 130 | next if non_layout_files.include?(File.basename(filename).downcase) 131 | puts "Generating '#{theme_name}' layout: #{File.basename(filename)}" 132 | 133 | open(File.join(CONFIG['layouts'], File.basename(filename)), 'w') do |page| 134 | if File.basename(filename, ".html").downcase == "default" 135 | page.puts "---" 136 | page.puts File.read(settings_file) if File.exist?(settings_file) 137 | page.puts "---" 138 | else 139 | page.puts "---" 140 | page.puts "layout: default" 141 | page.puts "---" 142 | end 143 | page.puts "{% include JB/setup %}" 144 | page.puts "{% include themes/#{theme_name}/#{File.basename(filename)} %}" 145 | end 146 | end 147 | 148 | puts "=> Theme successfully switched!" 149 | puts "=> Reload your web-page to check it out =)" 150 | end # task :switch 151 | 152 | # Public: Install a theme using the theme packager. 153 | # Version 0.1.0 simple 1:1 file matching. 154 | # 155 | # git - String, Optional path to the git repository of the theme to be installed. 156 | # name - String, Optional name of the theme you want to install. 157 | # Passing name requires that the theme package already exist. 158 | # 159 | # Examples 160 | # 161 | # rake theme:install git="https://github.com/jekyllbootstrap/theme-twitter.git" 162 | # rake theme:install name="cool-theme" 163 | # 164 | # Returns Success/failure messages. 165 | desc "Install theme" 166 | task :install do 167 | if ENV["git"] 168 | manifest = theme_from_git_url(ENV["git"]) 169 | name = manifest["name"] 170 | else 171 | name = ENV["name"].to_s.downcase 172 | end 173 | 174 | packaged_theme_path = JB::Path.build(:theme_packages, :node => name) 175 | 176 | abort("rake aborted! 177 | => ERROR: 'name' cannot be blank") if name.empty? 178 | abort("rake aborted! 179 | => ERROR: '#{packaged_theme_path}' directory not found. 180 | => Installable themes can be added via git. You can find some here: http://github.com/jekyllbootstrap 181 | => To download+install run: `rake theme:install git='[PUBLIC-CLONE-URL]'` 182 | => example : rake theme:install git='git@github.com:jekyllbootstrap/theme-the-program.git' 183 | ") unless FileTest.directory?(packaged_theme_path) 184 | 185 | manifest = verify_manifest(packaged_theme_path) 186 | 187 | # Get relative paths to packaged theme files 188 | # Exclude directories as they'll be recursively created. Exclude meta-data files. 189 | packaged_theme_files = [] 190 | FileUtils.cd(packaged_theme_path) { 191 | Dir.glob("**/*.*") { |f| 192 | next if ( FileTest.directory?(f) || f =~ /^(manifest|readme|packager)/i ) 193 | packaged_theme_files << f 194 | } 195 | } 196 | 197 | # Mirror each file into the framework making sure to prompt if already exists. 198 | packaged_theme_files.each do |filename| 199 | file_install_path = File.join(JB::Path.base, filename) 200 | if File.exist? file_install_path 201 | next if ask("#{file_install_path} already exists. Do you want to overwrite?", ['y', 'n']) == 'n' 202 | else 203 | mkdir_p File.dirname(file_install_path) 204 | cp_r File.join(packaged_theme_path, filename), file_install_path 205 | end 206 | end 207 | 208 | puts "=> #{name} theme has been installed!" 209 | puts "=> ---" 210 | if ask("=> Want to switch themes now?", ['y', 'n']) == 'y' 211 | system("rake switch_theme name='#{name}'") 212 | end 213 | end 214 | 215 | # Public: Package a theme using the theme packager. 216 | # The theme must be structured using valid JB API. 217 | # In other words packaging is essentially the reverse of installing. 218 | # 219 | # name - String, Required name of the theme you want to package. 220 | # 221 | # Examples 222 | # 223 | # rake theme:package name="twitter" 224 | # 225 | # Returns Success/failure messages. 226 | desc "Package theme" 227 | task :package do 228 | name = ENV["name"].to_s.downcase 229 | theme_path = JB::Path.build(:themes, :node => name) 230 | asset_path = JB::Path.build(:theme_assets, :node => name) 231 | 232 | abort("rake aborted: name cannot be blank") if name.empty? 233 | abort("rake aborted: '#{theme_path}' directory not found.") unless FileTest.directory?(theme_path) 234 | abort("rake aborted: '#{asset_path}' directory not found.") unless FileTest.directory?(asset_path) 235 | 236 | ## Mirror theme's template directory (_includes) 237 | packaged_theme_path = JB::Path.build(:themes, :root => JB::Path.build(:theme_packages, :node => name)) 238 | mkdir_p packaged_theme_path 239 | cp_r theme_path, packaged_theme_path 240 | 241 | ## Mirror theme's asset directory 242 | packaged_theme_assets_path = JB::Path.build(:theme_assets, :root => JB::Path.build(:theme_packages, :node => name)) 243 | mkdir_p packaged_theme_assets_path 244 | cp_r asset_path, packaged_theme_assets_path 245 | 246 | ## Log packager version 247 | packager = {"packager" => {"version" => CONFIG["theme_package_version"].to_s } } 248 | open(JB::Path.build(:theme_packages, :node => "#{name}/packager.yml"), "w") do |page| 249 | page.puts packager.to_yaml 250 | end 251 | 252 | puts "=> '#{name}' theme is packaged and available at: #{JB::Path.build(:theme_packages, :node => name)}" 253 | end 254 | 255 | end # end namespace :theme 256 | 257 | # Internal: Download and process a theme from a git url. 258 | # Notice we don't know the name of the theme until we look it up in the manifest. 259 | # So we'll have to change the folder name once we get the name. 260 | # 261 | # url - String, Required url to git repository. 262 | # 263 | # Returns theme manifest hash 264 | def theme_from_git_url(url) 265 | tmp_path = JB::Path.build(:theme_packages, :node => "_tmp") 266 | abort("rake aborted: system call to git clone failed") if !system("git clone #{url} #{tmp_path}") 267 | manifest = verify_manifest(tmp_path) 268 | new_path = JB::Path.build(:theme_packages, :node => manifest["name"]) 269 | if File.exist?(new_path) && ask("=> #{new_path} theme package already exists. Override?", ['y', 'n']) == 'n' 270 | remove_dir(tmp_path) 271 | abort("rake aborted: '#{manifest["name"]}' already exists as theme package.") 272 | end 273 | 274 | remove_dir(new_path) if File.exist?(new_path) 275 | mv(tmp_path, new_path) 276 | manifest 277 | end 278 | 279 | # Internal: Process theme package manifest file. 280 | # 281 | # theme_path - String, Required. File path to theme package. 282 | # 283 | # Returns theme manifest hash 284 | def verify_manifest(theme_path) 285 | manifest_path = File.join(theme_path, "manifest.yml") 286 | manifest_file = File.open( manifest_path ) 287 | abort("rake aborted: repo must contain valid manifest.yml") unless File.exist? manifest_file 288 | manifest = YAML.load( manifest_file ) 289 | manifest_file.close 290 | manifest 291 | end 292 | 293 | def ask(message, valid_options) 294 | if valid_options 295 | answer = get_stdin("#{message} #{valid_options.to_s.gsub(/"/, '').gsub(/, /,'/')} ") while !valid_options.include?(answer) 296 | else 297 | answer = get_stdin(message) 298 | end 299 | answer 300 | end 301 | 302 | def get_stdin(message) 303 | print message 304 | STDIN.gets.chomp 305 | end 306 | 307 | #Load custom rake scripts 308 | Dir['_rake/*.rake'].each { |r| load r } 309 | -------------------------------------------------------------------------------- /assets/themes/awesome/stylesheets/styles.css: -------------------------------------------------------------------------------- 1 | @import url(https://fonts.googleapis.com/css?family=Arvo:400,700,400italic); 2 | @import url("//hello.myfonts.net/count/27ddd3"); 3 | 4 | @font-face {font-family: 'NeoSansStd-Bold';src: url('/assets/themes/awesome/webfonts/27DDD3_0_0.eot');src: url('/assets/themes/awesome/webfonts/27DDD3_0_0.eot?#iefix') format('embedded-opentype'),url('/assets/themes/awesome/webfonts/27DDD3_0_0.woff') format('woff'),url('/assets/themes/awesome/webfonts/27DDD3_0_0.ttf') format('truetype');} 5 | 6 | 7 | 8 | 9 | html, 10 | body { 11 | /* height: 100%; */ 12 | 13 | background-color: #f0f0f2; 14 | } 15 | body { 16 | font-family: 'proxima-nova', sans-serif; 17 | font-size: 100%; 18 | line-height: 1.3; 19 | color: #555163; 20 | margin: 0; 21 | padding: 0; 22 | } 23 | p { 24 | font-size: 16px; 25 | } 26 | 27 | a, 28 | a:visited { 29 | color: #333333; 30 | text-decoration: none; 31 | outline: 0; 32 | /* on hover */ 33 | 34 | /* on click */ 35 | 36 | /* mobile tap color */ 37 | 38 | } 39 | a:hover, 40 | a:visited:hover, 41 | a:focus, 42 | a:visited:focus { 43 | color: #ef4036; 44 | } 45 | a:link, 46 | a:visited:link { 47 | /* 48 | this highlights links on iPhones/iPads. 49 | so it basically works like the :hover selector 50 | for mobile devices. 51 | */ 52 | 53 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0.3); 54 | } 55 | 56 | .page-content li a, .page-content p a { 57 | border-bottom: 1px solid #ddd; 58 | } 59 | 60 | .btn { 61 | border-radius: 5px; 62 | padding: 0.65em 2.6em .7em; 63 | text-transform: uppercase; 64 | background: #636b78; 65 | color: rgba(255, 255, 255, 0.9); 66 | margin-right: 10px; 67 | text-shadow: none; 68 | line-height: 1; 69 | font-weight: bold; 70 | -webkit-font-smoothing: antialiased; 71 | display: inline-block; 72 | cursor: hand; 73 | font-size: 1em; 74 | text-decoration: none; 75 | border: none; 76 | box-shadow: 0px 0.15em 0px #4E5563; 77 | } 78 | a.btn, 79 | a.btn:visited { 80 | color: rgba(255, 255, 255, 0.9); 81 | } 82 | a.btn:hover { 83 | color: white; 84 | } 85 | .btn-large { 86 | font-size: 1.5em; 87 | white-space: nowrap; 88 | } 89 | .btn:hover { 90 | color: #ffffff; 91 | } 92 | .btn:active { 93 | -webkit-transform: translate(0, 0.15em); 94 | transform: translate(0, 0.15em); 95 | box-shadow: none; 96 | background-color: #4E5563; 97 | } 98 | .btn.turquoise, 99 | .btn.btn-primary { 100 | background-color: #00d7cc; 101 | border: none; 102 | box-shadow: 0px 0.15em 0px #0aafa7; 103 | } 104 | .btn.turquoise:active, 105 | .btn.btn-primary:active { 106 | box-shadow: none; 107 | background-color: #0aafa7; 108 | } 109 | .btn.sunflower { 110 | background-color: #F1C40F; 111 | border: none; 112 | box-shadow: 0px 0.15em 0px #F39C12; 113 | } 114 | .btn.sunflower:active { 115 | box-shadow: none; 116 | background-color: #F39C12; 117 | } 118 | .btn.orange { 119 | background-color: #E9B309; 120 | border: none; 121 | box-shadow: 0px 0.15em 0px #DA8B0E; 122 | } 123 | .btn.orange:active { 124 | box-shadow: none; 125 | background-color: #DA8B0E; 126 | } 127 | /****************************************************************** 128 | 05. H1, H2, H3, H4, H5 STYLES 129 | ******************************************************************/ 130 | h1, 131 | .h1, 132 | h2, 133 | .h2, 134 | h3, 135 | .h3, 136 | h4, 137 | .h4, 138 | h5, 139 | .h5 { 140 | font-family: 'NeoSansStd-Bold', sans-serif; 141 | text-rendering: optimizelegibility; 142 | -webkit-font-smoothing: antialiased; 143 | font-weight: 400 !important; 144 | color: #635e70; 145 | /* 146 | if you're going to use webfonts, be sure to check your weights 147 | http://css-tricks.com/watch-your-font-weight/ 148 | */ 149 | 150 | /* removing text decoration from all headline links */ 151 | 152 | } 153 | h1 a, 154 | .h1 a, 155 | h2 a, 156 | .h2 a, 157 | h3 a, 158 | .h3 a, 159 | h4 a, 160 | .h4 a, 161 | h5 a, 162 | .h5 a { 163 | text-decoration: none; 164 | } 165 | .heading { 166 | font-family: 'NeoSansStd-Bold', sans-serif; 167 | font-weight: 400; 168 | } 169 | h1, 170 | .h1 { 171 | font-size: 2.3em; 172 | line-height: 1.333em; 173 | margin-bottom: 0.3em; 174 | margin-top: 1em; 175 | } 176 | h2, 177 | .h2 { 178 | font-size: 1.66rem; 179 | line-height: 1.3em; 180 | margin-top: 1.5em; 181 | margin-bottom: 0.2em; 182 | } 183 | h3, 184 | .h3 { 185 | font-size: 1.125em; 186 | margin-top: 1.5em; 187 | margin-bottom: 0.2em; 188 | } 189 | h4, 190 | .h4 { 191 | font-size: 1em; 192 | margin-top: 1.4em; 193 | margin-bottom: 0.5em; 194 | } 195 | h5, 196 | .h5 { 197 | font-size: 0.846em; 198 | line-height: 2.09em; 199 | text-transform: uppercase; 200 | letter-spacing: 2px; 201 | margin-bottom: 0.5em; 202 | } 203 | 204 | section menu, 205 | section ol, 206 | section ul { 207 | padding: 0 0 0 40px; 208 | } 209 | section dl, 210 | section menu, 211 | section ol, 212 | section ul { 213 | margin: 1em 0; 214 | } 215 | section dt { 216 | font-weight: 700; 217 | } 218 | section dd { 219 | padding-bottom: .3em; 220 | padding-top: .2em; 221 | } 222 | section p { 223 | line-height: 1.45em; 224 | } 225 | section .content-subhead { 226 | color: #555; 227 | font-weight: 300; 228 | margin: 50px 0 20px; 229 | } 230 | section .content-spaced { 231 | line-height: 1.8em; 232 | } 233 | section .snippet { 234 | margin: 1.3em 0 1em; 235 | padding: 1.3em; 236 | } 237 | section blockquote { 238 | margin: 1.5em 40px; 239 | } 240 | section .content-quote { 241 | border-left: 5px solid #ddd; 242 | color: #666; 243 | font-family: Georgia, serif; 244 | font-style: italic; 245 | line-height: 1.8em; 246 | padding-left: 1.5em; 247 | } 248 | section pre { 249 | line-height: 1.3em; 250 | margin-bottom: 20px; 251 | padding: 6px 10px; 252 | word-wrap: break-word; 253 | background: #fafafc; 254 | margin-left: -2.7em; 255 | padding-left: 2.7em; 256 | margin-right: -2.7em; 257 | padding-right: 2.7em; 258 | border-top: 1px solid #f0f0f2; 259 | border-bottom: 1px solid #f0f0f2; 260 | padding-top: 1em; 261 | padding-bottom: 1em; 262 | } 263 | section code { 264 | border: none; 265 | font-size: 14px; 266 | margin: 0 2px; 267 | padding: .4em .6em; 268 | } 269 | section pre code { 270 | margin: 0; 271 | padding: 0; 272 | } 273 | section pre, 274 | section code { 275 | background: #f8f7f9; 276 | /* color:#615d6d; */ 277 | 278 | color: #726f80; 279 | font-family: "source-code-pro", Consolas, 'Liberation Mono', Courier, monospace; 280 | } 281 | section pre .keyword, 282 | section pre .support { 283 | color: #00ccc2; 284 | } 285 | section pre .keyword.operator { 286 | color: #726f80; 287 | } 288 | section pre .comment { 289 | color: #abacb3; 290 | } 291 | section pre .tag, 292 | section pre .tag-name, 293 | section pre .support.tag-name { 294 | color: #555; 295 | } 296 | section pre .css-property, 297 | section pre .css-value, 298 | section pre .vendor-prefix, 299 | section pre .support.namespace { 300 | color: #726f80; 301 | } 302 | section pre .constant.numeric, 303 | section pre .keyword.unit, 304 | section pre .hex-color, 305 | section pre .string, 306 | section pre .support.value { 307 | color: #d33d55; 308 | } 309 | section video, 310 | section object { 311 | max-width: 100%; 312 | height: auto; 313 | } 314 | 315 | section p, section li { 316 | font-size: 16px; 317 | } 318 | section p { 319 | position: relative; 320 | margin: 0.725em 0 1.45em 0; 321 | } 322 | section p.breadcrumb { 323 | margin-bottom: 1em; 324 | } 325 | section h3 { 326 | font-size: 1.25em; 327 | margin-top: 1.7em; 328 | margin-bottom: 0.4em; 329 | } 330 | section ul, 331 | section ol { 332 | margin-bottom: 20px; 333 | padding: 0; 334 | margin: 0; 335 | padding-right: 120px; 336 | max-width: 550px; 337 | margin-left: 35px; 338 | margin-bottom: 30px; 339 | } 340 | section li { 341 | margin: 0; 342 | margin-bottom: 10px; 343 | margin-top: 10px; 344 | } 345 | section .intro, section p.intro { 346 | color: #555163; 347 | font-weight: 300; 348 | font-size: 24px; 349 | clear: both; 350 | } 351 | section blockquote { 352 | border-left: 5px solid #e8e8eb; 353 | color: #a1a0a7; 354 | font-size: 16px; 355 | line-height: 1.45em; 356 | padding: 0.6em 1em; 357 | margin: 1em 0; 358 | font-weight: 300; 359 | } 360 | section blockquote p { 361 | color: #a1a0a7; 362 | font-size: 16px; 363 | line-height: 1.45em; 364 | padding: 0; 365 | margin: 0; 366 | font-weight: 300; 367 | margin-left: 3.2em; 368 | } 369 | section blockquote p code, section blockquote p a { 370 | color: #a1a0a7; 371 | } 372 | section blockquote:before { 373 | content: 'Note: '; 374 | font-weight: 600; 375 | float: left; 376 | } 377 | section .intro p { 378 | margin: 0; 379 | font-size: 24px; 380 | } 381 | section .pull-quote { 382 | font-weight: 200; 383 | line-height: 38px; 384 | text-align: right; 385 | color: #bbb; 386 | width: 25%; 387 | float: right; 388 | margin: 0 0 35px 35px; 389 | } 390 | section hr { 391 | margin: 20px 0 30px; 392 | border: 0; 393 | border-bottom: 1px solid #ebe9f2; 394 | height: 1px; 395 | } 396 | section ul li { 397 | list-style-type: circle; 398 | } 399 | section .highlight { 400 | background: #FFF4B2; 401 | color: #222; 402 | } 403 | 404 | section table { 405 | border-collapse: collapse; 406 | border-spacing: 0; 407 | empty-cells: show; 408 | border: 1px solid #e8e8eb; 409 | } 410 | section td, section th { 411 | border-left: 1px solid #e8e8eb; 412 | border-width: 0 0 0 1px; 413 | font-size: inherit; 414 | margin: 0; 415 | overflow: visible; 416 | padding: 0.5em 1em; 417 | } 418 | section th { 419 | border-bottom: 1px solid #e8e8eb; 420 | color: #635e70; 421 | } 422 | 423 | /* -------------------- */ 424 | 425 | a small { 426 | font-size: 12px; 427 | } 428 | 429 | li.show-more { 430 | color: #C30000; 431 | font-weight: 400; 432 | cursor: pointer; 433 | list-style-type: none; 434 | padding-left: 50px; 435 | } 436 | 437 | li.show-more:hover { 438 | text-decoration: underline; 439 | } 440 | 441 | em { 442 | font-style: italic; 443 | } 444 | 445 | strong { 446 | font-weight:700; 447 | } 448 | 449 | /* Wrapper */ 450 | .wrapper { 451 | width:1000px; 452 | } 453 | 454 | #main-site-link { 455 | position: absolute; 456 | left: 810px; 457 | width: 170px; 458 | height: 25px; 459 | padding-top: 5px; 460 | text-align: center; 461 | } 462 | 463 | /* Header */ 464 | 465 | header { 466 | width:210px; 467 | float:left; 468 | border: none; 469 | padding: 0px 25px 22px 40px; 470 | margin: 30px 25px 0 0; 471 | } 472 | 473 | header h3 { 474 | margin-bottom: 0.5em; 475 | } 476 | 477 | div.logo div { 478 | text-indent: 100%; 479 | white-space: nowrap; 480 | overflow: hidden; 481 | background-image: url('/assets/themes/awesome/images/awe-flat-icon-logo.png'); 482 | background-size: 125px 125px; 483 | width: 125px; 484 | height: 125px; 485 | } 486 | 487 | div.logo h1 { 488 | margin-top: 0.3em; 489 | font-size: 2.2rem; 490 | } 491 | 492 | div.page-header h2 { 493 | padding-top: 5px; 494 | margin-top: 10px; 495 | } 496 | 497 | div.page-header { 498 | padding-top: 15px; 499 | margin-top: 26px; 500 | } 501 | 502 | div.page-header p.breadcrumb { 503 | padding: 0; 504 | margin: 0; 505 | } 506 | 507 | p.header { 508 | font-size: 16px; 509 | margin: 0 0 12px; 510 | } 511 | 512 | p.header a { 513 | font-weight: normal; 514 | } 515 | 516 | h1.header, h1.header a { 517 | /*font-family: Arvo, sans-serif;*/ 518 | font-size: 24px; 519 | font-weight: 500; 520 | line-height: 1.3em; 521 | border-bottom: none; 522 | margin-top: 5px; 523 | } 524 | 525 | h1.header img { 526 | border: none; 527 | float: left; 528 | margin-top: -12px; 529 | padding-right: 5px; 530 | margin-bottom: 12px; 531 | } 532 | 533 | header ul { 534 | list-style:none; 535 | padding:0; 536 | } 537 | 538 | header li { 539 | list-style-type: none; 540 | width:132px; 541 | height:15px; 542 | margin-bottom: 12px; 543 | line-height: 1em; 544 | padding: 6px 6px 6px 7px; 545 | 546 | background: #AF0011; 547 | background: -moz-linear-gradient(top, #AF0011 0%, #820011 100%); 548 | background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(100%,#dddddd)); 549 | background: -webkit-linear-gradient(top, #AF0011 0%,#820011 100%); 550 | background: -o-linear-gradient(top, #AF0011 0%,#820011 100%); 551 | background: -ms-linear-gradient(top, #AF0011 0%,#820011 100%); 552 | background: linear-gradient(top, #AF0011 0%,#820011 100%); 553 | 554 | border-radius:4px; 555 | border:1px solid #0D0D0D; 556 | 557 | -webkit-box-shadow: inset 0px 1px 1px 0 rgba(233,2,38, 1); 558 | box-shadow: inset 0px 1px 1px 0 rgba(233,2,38, 1); 559 | 560 | } 561 | 562 | header li:hover { 563 | background: #C3001D; 564 | background: -moz-linear-gradient(top, #C3001D 0%, #950119 100%); 565 | background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(100%,#dddddd)); 566 | background: -webkit-linear-gradient(top, #C3001D 0%,#950119 100%); 567 | background: -o-linear-gradient(top, #C3001D 0%,#950119 100%); 568 | background: -ms-linear-gradient(top, #C3001D 0%,#950119 100%); 569 | background: linear-gradient(top, #C3001D 0%,#950119 100%); 570 | } 571 | 572 | a.buttons { 573 | -webkit-font-smoothing: antialiased; 574 | background: url(../images/arrow-down.png) no-repeat; 575 | font-weight: normal; 576 | text-shadow: rgba(0, 0, 0, 0.4) 0 -1px 0; 577 | padding: 2px 2px 2px 22px; 578 | height: 30px; 579 | } 580 | 581 | a.github { 582 | background: url(../images/octocat-small.png) no-repeat 1px; 583 | } 584 | 585 | a.buttons:hover { 586 | color: #fff; 587 | text-decoration: none; 588 | } 589 | 590 | 591 | /* Section - for main page content */ 592 | 593 | section { 594 | width: 700px; 595 | position: absolute; 596 | left: 300px; 597 | top: 20px; 598 | padding-bottom: 50px; 599 | padding-left: 2em; 600 | padding-top: 2em; 601 | } 602 | 603 | .page { 604 | border: 1px solid #e8e8eb; 605 | background-color: white; 606 | box-shadow: 15px 40px 0px #e8e8eb; 607 | padding: 2.7em; 608 | border-radius: 2px; 609 | } 610 | 611 | .page-nav { 612 | margin-left: 2.7em; 613 | } 614 | 615 | 616 | /* Footer */ 617 | 618 | footer { 619 | width:180px; 620 | float:left; 621 | position:fixed; 622 | bottom:10px; 623 | padding-left: 30px; 624 | -webkit-transition: opacity 300ms ease; 625 | opacity: 0.6; 626 | z-index: -1; 627 | text-align: center; 628 | } 629 | 630 | footer p { 631 | margin: 0; 632 | } 633 | 634 | footer:hover { 635 | opacity: 1.0; 636 | } 637 | 638 | @media print, screen and (max-width: 1000px) { 639 | body { 640 | padding: 0; 641 | } 642 | 643 | div.wrapper { 644 | width:auto; 645 | margin:0; 646 | } 647 | 648 | div.logo div { 649 | background-size: 62px 62px; 650 | width: 62px; 651 | height: 62px; 652 | float: left; 653 | margin-left: 4em; 654 | margin-right: 20px; 655 | margin-top: 5px; 656 | } 657 | 658 | #main-site-link { 659 | position: absolute; 660 | top: 0; 661 | left: auto; 662 | right: 4em; 663 | } 664 | 665 | header, section, footer { 666 | float:none; 667 | position:static; 668 | width:auto; 669 | } 670 | 671 | footer { 672 | border-top: 1px solid #ccc; 673 | margin:0 84px 0 50px; 674 | padding:0; 675 | } 676 | 677 | div.page-header h2 { 678 | padding-top: 0; 679 | } 680 | 681 | div.page-header { 682 | padding-top: 5px; 683 | margin-top: 10px; 684 | } 685 | 686 | header { 687 | padding: 0px; 688 | margin: 0px; 689 | width: 100%; 690 | border: 0; 691 | border-radius: 0; 692 | } 693 | 694 | header h1 { 695 | padding: 15px; 696 | } 697 | 698 | h1.header, h1.header a { 699 | margin-top: 0; 700 | } 701 | 702 | header p, header h3 { 703 | display: none; 704 | } 705 | 706 | header h3.switch-container { 707 | display: block; 708 | position: absolute; 709 | right: 4em; 710 | margin-top: -3em; 711 | } 712 | 713 | section { 714 | padding: 20px 4em 20px 4em; 715 | margin:0 0 20px; 716 | } 717 | 718 | header a small { 719 | display:inline; 720 | } 721 | 722 | header ul { 723 | position:absolute; 724 | right:130px; 725 | top:84px; 726 | } 727 | } 728 | 729 | @media print, screen and (max-width: 720px) { 730 | body { 731 | word-wrap:break-word; 732 | } 733 | 734 | header p, header h3 { 735 | display: none; 736 | } 737 | 738 | section { 739 | padding:10px 0 10px 20px; 740 | margin:0 0 30px; 741 | } 742 | 743 | footer { 744 | margin: 0 0 0 30px; 745 | } 746 | 747 | header ul, header p.view { 748 | position:static; 749 | } 750 | } 751 | 752 | @media print, screen and (max-width: 480px) { 753 | 754 | header ul li.download { 755 | display:none; 756 | } 757 | 758 | header p, header h3 { 759 | display: none; 760 | } 761 | 762 | footer { 763 | margin: 0 0 0 20px; 764 | } 765 | 766 | footer a{ 767 | display:block; 768 | } 769 | 770 | } 771 | 772 | @media print { 773 | body { 774 | padding:0.4in; 775 | font-size:12pt; 776 | color:#444; 777 | } 778 | } 779 | 780 | .switch-container { 781 | width: 190px; 782 | } 783 | 784 | .switch-container .switch-text { 785 | float: left; 786 | } 787 | 788 | .switch-container .clear { 789 | clear: both; 790 | } 791 | 792 | .switch { 793 | float: right; 794 | margin-top: -4px; 795 | height: 28px; 796 | width: 77px; 797 | border: 1px solid #d7d7d9; 798 | border-radius: 15px; 799 | box-shadow: inset 0 2px 2px #BABABA, inset 0 4px 2px 2px rgba(232, 232, 232, 0.3); 800 | cursor: pointer; 801 | overflow: hidden; 802 | background: white; 803 | } 804 | .switch input[type=checkbox] { 805 | display: none; 806 | } 807 | .switch::before { 808 | content: ""; 809 | display: block; 810 | height: 28px; 811 | width: 0px; 812 | position: absolute; 813 | border-radius: 15px; 814 | background-color: white; 815 | } 816 | .switch.on::before { 817 | width: 77px; 818 | } 819 | .switch > .thumb { 820 | display: block; 821 | width: 26px; 822 | height: 26px; 823 | position: relative; 824 | top: 0; 825 | z-index: 3; 826 | border: solid 1px #d5d5db; 827 | border-radius: 15px; 828 | background-color: #CECECE; 829 | -o-transition: all 0.125s ease-in-out; 830 | -webkit-transition: all 0.125s ease-in-out; 831 | -moz-transition: all 0.125s ease-in-out; 832 | -o-transform: translateX(0px); 833 | -webkit-transform: translate3d(0,0,0); 834 | -moz-transform: translateX(0px); 835 | background: #ffffff; 836 | background: -moz-linear-gradient(-64deg, #ffffff 50%, #f8f7f9 50%); 837 | background: -webkit-gradient(linear, left top, right bottom, color-stop(50%, #ffffff), color-stop(50%, #f8f7f9)); 838 | background: -webkit-linear-gradient(-64deg, #ffffff 50%, #f8f7f9 50%); 839 | background: -o-linear-gradient(-64deg, #ffffff 50%, #f8f7f9 50%); 840 | background: -ms-linear-gradient(-64deg, #ffffff 50%, #f8f7f9 50%); 841 | background: linear-gradient(116deg, #ffffff 50%, #ededf0 50%); 842 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#f8f7f9', GradientType=1); 843 | } 844 | .switch.on > .thumb { 845 | -webkit-transform: translate3d(49px,0,0); 846 | -o-transform: translateX(49px); 847 | -moz-transform: translateX(49px); 848 | } 849 | .switch:hover > .thumb { 850 | border: 1px solid #a3a3a8; 851 | } 852 | .switch > .thumb::before { 853 | content: "C++"; 854 | display: block; 855 | height: 18px; 856 | border: none; 857 | position: absolute; 858 | top: 2px; 859 | left: -38px; 860 | font-size: 16px; 861 | font-weight: bold; 862 | } 863 | .switch > .thumb::after { 864 | content: ".NET"; 865 | display: block; 866 | height: 18px; 867 | border: none; 868 | position: absolute; 869 | right: -42px; 870 | top: 2px; 871 | font-size: 16px; 872 | font-weight: bold; 873 | letter-spacing: -1px; 874 | } --------------------------------------------------------------------------------