Coder Social home page Coder Social logo

anglesharp / anglesharp.js Goto Github PK

View Code? Open in Web Editor NEW
99.0 99.0 23.0 1.5 MB

:angel: Extends AngleSharp with a .NET-based JavaScript engine.

Home Page: https://anglesharp.github.io

License: MIT License

C# 99.36% PowerShell 0.33% Shell 0.27% TypeScript 0.02% Batchfile 0.02%
anglesharp c-sharp dom javascript jint library parser

anglesharp.js's Introduction

logo

AngleSharp

CI GitHub Tag NuGet Count Issues Open Gitter Chat StackOverflow Questions CLA Assistant

AngleSharp is a .NET library that gives you the ability to parse angle bracket based hyper-texts like HTML, SVG, and MathML. XML without validation is also supported by the library. An important aspect of AngleSharp is that CSS can also be parsed. The included parser is built upon the official W3C specification. This produces a perfectly portable HTML5 DOM representation of the given source code and ensures compatibility with results in evergreen browsers. Also standard DOM features such as querySelector or querySelectorAll work for tree traversal.

⚡⚡ Migrating from AngleSharp 0.9 to AngleSharp 0.10 or later (incl. 1.0)? Look at our migration documentation. ⚡⚡

Key Features

  • Portable (using .NET Standard 2.0)
  • Standards conform (works exactly as evergreen browsers)
  • Great performance (outperforms similar parsers in most scenarios)
  • Extensible (extend with your own services)
  • Useful abstractions (type helpers, jQuery like construction)
  • Fully functional DOM (all the lists, iterators, and events you know)
  • Form submission (easily log in everywhere)
  • Navigation (a BrowsingContext is like a browser tab - control it from .NET!).
  • LINQ enhanced (use LINQ with DOM elements, naturally without wrappers)

The advantage over similar libraries like HtmlAgilityPack is that the exposed DOM is using the official W3C specified API, i.e., that even things like querySelectorAll are available in AngleSharp. Also the parser uses the HTML 5.1 specification, which defines error handling and element correction. The AngleSharp library focuses on standards compliance, interactivity, and extensibility. It is therefore giving web developers working with C# all possibilities as they know from using the DOM in any modern browser.

The performance of AngleSharp is quite close to the performance of browsers. Even very large pages can be processed within milliseconds. AngleSharp tries to minimize memory allocations and reuses elements internally to avoid unnecessary object creation.

Simple Demo

The simple example will use the website of Wikipedia for data retrieval.

var config = Configuration.Default.WithDefaultLoader();
var address = "https://en.wikipedia.org/wiki/List_of_The_Big_Bang_Theory_episodes";
var context = BrowsingContext.New(config);
var document = await context.OpenAsync(address);
var cellSelector = "tr.vevent td:nth-child(3)";
var cells = document.QuerySelectorAll(cellSelector);
var titles = cells.Select(m => m.TextContent);

Or the same with explicit types:

IConfiguration config = Configuration.Default.WithDefaultLoader();
string address = "https://en.wikipedia.org/wiki/List_of_The_Big_Bang_Theory_episodes";
IBrowsingContext context = BrowsingContext.New(config);
IDocument document = await context.OpenAsync(address);
string cellSelector = "tr.vevent td:nth-child(3)";
IHtmlCollection<IElement> cells = document.QuerySelectorAll(cellSelector);
IEnumerable<string> titles = cells.Select(m => m.TextContent);

In the example we see:

  • How to setup the configuration for supporting document loading
  • Asynchronously get the document in a new context using the configuration
  • Performing a query to get all cells with the content of interest
  • The whole DOM supports LINQ queries

Every collection in AngleSharp supports LINQ statements. AngleSharp also provides many useful extension methods for element collections that cannot be found in the official DOM.

Supported Platforms

AngleSharp has been created as a .NET Standard 2.0 compatible library. This includes, but is not limited to:

  • .NET Core (2.0 and later)
  • .NET Framework (4.6.2 and later)
  • Xamarin.Android (7.0 and 8.0)
  • Xamarin.iOS (10.0 and 10.14)
  • Xamarin.Mac (3.0 and 3.8)
  • Mono (4.6 and 5.4)
  • UWP (10.0 and 10.0.16299)
  • Unity (2018.1)

Documentation

The documentation of AngleSharp is located in the docs folder. More examples, best-practices, and general information can be found there. The documentation also contains a list of frequently asked questions.

More information is also available by following some of the hyper references mentioned in the Wiki. In-depth articles will be published on the CodeProject, with links being placed in the Wiki at GitHub.

Use-Cases

  • Parsing HTML (incl. fragments)
  • Parsing CSS (incl. selectors, declarations, ...)
  • Constructing HTML (e.g., view-engine)
  • Minifying CSS, HTML, ...
  • Querying document elements
  • Crawling information
  • Gathering statistics
  • Web automation
  • Tools with HTML / CSS / ... support
  • Connection to page analytics
  • HTML / DOM unit tests
  • Automated JavaScript interaction
  • Testing other concepts, e.g., script engines
  • ...

Vision

The project aims to bring a solid implementation of the W3C DOM for HTML, SVG, MathML, and CSS to the CLR - all written in C#. The idea is that you can basically do everything with the DOM in C# that you can do in JavaScript (plus, of course, more).

Most parts of the DOM are included, even though some may still miss their (fully specified / correct) implementation. The goal for v1.0 is to have all practically relevant parts implemented according to the official W3C specification (with useful extensions by the WHATWG).

The API is close to the DOM4 specification, however, the naming has been adjusted to apply with .NET conventions. Nevertheless, to make AngleSharp really useful for, e.g., a JavaScript engine, attributes have been placed on the corresponding interfaces (and methods, properties, ...) to indicate the status of the field in the official specification. This allows automatic generation of DOM objects with the official API.

This is a long-term project which will eventually result in a state of the art parser for the most important angle bracket based hyper-texts.

Our hope is to build a community around web parsing and libraries from this project. So far we had great contributions, but that goal was not fully achieved. Want to help? Get in touch with us!

Participating in the Project

If you know some feature that AngleSharp is currently missing, and you are willing to implement the feature, then your contribution is more than welcome! Also if you have a really cool idea - do not be shy, we'd like to hear it.

If you have an idea how to improve the API (or what is missing) then posts / messages are also welcome. For instance there have been ongoing discussions about some styles that have been used by AngleSharp (e.g., HTMLDocument or HtmlDocument) in the past. In the end AngleSharp stopped using HTMLDocument (at least visible outside of the library). Now AngleSharp uses names like IDocument, IHtmlElement and so on. This change would not have been possible without such fruitful discussions.

The project is always searching for additional contributors. Even if you do not have any code to contribute, but rather an idea for improvement, a bug report or a mistake in the documentation. These are the contributions that keep this project active.

Live discussions can take place in our Gitter chat, which supports using GitHub accounts.

More information is found in the contribution guidelines. All contributors can be found in the CONTRIBUTORS file.

This project has also adopted the code of conduct defined by the Contributor Covenant to clarify expected behavior in our community.

For more information see the .NET Foundation Code of Conduct.

Funding / Support

If you use AngleSharp frequently, but you do not have the time to support the project by active participation you may still be interested to ensure that the AngleSharp projects keeps the lights on.

Therefore we created a backing model via Bountysource. Any donation is welcome and much appreciated. We will mostly spend the money on dedicated development time to improve AngleSharp where it needs to be improved, plus invest in the web utility eco-system in .NET (e.g., in JavaScript engines, other parsers, or a renderer for AngleSharp to mention some outstanding projects).

Visit Bountysource for more details.

Development

AngleSharp is written in the most recent version of C# and thus requires Roslyn as a compiler. Using an IDE like Visual Studio 2019+ is recommended on Windows. Alternatively, VSCode (with OmniSharp or another suitable Language Server Protocol implementation) should be the tool of choice on other platforms.

The code tries to be as clean as possible. Notably the following rules are used:

  • Use braces for any conditional / loop body
  • Use the -Async suffixed methods when available
  • Use VIP ("Var If Possible") style (in C++ called AAA: Almost Always Auto) to place types on the right

More important, however, is the proper usage of tests. Any new feature should come with a set of tests to cover the functionality and prevent regression.

Changelog

A very detailed changelog exists. If you are just interested in major releases then have a look at the GitHub releases.

.NET Foundation

This project is supported by the .NET Foundation.

License

AngleSharp is released using the MIT license. For more information see the license file.

anglesharp.js's People

Contributors

florianrappl avatar georgiosd avatar lahma avatar miroslav22 avatar sebbs128 avatar tomvanenckevort avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

anglesharp.js's Issues

Add (pseudo) view extensions

Events like onmouseover are currently missing. AngleSharp should (or will) probably already provide these events (even though they are currently unused). Nevertheless, some scripts unfortunately rely on them and fail if these expected properties are missing.

They (and possibly others) should be added to fake a view and enable script execution.

Pass values back and forth between Javascript & C#

Hi,

I am looking at replacing the web browser control in my C# winforms app with AngleSharp.

Is it possible to pass values back and forth from C# and JavaScript methods?

With the web browser control the way I currently do it is:

JavaScript to C#:
var return = window.external.MyCSharpFunc(myValue);

C# to JavaScript:
var return = WebBrowser.Document.InvokeScript("MyJSFunc", new object[] { myValue });

How would I go about doing this with anglesharp and jint? Are there any examples anywhere?

PageTests don't seem to work

Hi, I copied the two tests from PageTests.cs to a standalone executable for testing purposes, but query selector returns no results for some strange reason.

async static void RunScriptSelectorTest()
{
    var url = "http://html5test.com"; // same URL as in the test
    var sel = "#score > .pointsPanel > h2 > strong"; // same valid selector path as in the test
    var config = Configuration.Default
                .WithCss()
                .WithJavaScript()
                .WithDefaultLoader(setup => setup.IsResourceLoadingEnabled = true);
    var document = await BrowsingContext.New(config).OpenAsync(url);
    var elements = document.QuerySelectorAll(sel);
    // but no results (elements.Length is zero),
    // even though given selector has one match
}

Any ideas on what might be going wrong, as compared to the passing tests?

Implict wait for content to load

I just have discovered AngleSharp and I'm trying to learn about it.

I want to use it for testing my website, where content is dynamically generated.

Currently during loading, AngleSharp loads a document with the load spinner and not the actual loaded, ready document.

How can I implicitly wait during OpenAsync task for the element in the document to be loaded and visible?

ExecuteScript generates an error - Jint.Runtime.JavaScriptException

Response looks like below:

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <meta http-equiv="refresh" content="10;URL=/ciez2a">
</head>
<body>
  <script type="text/javascript">
function md5cycle(e,t){var i=e[0],a=e[1],r=e[2],n=e[3];a=ii(a=ii(a=ii(a=ii(a=hh(a=hh(a=hh(a=hh(a=gg(a=gg(a=gg(a=gg(a=ff(a=ff(a=ff(a=ff(a,r=ff(r,n=ff(n,i=ff(i,a,r,n,t[0],7,-680876936),a,r,t[1],12,-389564586),i,a,t[2],17,606105819),n,i,t[3],22,-1044525330),r=ff(r,n=ff(n,i=ff(i,a,r,n,t[4],7,-176418897),a,r,t[5],12,1200080426),i,a,t[6],17,-1473231341),n,i,t[7],22,-45705983),r=ff(r,n=ff(n,i=ff(i,a,r,n,t[8],7,1770035416),a,r,t[9],12,-1958414417),i,a,t[10],17,-42063),n,i,t[11],22,-1990404162),r=ff(r,n=ff(n,i=ff(i,a,r,n,t[12],7,1804603682),a,r,t[13],12,-40341101),i,a,t[14],17,-1502002290),n,i,t[15],22,1236535329),r=gg(r,n=gg(n,i=gg(i,a,r,n,t[1],5,-165796510),a,r,t[6],9,-1069501632),i,a,t[11],14,643717713),n,i,t[0],20,-373897302),r=gg(r,n=gg(n,i=gg(i,a,r,n,t[5],5,-701558691),a,r,t[10],9,38016083),i,a,t[15],14,-660478335),n,i,t[4],20,-405537848),r=gg(r,n=gg(n,i=gg(i,a,r,n,t[9],5,568446438),a,r,t[14],9,-1019803690),i,a,t[3],14,-187363961),n,i,t[8],20,1163531501),r=gg(r,n=gg(n,i=gg(i,a,r,n,t[13],5,-1444681467),a,r,t[2],9,-51403784),i,a,t[7],14,1735328473),n,i,t[12],20,-1926607734),r=hh(r,n=hh(n,i=hh(i,a,r,n,t[5],4,-378558),a,r,t[8],11,-2022574463),i,a,t[11],16,1839030562),n,i,t[14],23,-35309556),r=hh(r,n=hh(n,i=hh(i,a,r,n,t[1],4,-1530992060),a,r,t[4],11,1272893353),i,a,t[7],16,-155497632),n,i,t[10],23,-1094730640),r=hh(r,n=hh(n,i=hh(i,a,r,n,t[13],4,681279174),a,r,t[0],11,-358537222),i,a,t[3],16,-722521979),n,i,t[6],23,76029189),r=hh(r,n=hh(n,i=hh(i,a,r,n,t[9],4,-640364487),a,r,t[12],11,-421815835),i,a,t[15],16,530742520),n,i,t[2],23,-995338651),r=ii(r,n=ii(n,i=ii(i,a,r,n,t[0],6,-198630844),a,r,t[7],10,1126891415),i,a,t[14],15,-1416354905),n,i,t[5],21,-57434055),r=ii(r,n=ii(n,i=ii(i,a,r,n,t[12],6,1700485571),a,r,t[3],10,-1894986606),i,a,t[10],15,-1051523),n,i,t[1],21,-2054922799),r=ii(r,n=ii(n,i=ii(i,a,r,n,t[8],6,1873313359),a,r,t[15],10,-30611744),i,a,t[6],15,-1560198380),n,i,t[13],21,1309151649),r=ii(r,n=ii(n,i=ii(i,a,r,n,t[4],6,-145523070),a,r,t[11],10,-1120210379),i,a,t[2],15,718787259),n,i,t[9],21,-343485551),e[0]=add32(i,e[0]),e[1]=add32(a,e[1]),e[2]=add32(r,e[2]),e[3]=add32(n,e[3])}function cmn(e,t,i,a,r,n){return t=add32(add32(t,e),add32(a,n)),add32(t<<r|t>>>32-r,i)}function ff(e,t,i,a,r,n,o){return cmn(t&i|~t&a,e,t,r,n,o)}function gg(e,t,i,a,r,n,o){return cmn(t&a|i&~a,e,t,r,n,o)}function hh(e,t,i,a,r,n,o){return cmn(t^i^a,e,t,r,n,o)}function ii(e,t,i,a,r,n,o){return cmn(i^(t|~a),e,t,r,n,o)}function md51(e){txt="";var t,i=e.length,a=[1732584193,-271733879,-1732584194,271733878];for(t=64;t<=e.length;t+=64)md5cycle(a,md5blk(e.substring(t-64,t)));e=e.substring(t-64);var r=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(t=0;t<e.length;t++)r[t>>2]|=e.charCodeAt(t)<<(t%4<<3);if(r[t>>2]|=128<<(t%4<<3),t>55)for(md5cycle(a,r),t=0;t<16;t++)r[t]=0;return r[14]=8*i,md5cycle(a,r),a}function md5blk(e){var t,i=[];for(t=0;t<64;t+=4)i[t>>2]=e.charCodeAt(t)+(e.charCodeAt(t+1)<<8)+(e.charCodeAt(t+2)<<16)+(e.charCodeAt(t+3)<<24);return i}!function(e,t,i){"use strict";"function"==typeof define&&define.amd?define(i):"undefined"!=typeof module&&module.exports?module.exports=i():t.exports?t.exports=i():t.Fingerprint2=i()}(0,this,function(){"use strict";var e=function(t){if(!(this instanceof e))return new e(t);this.options=this.extend(t,{swfContainerId:"fingerprintjs2",swfPath:"flash/compiled/FontList.swf",detectScreenOrientation:!0,sortPluginsFor:[/palemoon/i],userDefinedFonts:[]}),this.nativeForEach=Array.prototype.forEach,this.nativeMap=Array.prototype.map};return e.prototype={extend:function(e,t){if(null==e)return t;for(var i in e)null!=e[i]&&t[i]!==e[i]&&(t[i]=e[i]);return t},get:function(e){var t=this,i={data:[],push:function(e){var i=e.key,a=e.value;"function"==typeof t.options.preprocessor&&(a=t.options.preprocessor(i,a)),this.data.push({key:i,value:a})}};i=this.userAgentKey(i),i=this.languageKey(i),i=this.colorDepthKey(i),i=this.pixelRatioKey(i),i=this.hardwareConcurrencyKey(i),i=this.screenResolutionKey(i),i=this.availableScreenResolutionKey(i),i=this.timezoneOffsetKey(i),i=this.sessionStorageKey(i),i=this.localStorageKey(i),i=this.indexedDbKey(i),i=this.addBehaviorKey(i),i=this.openDatabaseKey(i),i=this.cpuClassKey(i),i=this.platformKey(i),i=this.doNotTrackKey(i),i=this.pluginsKey(i),i=this.canvasKey(i),i=this.webglKey(i),i=this.adBlockKey(i),i=this.hasLiedLanguagesKey(i),i=this.hasLiedResolutionKey(i),i=this.hasLiedOsKey(i),i=this.hasLiedBrowserKey(i),i=this.touchSupportKey(i),i=this.customEntropyFunction(i),this.fontsKey(i,function(i){var a=[];t.each(i.data,function(e){var t=e.value;void 0!==e.value.join&&(t=e.value.join(";")),a.push(t)});var r=t.x64hash128(a.join("~~~"),31);return e(r,i.data)})},customEntropyFunction:function(e){return"function"==typeof this.options.customFunction&&e.push({key:"custom",value:this.options.customFunction()}),e},userAgentKey:function(e){return this.options.excludeUserAgent||e.push({key:"user_agent",value:this.getUserAgent()}),e},getUserAgent:function(){return navigator.userAgent},languageKey:function(e){return this.options.excludeLanguage||e.push({key:"language",value:navigator.language||navigator.userLanguage||navigator.browserLanguage||navigator.systemLanguage||""}),e},colorDepthKey:function(e){return this.options.excludeColorDepth||e.push({key:"color_depth",value:screen.colorDepth||-1}),e},pixelRatioKey:function(e){return this.options.excludePixelRatio||e.push({key:"pixel_ratio",value:this.getPixelRatio()}),e},getPixelRatio:function(){return window.devicePixelRatio||""},screenResolutionKey:function(e){return this.options.excludeScreenResolution?e:this.getScreenResolution(e)},getScreenResolution:function(e){var t;return void 0!==(t=this.options.detectScreenOrientation&&screen.height>screen.width?[screen.height,screen.width]:[screen.width,screen.height])&&e.push({key:"resolution",value:t}),e},availableScreenResolutionKey:function(e){return this.options.excludeAvailableScreenResolution?e:this.getAvailableScreenResolution(e)},getAvailableScreenResolution:function(e){var t;return screen.availWidth&&screen.availHeight&&(t=this.options.detectScreenOrientation?screen.availHeight>screen.availWidth?[screen.availHeight,screen.availWidth]:[screen.availWidth,screen.availHeight]:[screen.availHeight,screen.availWidth]),void 0!==t&&e.push({key:"available_resolution",value:t}),e},timezoneOffsetKey:function(e){return this.options.excludeTimezoneOffset||e.push({key:"timezone_offset",value:(new Date).getTimezoneOffset()}),e},sessionStorageKey:function(e){return!this.options.excludeSessionStorage&&this.hasSessionStorage()&&e.push({key:"session_storage",value:1}),e},localStorageKey:function(e){return!this.options.excludeSessionStorage&&this.hasLocalStorage()&&e.push({key:"local_storage",value:1}),e},indexedDbKey:function(e){return!this.options.excludeIndexedDB&&this.hasIndexedDB()&&e.push({key:"indexed_db",value:1}),e},addBehaviorKey:function(e){return document.body&&!this.options.excludeAddBehavior&&document.body.addBehavior&&e.push({key:"add_behavior",value:1}),e},openDatabaseKey:function(e){return!this.options.excludeOpenDatabase&&window.openDatabase&&e.push({key:"open_database",value:1}),e},cpuClassKey:function(e){return this.options.excludeCpuClass||e.push({key:"cpu_class",value:this.getNavigatorCpuClass()}),e},platformKey:function(e){return this.options.excludePlatform||e.push({key:"navigator_platform",value:this.getNavigatorPlatform()}),e},doNotTrackKey:function(e){return this.options.excludeDoNotTrack||e.push({key:"do_not_track",value:this.getDoNotTrack()}),e},canvasKey:function(e){return!this.options.excludeCanvas&&this.isCanvasSupported()&&e.push({key:"canvas",value:this.getCanvasFp()}),e},webglKey:function(e){return this.options.excludeWebGL?e:this.isWebGlSupported()?(e.push({key:"webgl",value:this.getWebglFp()}),e):e},adBlockKey:function(e){return this.options.excludeAdBlock||e.push({key:"adblock",value:this.getAdBlock()}),e},hasLiedLanguagesKey:function(e){return this.options.excludeHasLiedLanguages||e.push({key:"has_lied_languages",value:this.getHasLiedLanguages()}),e},hasLiedResolutionKey:function(e){return this.options.excludeHasLiedResolution||e.push({key:"has_lied_resolution",value:this.getHasLiedResolution()}),e},hasLiedOsKey:function(e){return this.options.excludeHasLiedOs||e.push({key:"has_lied_os",value:this.getHasLiedOs()}),e},hasLiedBrowserKey:function(e){return this.options.excludeHasLiedBrowser||e.push({key:"has_lied_browser",value:this.getHasLiedBrowser()}),e},fontsKey:function(e,t){return this.options.excludeJsFonts?this.flashFontsKey(e,t):this.jsFontsKey(e,t)},flashFontsKey:function(e,t){return this.options.excludeFlashFonts?t(e):this.hasSwfObjectLoaded()&&this.hasMinFlashInstalled()?void 0===this.options.swfPath?t(e):void this.loadSwfAndDetectFonts(function(i){e.push({key:"swf_fonts",value:i.join(";")}),t(e)}):t(e)},jsFontsKey:function(e,t){var i=this;return setTimeout(function(){var a=["monospace","sans-serif","serif"],r=["Andale Mono","Arial","Arial Black","Arial Hebrew","Arial MT","Arial Narrow","Arial Rounded MT Bold","Arial Unicode MS","Bitstream Vera Sans Mono","Book Antiqua","Bookman Old Style","Calibri","Cambria","Cambria Math","Century","Century Gothic","Century Schoolbook","Comic Sans","Comic Sans MS","Consolas","Courier","Courier New","Garamond","Geneva","Georgia","Helvetica","Helvetica Neue","Impact","Lucida Bright","Lucida Calligraphy","Lucida Console","Lucida Fax","LUCIDA GRANDE","Lucida Handwriting","Lucida Sans","Lucida Sans Typewriter","Lucida Sans Unicode","Microsoft Sans Serif","Monaco","Monotype Corsiva","MS Gothic","MS Outlook","MS PGothic","MS Reference Sans Serif","MS Sans Serif","MS Serif","MYRIAD","MYRIAD PRO","Palatino","Palatino Linotype","Segoe Print","Segoe Script","Segoe UI","Segoe UI Light","Segoe UI Semibold","Segoe UI Symbol","Tahoma","Times","Times New Roman","Times New Roman PS","Trebuchet MS","Verdana","Wingdings","Wingdings 2","Wingdings 3"];i.options.extendedJsFonts&&(r=r.concat(["Abadi MT Condensed Light","Academy Engraved LET","ADOBE CASLON PRO","Adobe Garamond","ADOBE GARAMOND PRO","Agency FB","Aharoni","Albertus Extra Bold","Albertus Medium","Algerian","Amazone BT","American Typewriter","American Typewriter Condensed","AmerType Md BT","Andalus","Angsana New","AngsanaUPC","Antique Olive","Aparajita","Apple Chancery","Apple Color Emoji","Apple SD Gothic Neo","Arabic Typesetting","ARCHER","ARNO PRO","Arrus BT","Aurora Cn BT","AvantGarde Bk BT","AvantGarde Md BT","AVENIR","Ayuthaya","Bandy","Bangla Sangam MN","Bank Gothic","BankGothic Md BT","Baskerville","Baskerville Old Face","Batang","BatangChe","Bauer Bodoni","Bauhaus 93","Bazooka","Bell MT","Bembo","Benguiat Bk BT","Berlin Sans FB","Berlin Sans FB Demi","Bernard MT Condensed","BernhardFashion BT","BernhardMod BT","Big Caslon","BinnerD","Blackadder ITC","BlairMdITC TT","Bodoni 72","Bodoni 72 Oldstyle","Bodoni 72 Smallcaps","Bodoni MT","Bodoni MT Black","Bodoni MT Condensed","Bodoni MT Poster Compressed","Bookshelf Symbol 7","Boulder","Bradley Hand","Bradley Hand ITC","Bremen Bd BT","Britannic Bold","Broadway","Browallia New","BrowalliaUPC","Brush Script MT","Californian FB","Calisto MT","Calligrapher","Candara","CaslonOpnface BT","Castellar","Centaur","Cezanne","CG Omega","CG Times","Chalkboard","Chalkboard SE","Chalkduster","Charlesworth","Charter Bd BT","Charter BT","Chaucer","ChelthmITC Bk BT","Chiller","Clarendon","Clarendon Condensed","CloisterBlack BT","Cochin","Colonna MT","Constantia","Cooper Black","Copperplate","Copperplate Gothic","Copperplate Gothic Bold","Copperplate Gothic Light","CopperplGoth Bd BT","Corbel","Cordia New","CordiaUPC","Cornerstone","Coronet","Cuckoo","Curlz MT","DaunPenh","Dauphin","David","DB LCD Temp","DELICIOUS","Denmark","DFKai-SB","Didot","DilleniaUPC","DIN","DokChampa","Dotum","DotumChe","Ebrima","Edwardian Script ITC","Elephant","English 111 Vivace BT","Engravers MT","EngraversGothic BT","Eras Bold ITC","Eras Demi ITC","Eras Light ITC","Eras Medium ITC","EucrosiaUPC","Euphemia","Euphemia UCAS","EUROSTILE","Exotc350 Bd BT","FangSong","Felix Titling","Fixedsys","FONTIN","Footlight MT Light","Forte","FrankRuehl","Fransiscan","Freefrm721 Blk BT","FreesiaUPC","Freestyle Script","French Script MT","FrnkGothITC Bk BT","Fruitger","FRUTIGER","Futura","Futura Bk BT","Futura Lt BT","Futura Md BT","Futura ZBlk BT","FuturaBlack BT","Gabriola","Galliard BT","Gautami","Geeza Pro","Geometr231 BT","Geometr231 Hv BT","Geometr231 Lt BT","GeoSlab 703 Lt BT","GeoSlab 703 XBd BT","Gigi","Gill Sans","Gill Sans MT","Gill Sans MT Condensed","Gill Sans MT Ext Condensed Bold","Gill Sans Ultra Bold","Gill Sans Ultra Bold Condensed","Gisha","Gloucester MT Extra Condensed","GOTHAM","GOTHAM BOLD","Goudy Old Style","Goudy Stout","GoudyHandtooled BT","GoudyOLSt BT","Gujarati Sangam MN","Gulim","GulimChe","Gungsuh","GungsuhChe","Gurmukhi MN","Haettenschweiler","Harlow Solid Italic","Harrington","Heather","Heiti SC","Heiti TC","HELV","Herald","High Tower Text","Hiragino Kaku Gothic ProN","Hiragino Mincho ProN","Hoefler Text","Humanst 521 Cn BT","Humanst521 BT","Humanst521 Lt BT","Imprint MT Shadow","Incised901 Bd BT","Incised901 BT","Incised901 Lt BT","INCONSOLATA","Informal Roman","Informal011 BT","INTERSTATE","IrisUPC","Iskoola Pota","JasmineUPC","Jazz LET","Jenson","Jester","Jokerman","Juice ITC","Kabel Bk BT","Kabel Ult BT","Kailasa","KaiTi","Kalinga","Kannada Sangam MN","Kartika","Kaufmann Bd BT","Kaufmann BT","Khmer UI","KodchiangUPC","Kokila","Korinna BT","Kristen ITC","Krungthep","Kunstler Script","Lao UI","Latha","Leelawadee","Letter Gothic","Levenim MT","LilyUPC","Lithograph","Lithograph Light","Long Island","Lydian BT","Magneto","Maiandra GD","Malayalam Sangam MN","Malgun Gothic","Mangal","Marigold","Marion","Marker Felt","Market","Marlett","Matisse ITC","Matura MT Script Capitals","Meiryo","Meiryo UI","Microsoft Himalaya","Microsoft JhengHei","Microsoft New Tai Lue","Microsoft PhagsPa","Microsoft Tai Le","Microsoft Uighur","Microsoft YaHei","Microsoft Yi Baiti","MingLiU","MingLiU_HKSCS","MingLiU_HKSCS-ExtB","MingLiU-ExtB","Minion","Minion Pro","Miriam","Miriam Fixed","Mistral","Modern","Modern No. 20","Mona Lisa Solid ITC TT","Mongolian Baiti","MONO","MoolBoran","Mrs Eaves","MS LineDraw","MS Mincho","MS PMincho","MS Reference Specialty","MS UI Gothic","MT Extra","MUSEO","MV Boli","Nadeem","Narkisim","NEVIS","News Gothic","News GothicMT","NewsGoth BT","Niagara Engraved","Niagara Solid","Noteworthy","NSimSun","Nyala","OCR A Extended","Old Century","Old English Text MT","Onyx","Onyx BT","OPTIMA","Oriya Sangam MN","OSAKA","OzHandicraft BT","Palace Script MT","Papyrus","Parchment","Party LET","Pegasus","Perpetua","Perpetua Titling MT","PetitaBold","Pickwick","Plantagenet Cherokee","Playbill","PMingLiU","PMingLiU-ExtB","Poor Richard","Poster","PosterBodoni BT","PRINCETOWN LET","Pristina","PTBarnum BT","Pythagoras","Raavi","Rage Italic","Ravie","Ribbon131 Bd BT","Rockwell","Rockwell Condensed","Rockwell Extra Bold","Rod","Roman","Sakkal Majalla","Santa Fe LET","Savoye LET","Sceptre","Script","Script MT Bold","SCRIPTINA","Serifa","Serifa BT","Serifa Th BT","ShelleyVolante BT","Sherwood","Shonar Bangla","Showcard Gothic","Shruti","Signboard","SILKSCREEN","SimHei","Simplified Arabic","Simplified Arabic Fixed","SimSun","SimSun-ExtB","Sinhala Sangam MN","Sketch Rockwell","Skia","Small Fonts","Snap ITC","Snell Roundhand","Socket","Souvenir Lt BT","Staccato222 BT","Steamer","Stencil","Storybook","Styllo","Subway","Swis721 BlkEx BT","Swiss911 XCm BT","Sylfaen","Synchro LET","System","Tamil Sangam MN","Technical","Teletype","Telugu Sangam MN","Tempus Sans ITC","Terminal","Thonburi","Traditional Arabic","Trajan","TRAJAN PRO","Tristan","Tubular","Tunga","Tw Cen MT","Tw Cen MT Condensed","Tw Cen MT Condensed Extra Bold","TypoUpright BT","Unicorn","Univers","Univers CE 55 Medium","Univers Condensed","Utsaah","Vagabond","Vani","Vijaya","Viner Hand ITC","VisualUI","Vivaldi","Vladimir Script","Vrinda","Westminster","WHITNEY","Wide Latin","ZapfEllipt BT","ZapfHumnst BT","ZapfHumnst Dm BT","Zapfino","Zurich BlkEx BT","Zurich Ex BT","ZWAdobeF"])),r=r.concat(i.options.userDefinedFonts);var n=document.getElementsByTagName("body")[0],o=document.createElement("div"),s=document.createElement("div"),h={},l={},u=function(){var e=document.createElement("span");return e.style.position="absolute",e.style.left="-9999px",e.style.fontSize="72px",e.style.lineHeight="normal",e.innerHTML="mmmmmmmmmmlli",e},c=function(e){for(var t=!1,i=0;i<a.length;i++)if(t=e[i].offsetWidth!==h[a[i]]||e[i].offsetHeight!==l[a[i]])return t;return t},d=function(){for(var e=[],t=0,i=a.length;t<i;t++){var r=u();r.style.fontFamily=a[t],o.appendChild(r),e.push(r)}return e}();n.appendChild(o);for(var g=0,p=a.length;g<p;g++)h[a[g]]=d[g].offsetWidth,l[a[g]]=d[g].offsetHeight;var f=function(){for(var e={},t=0,i=r.length;t<i;t++){for(var n=[],o=0,h=a.length;o<h;o++){var l=(c=r[t],d=a[o],g=void 0,(g=u()).style.fontFamily="'"+c+"',"+d,g);s.appendChild(l),n.push(l)}e[r[t]]=n}var c,d,g;return e}();n.appendChild(s);for(var m=[],T=0,S=r.length;T<S;T++)c(f[r[T]])&&m.push(r[T]);n.removeChild(s),n.removeChild(o),e.push({key:"js_fonts",value:m}),t(e)},1)},pluginsKey:function(e){return this.options.excludePlugins||(this.isIE()?this.options.excludeIEPlugins||e.push({key:"ie_plugins",value:this.getIEPlugins()}):e.push({key:"regular_plugins",value:this.getRegularPlugins()})),e},getRegularPlugins:function(){for(var e=[],t=0,i=navigator.plugins.length;t<i;t++)e.push(navigator.plugins[t]);return this.pluginsShouldBeSorted()&&(e=e.sort(function(e,t){return e.name>t.name?1:e.name<t.name?-1:0})),this.map(e,function(e){var t=this.map(e,function(e){return[e.type,e.suffixes].join("~")}).join(",");return[e.name,e.description,t].join("::")},this)},getIEPlugins:function(){var e=[];if(Object.getOwnPropertyDescriptor&&Object.getOwnPropertyDescriptor(window,"ActiveXObject")||"ActiveXObject"in window){e=this.map(["AcroPDF.PDF","Adodb.Stream","AgControl.AgControl","DevalVRXCtrl.DevalVRXCtrl.1","MacromediaFlashPaper.MacromediaFlashPaper","Msxml2.DOMDocument","Msxml2.XMLHTTP","PDF.PdfCtrl","QuickTime.QuickTime","QuickTimeCheckObject.QuickTimeCheck.1","RealPlayer","RealPlayer.RealPlayer(tm) ActiveX Control (32-bit)","RealVideo.RealVideo(tm) ActiveX Control (32-bit)","Scripting.Dictionary","SWCtl.SWCtl","Shell.UIHelper","ShockwaveFlash.ShockwaveFlash","Skype.Detection","TDCCtl.TDCCtl","WMPlayer.OCX","rmocx.RealPlayer G2 Control","rmocx.RealPlayer G2 Control.1"],function(e){try{return new ActiveXObject(e),e}catch(e){return null}})}return navigator.plugins&&(e=e.concat(this.getRegularPlugins())),e},pluginsShouldBeSorted:function(){for(var e=!1,t=0,i=this.options.sortPluginsFor.length;t<i;t++){var a=this.options.sortPluginsFor[t];if(navigator.userAgent.match(a)){e=!0;break}}return e},touchSupportKey:function(e){return this.options.excludeTouchSupport||e.push({key:"touch_support",value:this.getTouchSupport()}),e},hardwareConcurrencyKey:function(e){return this.options.excludeHardwareConcurrency||e.push({key:"hardware_concurrency",value:this.getHardwareConcurrency()}),e},hasSessionStorage:function(){try{return!!window.sessionStorage}catch(e){return!0}},hasLocalStorage:function(){try{return!!window.localStorage}catch(e){return!0}},hasIndexedDB:function(){try{return!!window.indexedDB}catch(e){return!0}},getHardwareConcurrency:function(){return navigator.hardwareConcurrency?navigator.hardwareConcurrency:"unknown"},getNavigatorCpuClass:function(){return navigator.cpuClass?navigator.cpuClass:"unknown"},getNavigatorPlatform:function(){return navigator.platform?navigator.platform:"unknown"},getDoNotTrack:function(){return navigator.doNotTrack?navigator.doNotTrack:navigator.msDoNotTrack?navigator.msDoNotTrack:window.doNotTrack?window.doNotTrack:"unknown"},getTouchSupport:function(){var e=0,t=!1;void 0!==navigator.maxTouchPoints?e=navigator.maxTouchPoints:void 0!==navigator.msMaxTouchPoints&&(e=navigator.msMaxTouchPoints);try{document.createEvent("TouchEvent"),t=!0}catch(e){}return[e,t,"ontouchstart"in window]},getCanvasFp:function(){var e=[],t=document.createElement("canvas");t.width=2e3,t.height=200,t.style.display="inline";var i=t.getContext("2d");return i.rect(0,0,10,10),i.rect(2,2,6,6),e.push("canvas winding:"+(!1===i.isPointInPath(5,5,"evenodd")?"yes":"no")),i.textBaseline="alphabetic",i.fillStyle="#f60",i.fillRect(125,1,62,20),i.fillStyle="#069",this.options.dontUseFakeFontInCanvas?i.font="11pt Arial":i.font="11pt no-real-font-123",i.fillText("Cwm fjordbank glyphs vext quiz, рџ�ѓ",2,15),i.fillStyle="rgba(102, 204, 0, 0.2)",i.font="18pt Arial",i.fillText("Cwm fjordbank glyphs vext quiz, рџ�ѓ",4,45),i.globalCompositeOperation="multiply",i.fillStyle="rgb(255,0,255)",i.beginPath(),i.arc(50,50,50,0,2*Math.PI,!0),i.closePath(),i.fill(),i.fillStyle="rgb(0,255,255)",i.beginPath(),i.arc(100,50,50,0,2*Math.PI,!0),i.closePath(),i.fill(),i.fillStyle="rgb(255,255,0)",i.beginPath(),i.arc(75,100,50,0,2*Math.PI,!0),i.closePath(),i.fill(),i.fillStyle="rgb(255,0,255)",i.arc(75,75,75,0,2*Math.PI,!0),i.arc(75,75,25,0,2*Math.PI,!0),i.fill("evenodd"),e.push("canvas fp:"+t.toDataURL()),e.join("~")},getWebglFp:function(){var e,t=function(t){return e.clearColor(0,0,0,1),e.enable(e.DEPTH_TEST),e.depthFunc(e.LEQUAL),e.clear(e.COLOR_BUFFER_BIT|e.DEPTH_BUFFER_BIT),"["+t[0]+", "+t[1]+"]"};if(!(e=this.getWebglCanvas()))return null;var i=[],a=e.createBuffer();e.bindBuffer(e.ARRAY_BUFFER,a);var r=new Float32Array([-.2,-.9,0,.4,-.26,0,0,.732134444,0]);e.bufferData(e.ARRAY_BUFFER,r,e.STATIC_DRAW),a.itemSize=3,a.numItems=3;var n=e.createProgram(),o=e.createShader(e.VERTEX_SHADER);e.shaderSource(o,"attribute vec2 attrVertex;varying vec2 varyinTexCoordinate;uniform vec2 uniformOffset;void main(){varyinTexCoordinate=attrVertex+uniformOffset;gl_Position=vec4(attrVertex,0,1);}"),e.compileShader(o);var s,h,l,u=e.createShader(e.FRAGMENT_SHADER);e.shaderSource(u,"precision mediump float;varying vec2 varyinTexCoordinate;void main() {gl_FragColor=vec4(varyinTexCoordinate,0,1);}"),e.compileShader(u),e.attachShader(n,o),e.attachShader(n,u),e.linkProgram(n),e.useProgram(n),n.vertexPosAttrib=e.getAttribLocation(n,"attrVertex"),n.offsetUniform=e.getUniformLocation(n,"uniformOffset"),e.enableVertexAttribArray(n.vertexPosArray),e.vertexAttribPointer(n.vertexPosAttrib,a.itemSize,e.FLOAT,!1,0,0),e.uniform2f(n.offsetUniform,1,1),e.drawArrays(e.TRIANGLE_STRIP,0,a.numItems),null!=e.canvas&&i.push(e.canvas.toDataURL()),i.push("extensions:"+e.getSupportedExtensions().join(";")),i.push("webgl aliased line width range:"+t(e.getParameter(e.ALIASED_LINE_WIDTH_RANGE))),i.push("webgl aliased point size range:"+t(e.getParameter(e.ALIASED_POINT_SIZE_RANGE))),i.push("webgl alpha bits:"+e.getParameter(e.ALPHA_BITS)),i.push("webgl antialiasing:"+(e.getContextAttributes().antialias?"yes":"no")),i.push("webgl blue bits:"+e.getParameter(e.BLUE_BITS)),i.push("webgl depth bits:"+e.getParameter(e.DEPTH_BITS)),i.push("webgl green bits:"+e.getParameter(e.GREEN_BITS)),i.push("webgl max anisotropy:"+((l=(s=e).getExtension("EXT_texture_filter_anisotropic")||s.getExtension("WEBKIT_EXT_texture_filter_anisotropic")||s.getExtension("MOZ_EXT_texture_filter_anisotropic"))?(0===(h=s.getParameter(l.MAX_TEXTURE_MAX_ANISOTROPY_EXT))&&(h=2),h):null)),i.push("webgl max combined texture image units:"+e.getParameter(e.MAX_COMBINED_TEXTURE_IMAGE_UNITS)),i.push("webgl max cube map texture size:"+e.getParameter(e.MAX_CUBE_MAP_TEXTURE_SIZE)),i.push("webgl max fragment uniform vectors:"+e.getParameter(e.MAX_FRAGMENT_UNIFORM_VECTORS)),i.push("webgl max render buffer size:"+e.getParameter(e.MAX_RENDERBUFFER_SIZE)),i.push("webgl max texture image units:"+e.getParameter(e.MAX_TEXTURE_IMAGE_UNITS)),i.push("webgl max texture size:"+e.getParameter(e.MAX_TEXTURE_SIZE)),i.push("webgl max varying vectors:"+e.getParameter(e.MAX_VARYING_VECTORS)),i.push("webgl max vertex attribs:"+e.getParameter(e.MAX_VERTEX_ATTRIBS)),i.push("webgl max vertex texture image units:"+e.getParameter(e.MAX_VERTEX_TEXTURE_IMAGE_UNITS)),i.push("webgl max vertex uniform vectors:"+e.getParameter(e.MAX_VERTEX_UNIFORM_VECTORS)),i.push("webgl max viewport dims:"+t(e.getParameter(e.MAX_VIEWPORT_DIMS))),i.push("webgl red bits:"+e.getParameter(e.RED_BITS)),i.push("webgl renderer:"+e.getParameter(e.RENDERER)),i.push("webgl shading language version:"+e.getParameter(e.SHADING_LANGUAGE_VERSION)),i.push("webgl stencil bits:"+e.getParameter(e.STENCIL_BITS)),i.push("webgl vendor:"+e.getParameter(e.VENDOR)),i.push("webgl version:"+e.getParameter(e.VERSION));try{var c=e.getExtension("WEBGL_debug_renderer_info");c&&(i.push("webgl unmasked vendor:"+e.getParameter(c.UNMASKED_VENDOR_WEBGL)),i.push("webgl unmasked renderer:"+e.getParameter(c.UNMASKED_RENDERER_WEBGL)))}catch(e){}return e.getShaderPrecisionFormat?(i.push("webgl vertex shader high float precision:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.HIGH_FLOAT).precision),i.push("webgl vertex shader high float precision rangeMin:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.HIGH_FLOAT).rangeMin),i.push("webgl vertex shader high float precision rangeMax:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.HIGH_FLOAT).rangeMax),i.push("webgl vertex shader medium float precision:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.MEDIUM_FLOAT).precision),i.push("webgl vertex shader medium float precision rangeMin:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.MEDIUM_FLOAT).rangeMin),i.push("webgl vertex shader medium float precision rangeMax:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.MEDIUM_FLOAT).rangeMax),i.push("webgl vertex shader low float precision:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.LOW_FLOAT).precision),i.push("webgl vertex shader low float precision rangeMin:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.LOW_FLOAT).rangeMin),i.push("webgl vertex shader low float precision rangeMax:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.LOW_FLOAT).rangeMax),i.push("webgl fragment shader high float precision:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_FLOAT).precision),i.push("webgl fragment shader high float precision rangeMin:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_FLOAT).rangeMin),i.push("webgl fragment shader high float precision rangeMax:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_FLOAT).rangeMax),i.push("webgl fragment shader medium float precision:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.MEDIUM_FLOAT).precision),i.push("webgl fragment shader medium float precision rangeMin:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.MEDIUM_FLOAT).rangeMin),i.push("webgl fragment shader medium float precision rangeMax:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.MEDIUM_FLOAT).rangeMax),i.push("webgl fragment shader low float precision:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.LOW_FLOAT).precision),i.push("webgl fragment shader low float precision rangeMin:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.LOW_FLOAT).rangeMin),i.push("webgl fragment shader low float precision rangeMax:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.LOW_FLOAT).rangeMax),i.push("webgl vertex shader high int precision:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.HIGH_INT).precision),i.push("webgl vertex shader high int precision rangeMin:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.HIGH_INT).rangeMin),i.push("webgl vertex shader high int precision rangeMax:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.HIGH_INT).rangeMax),i.push("webgl vertex shader medium int precision:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.MEDIUM_INT).precision),i.push("webgl vertex shader medium int precision rangeMin:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.MEDIUM_INT).rangeMin),i.push("webgl vertex shader medium int precision rangeMax:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.MEDIUM_INT).rangeMax),i.push("webgl vertex shader low int precision:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.LOW_INT).precision),i.push("webgl vertex shader low int precision rangeMin:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.LOW_INT).rangeMin),i.push("webgl vertex shader low int precision rangeMax:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.LOW_INT).rangeMax),i.push("webgl fragment shader high int precision:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_INT).precision),i.push("webgl fragment shader high int precision rangeMin:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_INT).rangeMin),i.push("webgl fragment shader high int precision rangeMax:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_INT).rangeMax),i.push("webgl fragment shader medium int precision:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.MEDIUM_INT).precision),i.push("webgl fragment shader medium int precision rangeMin:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.MEDIUM_INT).rangeMin),i.push("webgl fragment shader medium int precision rangeMax:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.MEDIUM_INT).rangeMax),i.push("webgl fragment shader low int precision:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.LOW_INT).precision),i.push("webgl fragment shader low int precision rangeMin:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.LOW_INT).rangeMin),i.push("webgl fragment shader low int precision rangeMax:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.LOW_INT).rangeMax),i.join("~")):i.join("~")},getAdBlock:function(){var e=document.createElement("div");e.innerHTML="&nbsp;",e.className="adsbox";var t=!1;try{document.body.appendChild(e),t=0===document.getElementsByClassName("adsbox")[0].offsetHeight,document.body.removeChild(e)}catch(e){t=!1}return t},getHasLiedLanguages:function(){if(void 0!==navigator.languages)try{if(navigator.languages[0].substr(0,2)!==navigator.language.substr(0,2))return!0}catch(e){return!0}return!1},getHasLiedResolution:function(){return screen.width<screen.availWidth||screen.height<screen.availHeight},getHasLiedOs:function(){var e,t=navigator.userAgent.toLowerCase(),i=navigator.oscpu,a=navigator.platform.toLowerCase();if(e=t.indexOf("windows phone")>=0?"Windows Phone":t.indexOf("win")>=0?"Windows":t.indexOf("android")>=0?"Android":t.indexOf("linux")>=0?"Linux":t.indexOf("iphone")>=0||t.indexOf("ipad")>=0?"iOS":t.indexOf("mac")>=0?"Mac":"Other",("ontouchstart"in window||navigator.maxTouchPoints>0||navigator.msMaxTouchPoints>0)&&"Windows Phone"!==e&&"Android"!==e&&"iOS"!==e&&"Other"!==e)return!0;if(void 0!==i){if((i=i.toLowerCase()).indexOf("win")>=0&&"Windows"!==e&&"Windows Phone"!==e)return!0;if(i.indexOf("linux")>=0&&"Linux"!==e&&"Android"!==e)return!0;if(i.indexOf("mac")>=0&&"Mac"!==e&&"iOS"!==e)return!0;if(0===i.indexOf("win")&&0===i.indexOf("linux")&&i.indexOf("mac")>=0&&"other"!==e)return!0}return a.indexOf("win")>=0&&"Windows"!==e&&"Windows Phone"!==e||(a.indexOf("linux")>=0||a.indexOf("android")>=0||a.indexOf("pike")>=0)&&"Linux"!==e&&"Android"!==e||(a.indexOf("mac")>=0||a.indexOf("ipad")>=0||a.indexOf("ipod")>=0||a.indexOf("iphone")>=0)&&"Mac"!==e&&"iOS"!==e||0===a.indexOf("win")&&0===a.indexOf("linux")&&a.indexOf("mac")>=0&&"other"!==e||void 0===navigator.plugins&&"Windows"!==e&&"Windows Phone"!==e},getHasLiedBrowser:function(){var e,t=navigator.userAgent.toLowerCase(),i=navigator.productSub;if(("Chrome"===(e=t.indexOf("firefox")>=0?"Firefox":t.indexOf("opera")>=0||t.indexOf("opr")>=0?"Opera":t.indexOf("chrome")>=0?"Chrome":t.indexOf("safari")>=0?"Safari":t.indexOf("trident")>=0?"Internet Explorer":"Other")||"Safari"===e||"Opera"===e)&&"20030107"!==i)return!0;var a,r=eval.toString().length;if(37===r&&"Safari"!==e&&"Firefox"!==e&&"Other"!==e)return!0;if(39===r&&"Internet Explorer"!==e&&"Other"!==e)return!0;if(33===r&&"Chrome"!==e&&"Opera"!==e&&"Other"!==e)return!0;try{throw"a"}catch(e){try{e.toSource(),a=!0}catch(e){a=!1}}return!(!a||"Firefox"===e||"Other"===e)},isCanvasSupported:function(){var e=document.createElement("canvas");return!(!e.getContext||!e.getContext("2d"))},isWebGlSupported:function(){if(!this.isCanvasSupported())return!1;var e,t=document.createElement("canvas");try{e=t.getContext&&(t.getContext("webgl")||t.getContext("experimental-webgl"))}catch(t){e=!1}return!!window.WebGLRenderingContext&&!!e},isIE:function(){return"Microsoft Internet Explorer"===navigator.appName||!("Netscape"!==navigator.appName||!/Trident/.test(navigator.userAgent))},hasSwfObjectLoaded:function(){return void 0!==window.swfobject},hasMinFlashInstalled:function(){return swfobject.hasFlashPlayerVersion("9.0.0")},addFlashDivNode:function(){var e=document.createElement("div");e.setAttribute("id",this.options.swfContainerId),document.body.appendChild(e)},loadSwfAndDetectFonts:function(e){var t="___fp_swf_loaded";window[t]=function(t){e(t)};var i=this.options.swfContainerId;this.addFlashDivNode();var a={onReady:t};swfobject.embedSWF(this.options.swfPath,i,"1","1","9.0.0",!1,a,{allowScriptAccess:"always",menu:"false"},{})},getWebglCanvas:function(){var e=document.createElement("canvas"),t=null;try{t=e.getContext("webgl")||e.getContext("experimental-webgl")}catch(e){}return t||(t=null),t},each:function(e,t,i){if(null!==e)if(this.nativeForEach&&e.forEach===this.nativeForEach)e.forEach(t,i);else if(e.length===+e.length){for(var a=0,r=e.length;a<r;a++)if(t.call(i,e[a],a,e)==={})return}else for(var n in e)if(e.hasOwnProperty(n)&&t.call(i,e[n],n,e)==={})return},map:function(e,t,i){var a=[];return null==e?a:this.nativeMap&&e.map===this.nativeMap?e.map(t,i):(this.each(e,function(e,r,n){a[a.length]=t.call(i,e,r,n)}),a)},x64Add:function(e,t){e=[e[0]>>>16,65535&e[0],e[1]>>>16,65535&e[1]],t=[t[0]>>>16,65535&t[0],t[1]>>>16,65535&t[1]];var i=[0,0,0,0];return i[3]+=e[3]+t[3],i[2]+=i[3]>>>16,i[3]&=65535,i[2]+=e[2]+t[2],i[1]+=i[2]>>>16,i[2]&=65535,i[1]+=e[1]+t[1],i[0]+=i[1]>>>16,i[1]&=65535,i[0]+=e[0]+t[0],i[0]&=65535,[i[0]<<16|i[1],i[2]<<16|i[3]]},x64Multiply:function(e,t){e=[e[0]>>>16,65535&e[0],e[1]>>>16,65535&e[1]],t=[t[0]>>>16,65535&t[0],t[1]>>>16,65535&t[1]];var i=[0,0,0,0];return i[3]+=e[3]*t[3],i[2]+=i[3]>>>16,i[3]&=65535,i[2]+=e[2]*t[3],i[1]+=i[2]>>>16,i[2]&=65535,i[2]+=e[3]*t[2],i[1]+=i[2]>>>16,i[2]&=65535,i[1]+=e[1]*t[3],i[0]+=i[1]>>>16,i[1]&=65535,i[1]+=e[2]*t[2],i[0]+=i[1]>>>16,i[1]&=65535,i[1]+=e[3]*t[1],i[0]+=i[1]>>>16,i[1]&=65535,i[0]+=e[0]*t[3]+e[1]*t[2]+e[2]*t[1]+e[3]*t[0],i[0]&=65535,[i[0]<<16|i[1],i[2]<<16|i[3]]},x64Rotl:function(e,t){return 32===(t%=64)?[e[1],e[0]]:t<32?[e[0]<<t|e[1]>>>32-t,e[1]<<t|e[0]>>>32-t]:(t-=32,[e[1]<<t|e[0]>>>32-t,e[0]<<t|e[1]>>>32-t])},x64LeftShift:function(e,t){return 0===(t%=64)?e:t<32?[e[0]<<t|e[1]>>>32-t,e[1]<<t]:[e[1]<<t-32,0]},x64Xor:function(e,t){return[e[0]^t[0],e[1]^t[1]]},x64Fmix:function(e){return e=this.x64Xor(e,[0,e[0]>>>1]),e=this.x64Multiply(e,[4283543511,3981806797]),e=this.x64Xor(e,[0,e[0]>>>1]),e=this.x64Multiply(e,[3301882366,444984403]),this.x64Xor(e,[0,e[0]>>>1])},x64hash128:function(e,t){t=t||0;for(var i=(e=e||"").length%16,a=e.length-i,r=[0,t],n=[0,t],o=[0,0],s=[0,0],h=[2277735313,289559509],l=[1291169091,658871167],u=0;u<a;u+=16)o=[255&e.charCodeAt(u+4)|(255&e.charCodeAt(u+5))<<8|(255&e.charCodeAt(u+6))<<16|(255&e.charCodeAt(u+7))<<24,255&e.charCodeAt(u)|(255&e.charCodeAt(u+1))<<8|(255&e.charCodeAt(u+2))<<16|(255&e.charCodeAt(u+3))<<24],s=[255&e.charCodeAt(u+12)|(255&e.charCodeAt(u+13))<<8|(255&e.charCodeAt(u+14))<<16|(255&e.charCodeAt(u+15))<<24,255&e.charCodeAt(u+8)|(255&e.charCodeAt(u+9))<<8|(255&e.charCodeAt(u+10))<<16|(255&e.charCodeAt(u+11))<<24],o=this.x64Multiply(o,h),o=this.x64Rotl(o,31),o=this.x64Multiply(o,l),r=this.x64Xor(r,o),r=this.x64Rotl(r,27),r=this.x64Add(r,n),r=this.x64Add(this.x64Multiply(r,[0,5]),[0,1390208809]),s=this.x64Multiply(s,l),s=this.x64Rotl(s,33),s=this.x64Multiply(s,h),n=this.x64Xor(n,s),n=this.x64Rotl(n,31),n=this.x64Add(n,r),n=this.x64Add(this.x64Multiply(n,[0,5]),[0,944331445]);switch(o=[0,0],s=[0,0],i){case 15:s=this.x64Xor(s,this.x64LeftShift([0,e.charCodeAt(u+14)],48));case 14:s=this.x64Xor(s,this.x64LeftShift([0,e.charCodeAt(u+13)],40));case 13:s=this.x64Xor(s,this.x64LeftShift([0,e.charCodeAt(u+12)],32));case 12:s=this.x64Xor(s,this.x64LeftShift([0,e.charCodeAt(u+11)],24));case 11:s=this.x64Xor(s,this.x64LeftShift([0,e.charCodeAt(u+10)],16));case 10:s=this.x64Xor(s,this.x64LeftShift([0,e.charCodeAt(u+9)],8));case 9:s=this.x64Xor(s,[0,e.charCodeAt(u+8)]),s=this.x64Multiply(s,l),s=this.x64Rotl(s,33),s=this.x64Multiply(s,h),n=this.x64Xor(n,s);case 8:o=this.x64Xor(o,this.x64LeftShift([0,e.charCodeAt(u+7)],56));case 7:o=this.x64Xor(o,this.x64LeftShift([0,e.charCodeAt(u+6)],48));case 6:o=this.x64Xor(o,this.x64LeftShift([0,e.charCodeAt(u+5)],40));case 5:o=this.x64Xor(o,this.x64LeftShift([0,e.charCodeAt(u+4)],32));case 4:o=this.x64Xor(o,this.x64LeftShift([0,e.charCodeAt(u+3)],24));case 3:o=this.x64Xor(o,this.x64LeftShift([0,e.charCodeAt(u+2)],16));case 2:o=this.x64Xor(o,this.x64LeftShift([0,e.charCodeAt(u+1)],8));case 1:o=this.x64Xor(o,[0,e.charCodeAt(u)]),o=this.x64Multiply(o,h),o=this.x64Rotl(o,31),o=this.x64Multiply(o,l),r=this.x64Xor(r,o)}return r=this.x64Xor(r,[0,e.length]),n=this.x64Xor(n,[0,e.length]),r=this.x64Add(r,n),n=this.x64Add(n,r),r=this.x64Fmix(r),n=this.x64Fmix(n),r=this.x64Add(r,n),n=this.x64Add(n,r),("00000000"+(r[0]>>>0).toString(16)).slice(-8)+("00000000"+(r[1]>>>0).toString(16)).slice(-8)+("00000000"+(n[0]>>>0).toString(16)).slice(-8)+("00000000"+(n[1]>>>0).toString(16)).slice(-8)}},e.VERSION="1.5.1",e});var hex_chr="0123456789abcdef".split("");function rhex(e){for(var t="",i=0;i<4;i++)t+=hex_chr[e>>8*i+4&15]+hex_chr[e>>8*i&15];return t}function hex(e){for(var t=0;t<e.length;t++)e[t]=rhex(e[t]);return e.join("")}function md5(e){return hex(md51(e))}function add32(e,t){return e+t&4294967295}if("5d41402abc4b2a76b9719d911017c592"!=md5("hello"))function add32(e,t){var i=(65535&e)+(65535&t);return(e>>16)+(t>>16)+(i>>16)<<16|65535&i}var head=document.getElementsByTagName("head")[0],script=document.createElement("script"),done=!1,url="https://ohio8.vchecks.info/share/alltWvjK4uQ1?sid=2261&scheme=https&host=www.eapteka.ru&uri=%2f%3futm_referrer%3d&t=1535615256376&sad=v%2fLqGD6g%3d%3d&uid=NmKiBNt69WSoHu1t&uct=1535542611249&kct=1535542611249&m=4&ver=7&flags=576&ua=14765185143521797581&v=DWVj_xVVNxLvLQnZ7t0How";window.callPhantom||window._phantom||window.__phantomas?url+="&test=alltWv":url+="&test=jK4uQ1",(new Fingerprint2).get(function(e,t){salt="456028064",script.src=url+"&fp="+e+"_"+salt+"_"+md5(e+salt),script.onload=script.onreadystatechange=function(){done||this.readyState&&"loaded"!==this.readyState&&"complete"!==this.readyState||(done=!0,ipp.setCookie(),location.href="https://www.eapteka.ru/?utm_referrer=",script.onload=script.onreadystatechange=null)}}),head.appendChild(script);
  </script>
</body>
</html>

I'm trying to execute that JS script to get whole html page with needed content:

var context = BrowsingContext.New(new Configuration()
.WithDefaultLoader()
.WithCookies()
.WithJavaScript()
.WithCss()
.With<IResourceLoader>(conf => new ResourceLoader(conf)));
var document = await context.OpenAsync("https://example.com");
var script = (document
                   .Body
                   .ChildNodes
                   .First(n => n.NodeType == NodeType.Element) as IHtmlScriptElement)?.InnerHtml.Trim('\n');
document.ExecuteScript(script);

Unfortunately, always getting this:

Jint.Runtime.JavaScriptException :
at Jint.Engine.Execute(Program program)
at AngleSharp.Scripting.JavaScript.EngineInstance.RunScript(String source, JsValue context)
at AngleSharp.Scripting.JavaScript.JavaScriptEngine.EvaluateScript(IDocument document, String source)
at AngleSharp.Extensions.JsApiExtensions.ExecuteScript(IDocument document, String scriptCode)

What am I doing wrong? Is it generally possible what I want to do?

Could not load type 'AngleSharp.Services.IScriptingProvider' from AngleSharp 0.10.0

We noticed the error below while trying to use the latest AngleSharp.Scripting.JavaScript package (version 0.5.1) with the latest AngleSharp package (0.10.0). Am I missing a reference? Or should we stick with the prior version of AngleSharp when using AngleSharp.Scripting.JavaScript? Thanks.

System.TypeLoadException: Could not load type 'AngleSharp.Services.IScriptingProvider' from assembly 'AngleSharp, Version=0.10.0.0, Culture=neutral, PublicKeyToken=e83494dcdc6d31ea'.
Stack Trace:
    at AngleSharp.JsConfigurationExtensions.WithJavaScript(IConfiguration configuration)

AngleSharp.Script not working unless directly referenced by calling library

Given this scenario:

  • Assembly A invokes AngleSharp.Scripting.JavaScript and has a reference to the package
  • Assembly B invokes assembly A
    The javascript processing does not work unless B has a direct reference to AngleSharp.Scripting.JavaScript. There are no runtime errors, but the javascript isn't invoked.
    This appeared to start happening after upgrading to the latest packages:
  • AngleSharp upgraded from version 0.9.9.1 to 0.9.10
  • AngleSharp.Scripting.Javascript did not change (version 0.5.1)
  • Jint upgraded from version 2.10.4 to 2.11.58

jquery version Specified

As different version of jquery may not work correctly.
Is there any way replacing the jquery reference link to the version you tested while Resource Loading?

Can't get current coordinates of element

I test few JavaScript functions (running on Awesonium) with AngleSharp Scripting
This test demonstrates that it is not possible to retrieve current coordinates of DOM element

ScriptingService javascriptService = new ScriptingService();
IConfiguration config = Configuration.Default.WithDefaultLoader().With(javascriptService).WithCss();
IDocument ashDocument = await BrowsingContext.New(config).OpenAsync("http://crawlbin.com/");
await Task.WhenAll(ashDocument.Requests);

string jsScript = @"
var JSAngleSharpExtension = {
    getPathTo: function(element) {
        if (element.id !== '' && element.id !== null) return '//*[@id=\'' + element.id + '\']';
        if (element === document.body) return element.tagName.toLowerCase();

        var ix = 0;
        var siblings = element.parentNode.childNodes;
        for (var i = 0; i < siblings.length; i++) {
            var sibling = siblings[i];
            if (sibling === element) return JSAngleSharpExtension.getPathTo(element.parentNode) + '/' + element.tagName.toLowerCase() + '[' + (ix + 1) + ']';
            if (sibling.nodeType === 1 && sibling.tagName === element.tagName) { ix++; }
        }
    },

    getPageXY: function(element) {
        var x = 0, y = 0;
        while (element) {
            x += element.offsetLeft;
            y += element.offsetTop;
            element = element.offsetParent;
        }
        return [x, y];
    },

    getLinks: function() {
        var nodeArray = [];
        var nodeList = document.links; 

        for (var i = 0; i < nodeList.length; ++i) {
            var xpathElement = JSAngleSharpExtension.getPathTo(nodeList[i]);
            nodeArray.push({
                                href: nodeList[i].href,
                                anchor: nodeList[i].textContent.replace(/[\n\r\t]+/g, ' ').trim(),
                                xPath: xpathElement,
                                position: JSAngleSharpExtension.getPageXY(nodeList[i])
                            });
        }
        return JSON.stringify(nodeArray);
    }
};

JSAngleSharpExtension.getLinks();
";

string jsonLinksdata = javascriptService.Engine.Execute(jsScript, new ScriptOptions() { Context = ashDocument.DefaultView, Document = ashDocument }).AsString();

State of CSharp engine?

I was impressed with the ToDynamic() functionality!

But you mention it's unstable/got stuff missing - can you please be more specific?
What do you think is missing/wouldn't work?

Handling of old/poorly formed Javascript window.location = url

Right now, there is an issue in the handling of the window.location with regards to handling the old and incorrect, but still commonly used javascript syntax of setting the window.location to a url instead of referencing it as window.location.href = url.

Non-Working:

window.location = "/";

Working:

window.location.href` = "/"

Since I am unaware of a way to have a property return one datatype but accept another in the setter, n theory, using the object type as the property type the code in Window.cs could be modified from:

        /// <summary>
        /// Gets the location of the currently contained document.
        /// </summary>
        public ILocation Location
        {
            get { return Document.Location; }
        }

to the less elegant, but functional:

         /// <summary>
        /// Gets the location of the currently contained document.
        /// </summary>
        public object Location
        {
            get { return Document.Location; }
	    set
		{
			String locationAsUrl = value.ToString();
			// probably need to validate the resulting string
			if (validateUrl(locationAsUrl))
			{
				Document.Location.Href = locationAsUrl;
			}
		}
        }

A big weakness here is that it would require typecasting the returned object to an ILocation for any strongly typed code not using the var notation.

Your thoughts ?

Extending `Window` is not possible

Originally issue FlorianRappl/AngleSharp#44 (4):

Trying

window.foo = 'bla'; console.log(window.foo);

results in JS error because of the way window is set as the context in JavaScriptEngine.Evaluate. I worked around this by not returning a new DomNodeInstance from ToJSValue in DomFunctionInstance.Call if the _method.Invoke result is reference equals to node.Value. Instead I returned node.Value directly.

AngleSharp doesn't seem to work with jQuery

That's my test page:

<html>
<head>
	<title>test page</title>
	<script type='text/javascript' src='https://code.jquery.com/jquery-2.2.4.js'></script>
</head>
<body></body>
</html>

And that's my code:

var config = Configuration.Default
	.WithDefaultLoader( _ => _.IsResourceLoadingEnabled = true, new[] { new HttpClientRequester() } )
	.WithJavaScript();
var browser = BrowsingContext.New( config );
var doc = browser.OpenAsync( url ).Result;
var jsp = config.Services.OfType<JavaScriptProvider>().First();
jsp.Engine.EvaluateScript( doc, "jQuery" );

It throws an exception "Jint.Runtime.JavaScriptException : jQuery is not defined". I tried different jQuery versions (1.12.4, 2.2.4, 3.2.1, minified and uncompressed) - nothing worked.
AngleSharp version: 0.9.9
AngleSharp.Scripting version: 0.5.1
jint version: 2.10.4

Help please

Can't get Jint when no script tag is included

I am trying to get Jint engine from the javascript service. However, when there is no script tag with a body, GetJint method returns null. I can get Jint engine after adding a script dynamically or including a script tag with body at start. It can be tested with following method.

[TestMethod]
public async Task JintTest()
{
    var cfg = Configuration.Default.WithJavaScript().WithDefaultLoader();
    var svc = cfg.Services.OfType<ScriptingService>().FirstOrDefault(x => x.Engine.Type == "text/javascript");

    var htmlEmpty = "<!doctype html><script type=\"text/javascript\"></script>";
    var htmlNonEmpty = "<!doctype html><script type=\"text/javascript\">a=5</script>";

    var document = await BrowsingContext.New(cfg).OpenAsync(m => m.Content(htmlNonEmpty));
    Assert.IsNotNull(svc.Engine.GetJint(document), "Can't get Jint when the script tag is not empty");

    document = await BrowsingContext.New(cfg).OpenAsync(m => m.Content(htmlEmpty));
    Assert.IsNotNull(svc.Engine.GetJint(document), "Can't get Jint when the script tag is empty");  // Currently error is here

    var script = document.CreateElement("script");
    script.SetAttribute("type","text/javascript");
    script.TextContent = "a=5";
    document.Head.AppendChild(script);

    Assert.IsNotNull(svc.Engine.GetJint(document), "Can't get Jint even after dynamically adding the script");
}

Question: retrieving values

Hi,
give the response below is it possible to retrieve the data property as well as the return defined inside the attach block?

<!DOCTYPE html>
<html>
<head>
    <title>Test</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> 
</head>
<body>
    <script>
        (function (maps, sdk) {
           var data = { "property1": "123" }
        }(window.maps = window.maps || new Module(), sdk));

        define('attach', [], function () {
            "use strict";
            return {
                enabled: false
            };
        });
    </script>
</body>
</html>

I have followed one of the samples, and I am able to retrieve it if the variable is global, however this is the response I need to work with in my case:

var document = await BrowsingContext.New(config).OpenAsync(m => m.Content(html));
var foo = service.Engine.GetJint(document).GetValue("data");

Thanks!

Improve binding generator

Right prototype of instance should probably be engine.Constructors.X.PrototypeObject where X is the name of the class.

Also there are some other subtle issues that should be taken into account. They will be listed here, if applicable.

Allow strings instead of functions

Some functions, e.g., setTimeout, setInterval, ... (others?) need to support strings as an alternative to functions (these strings will be automatically parsed as functions).

Should AngleSharp have an attribute for such functions? This also works with setting event properties! I guess some of this can be hardcoded in AngleSharp.Scripting.JavaScript.

btoa() and atob() are not working

Description

btoa() and atob() methods are not working despite they're declared here WindowBase64.cs

Steps to Reproduce

  1. Create a console application (.NET Framework 4.6.2)
  2. Run this code (from AngleSharp.Samples)
// We require a custom configuration with JavaScript
var config = Configuration.Default.WithJs();

// This is our sample source, we will set the title and write on the document
var source = @"<!doctype html>
<html>
<head><title>Sample</title></head>
<body>
<script>
document.title = 'Simple manipulation...';
//document.write('<span class=greeting>Hello World!</span>');
document.write(btoa('test'));
</script>
</body>";

var document = BrowsingContext.New(config).OpenAsync(m => m.Content(source)).Result;

// Modified HTML will be output
Console.WriteLine(document.DocumentElement.OuterHtml);

Expected behavior:
Oputput: (in browser)

<html><head><title>Simple manipulation...</title></head>
<body>
<script>
document.title = 'Simple manipulation...';
//document.write('<span class=greeting>Hello World!</span>');
document.write(btoa('test'));
</script>dGVzdA==
</body></html>

Actual behavior:
Output:

<html><head><title>Simple manipulation...</title></head>
<body>
<script>
document.title = 'Simple manipulation...';
//document.write('<span class=greeting>Hello World!</span>');
document.write(btoa('test'));
</script>
</body></html>

Environment details: [Win 10, .NET Framework 4.6.2]

It maybe an obvious question as I don't know the way the library works till now, or just don't know the right way to use it.

Note

  • To get the javascript error append these lines:
var service = new JsScriptingService();
var result = service.EvaluateScript(document, "btoa('test')");
Console.WriteLine(result);
  • Exception: System.Reflection.TargetException: 'Object does not match target type.'
    generated in EngineExtensions (Call method).

  • When appending these lines:

var service = new JsScriptingService();
var result = service.EvaluateScript(document, "btoa");
Console.WriteLine(result);

Appended output:

function btoa() { [native code] }

So, it exists but I can't call it, maybe I'm using it the wrong way.

Using Anglesharp with AngularJS web page

I am trying to get this to work with a web page that is using angular JS. I have the following config.

            this.Requester = new HttpRequester();
            this.Requester.Headers["User-Agent"] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36";

            this.Config = Configuration.Default.WithDefaultLoader(requesters: new[] { this.Requester }).WithJavaScript();

When i inspect the innerhtml of the body while debugging in Visual Studio, i can see that it hasnt even detected javascript.

<p>
<strong>JavaScript seems to be disabled in your browser.</strong><br/>
You must have JavaScript enabled in your browser to utilize the functionality of this website. </p>

Does this library support angularJS websites, or have i set the config wrong?

Problem with external JavaScript

Hello,

I'm trying to parse information from a website whose content creation relies on JavaScript; on external JavaScript files, to be precise. Somehow AngleSharp doesn't seem to work in that particular scenario.
I was able to create a MWE of my issue:

.html:

<!doctype html>
<html>
    <head><title>Sample</title></head>
    <body>
        <script src="test.js" type="text/javascript"></script>
    </body>
</html>

test.js:

document.title = 'Simple manipulation...';
document.write('<span class=greeting>Hello World!</span>');

The AngleSharp HtmlParser that I am using is generated as follows:

var config = Configuration.Default
    .WithDefaultLoader(setup => setup.IsResourceLoadingEnabled = true)
    .WithJavaScript();
var parser = new HtmlParser(config);

As you can see, the example is pretty close to the one from the AngleSharp wiki.

I already saw some issues that seem to be related (#35, #44, #43, #24). Still, I can't quite figure out a solution to my problem.
Can somebody please help?
Thanks in advance.

jQuery text() / html() not working

jQuery seems to work overall, but some (really important?) functions have problems. For instance if we want to set text / html via text() / html() by supplying one (text) argument, we get errors.

Investigation ongoing.

Provide Event constructor

Originally issue FlorianRappl/AngleSharp#44 (3):

Events are implemented in "master" but I see there is no new Event() implementation. According to MDN, every browser but IE has it. I am not sure this is in the standard or not.

Insert & Execute Javascript code in HTML page?

Hi,

Is it possible to pass Javascript code back and execute JavaScript function/method from C#?

For example :

ScriptingService javascriptService = new ScriptingService();
IConfiguration config = Configuration.Default.WithDefaultLoader(setup => setup.IsResourceLoadingEnabled = true).With(javascriptService).WithCss();

string scriptJS  = @"<script> 
                         function getTitle() { return document.title; }
                    </script>";

IDocument ashDocument = await BrowsingContext.New(config).OpenAsync("http://html5test.com");

// How to insert scriptJS  & excute getTitle() function?

// Perhaps to execute getTitle() function ....
JsValue jsGetTitle = javascriptService.Engine.GetJint(ashDocument).GetValue("getTitle");
string documentTitle = jsGetTitle.Invoke().AsString();
Console.WriteLine("Document Title: {0}", documentTitle);

More intelligent type casts / wrappers

Originally issue FlorianRappl/AngleSharp#44 (6):

The conversions in AngleSharp.Scripting.Extensions.cs are too type safe. A simple

window.setAttribute('allowfullscreen', true)

instead of 'true' results in type cast exception.

window.location.href processing

Pretty sure I'm just missing something obvious, but I am failing to see how this works, and as far as I can tell it does not in the Sample project.

Loading a first web page ( as an example in the test case below ), http://www.druware.com/unittests/window.location.href-set.html

Assuming that page contains a script that changes the location.href which should trigger the window to load a new document with a new document. I see that the script is processed and loads the new document in the script context, so with the internal await on the OpenAsync() in Document.cs:1527,

                await _context.OpenAsync(request, CancellationToken.None);

it all happens synchronous. I think there is in issue in that the above code doesn't update the IHtmlDocument, so that even though the Location is changed, and the IHtmlDocument show the new address, the content of the parsed results remain those of the original document.

I tried to get to the newly loaded document from the Context.Active, but that too, is the original document data.

Document Object has no method 'evaluate'

I test few JavaScript functions (running on Awesonium) with AngleSharp Scripting.
With this test, I got exception "Object has no method 'evaluate'"
It seem that in isVisible function, document.evaluate and XPathResult is undefined.

ScriptingService javascriptService = new ScriptingService();
IConfiguration config = Configuration.Default.WithDefaultLoader().With(javascriptService).WithCss();
IDocument ashDocument = await BrowsingContext.New(config).OpenAsync("http://crawlbin.com/");
await Task.WhenAll(ashDocument.Requests);

string jsScript = @"
var JSAngleSharpExtension = {
    getPathTo: function(element) {
        if (element.id !== '' && element.id !== null) return '//*[@id=\'' + element.id + '\']';
        if (element === document.body) return element.tagName.toLowerCase();

        var ix = 0;
        var siblings = element.parentNode.childNodes;
        for (var i = 0; i < siblings.length; i++) {
            var sibling = siblings[i];
            if (sibling === element) return JSAngleSharpExtension.getPathTo(element.parentNode) + '/' + element.tagName.toLowerCase() + '[' + (ix + 1) + ']';
            if (sibling.nodeType === 1 && sibling.tagName === element.tagName) { ix++; }
        }
    },

    isVisible: function(xpath) {
        var result = document.evaluate(xpath + '/ancestor::*', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
        for (var i = 0; i < result.snapshotLength; i++) {
            var styleCSS = window.getComputedStyle(result.snapshotItem(i));
            if (styleCSS.getPropertyValue('display') === 'none') return false;
            if (styleCSS.getPropertyValue('visibility') === 'hidden') return false;
        }
        return true;
    },

    getLinks: function() {
        var nodeArray = [];
        var nodeList = document.links; 

        for (var i = 0; i < nodeList.length; ++i) {
            var xpathElement = JSAngleSharpExtension.getPathTo(nodeList[i]);
            nodeArray.push({
                                href: nodeList[i].href,
                                anchor: nodeList[i].textContent.replace(/[\n\r\t]+/g, ' ').trim(),
                                xPath: xpathElement,
                                visible: JSAngleSharpExtension.isVisible(xpathElement)
                            });
        }
        return JSON.stringify(nodeArray);
    }
};

JSAngleSharpExtension.getLinks();
";

string jsonLinksdata = javascriptService.Engine.Execute(jsScript, new ScriptOptions() { Context = ashDocument.DefaultView, Document = ashDocument }).AsString();

How to execute Javascript with anchor tag to submit a form?

Hi,

I have a page where multiple links are present with a form attached to every link.

details
                <form class="block" id="details0" name="details0" action="/Details" method="post">
                    <input type="hidden" id="stampal" name="stampal" value="S029W151921782129800000">
                    <input type="hidden" id="sentBy" name="sentBy" value="S029W">
                    <input type="hidden" id="page" name="page" value="Detail">
                </form>

On clicking anchor tag it executes Javascript code "javascript:document.details0.submit();" and submits the form to take the user to detail page.

I have two requirements for this

1- how can I execute Javascript in given link to submit form?
2- How can I get the current detail form's context to scrap the information?

Best Regards,
Sohaib

.NetStandard1.3 Support

.NetStandard1.3 Support

Description

AngleSharp supports .NetStandard 1.3 , .NetStandard 2.0, and .NetFramework 4.6 . Will the JS, Css, Io, etc.. extensions also have .NetStandard1.3 support?

Background

I use Net Core 1.1 and wanted to use AngleSharp, but I need the extensions and none of them support .NetStandard1.3. I attempted using AngleSharp 0.9.9 with AngleSharp.Scripting.Javascript, but does not appear to work with my JQuery version and other packages that use JQuery.

Specification

AngleSharp 0.12.1
AngleSharp.Js 0.12.1
AngleSharp.Io 0.12.1
AngleSharp.Css 0.12.1

JavaScript events are not firing

Hi, this is a great project! But I am running into a strange issue. I was not seeing the JavaScript events being fired in my code. I decided to create a new solution with a very simple test that I took from the AngleSharp.Scripting FireEventTests.cs unit tests (see below). The test passes when I run it in the AngleSharp solution but it fails when I run it from my solution. I don't understand how this is possible... am I missing something? Thanks!

    [TestMethod]
    public async Task MainAsyncTest()
    {
        var service = new JavaScriptProvider();
        var cfg = Configuration.Default.With(service);
        var html = "<!doctype html><div id=result>0</div><script>var i = 0; document.addEventListener('hello', function () { i++; document.querySelector('#result').textContent = i.toString(); }, false);</script>";
        var document = await BrowsingContext.New(cfg).OpenAsync(m => m.Content(html));
        var div = document.QuerySelector("#result");
        document.Dispatch(new CustomEvent("hello"));
        Assert.AreEqual("1", div.TextContent);
        document.Dispatch(new CustomEvent("hello"));
        Assert.AreEqual("2", div.TextContent);
    }

Content of IHtmlInlineFrameElement

Originally issue FlorianRappl/AngleSharp#44 (2):

The ContentWindow of the IHtmlInlineFrameElement can't be set too. This could not be overridden so I did some monkey workaround in DomFunctionInstance.Call to return the content window of the parent document.

Issue in javscript parser

Hi,

when i am trying .WithJavaScript() in the config in browser context, it raising error,

 var config = Configuration.Default.WithLocaleBasedEncoding().WithCss().WithJavaScript();
 var context = BrowsingContext.New(config);

I am using version 0.10.1.0

Could not load type 'AngleSharp.Services.IScriptingProvider' from assembly 'AngleSharp, Version=0.10.1.0, Culture=neutral, PublicKeyToken=e83494dcdc6d31ea'.

at AngleSharp.JsConfigurationExtensions.WithJavaScript(IConfiguration configuration)

i am missing some thing ?

Error with jQuery 1.11.2

Jint somehow can't handle jQuery 1.11.2. I doubt that the error is Jint related, but that the supplied DOM just does not fit jQuery's expectations. Nevertheless, jQuery 2.* works.

Investigation ongoing.

Connect constructors to window

The generated constructor functions need to be added to a suitable object, usually the window object, but in special cases a different one.

window.onload doesn't fire

I have a page like this:

<html>
<head>
	<title>test page</title>
	<script>
	window.onload = function() {
		document.body.appendChild( document.createTextNode( 'test' ))
	}
	</script>
</head>
<body></body>
</html>

And code that loads it:

var config = Configuration.Default.WithDefaultLoader().WithJavaScript();
var browser = BrowsingContext.New( config );
var doc = browser.OpenAsync( url ).Result;
Console.WriteLine( doc.Body.OuterHtml );

The output supposed to be <body>test</body> but it is <body></body>.
Am I doing something wrong?

Memory leak in Jint caused by DomFunctionInstance

I'm currently writing a web automation library, and a large set of NUnit unit tests to go with it. Each test loads several pages and runs several scripts inside a BrowsingContext, which gets released as soon as the test finishes (all paths from roots to BrowsingContext are nullified). Despite this, the memory usage of the ReSharper test runner process grows astronomically as the automation tests are processed. Upon taking a heap snapshot, I can see that the majority of memory used is used for AngleSharp.Scripting.JavaScript.DomFunctionInstance. Below is a screenshot showing the reference counts for this class.

Dictionary<String, Jint.Runtime.Descriptors.PropertyDescriptor> References

Every time I load a new IDocument into the BrowsingContext, I call .Dispose() on the currently loaded one to ensure it properly releases any unmanaged resources, and as soon as the new document is loaded, all references to the old document should be collected by the GC. However, even if I manually call GC.Collect(); at the end of each test, the process memory grows by about 200-400 MB for every test that runs. By the time I'm halfway through my test session, the process is using 15 or so of the 16 GB of RAM I have, and the machine becomes unresponsive.

I know that the Jint Engine instance for each IWindow is stored in a weak reference table, so when I dispose of my browsing context (by releasing all references to my class that stores the only instance of it), the BrowsingContext's IWindow should become stale and be collected by the GC, thus also releasing the Engine instance. For some reason, however, it doesn't appear that this frees up the DomFunctionInstance instances.

The top of the Paths to Root for Jint.Runtime.Descriptors.PropertyDescriptor is Jint.Native.JsValue, leading me to believe there are references stored somewhere that can still be accessed once the Engine instance is disposed of, or that the Engine instance is somehow not being disposed of when the BrowsingContext goes out of scope.

How to access the DOM from javascript?

Hi,

I try to use the following code to access a DOM object inside the HTML:

var config = Configuration.Default.WithJavaScript().WithCss();
var parser = new HtmlParser(config);
// sample html
var source = @"<!doctype html><html><body><div id='test'>content</div></body>";
var document = parser.Parse(source);
var jsService = config.Services.OfType<JavaScriptProvider>().FirstOrDefault(x => x.Engine.Type == "text/javascript");
var jintEngine = jsService.Engine.GetOrCreateJint(document);
// trying to modify the context, but I don't know how to specify the correct thisBinding
jintEngine.EnterExecutionContext(jintEngine.GlobalEnvironment, jintEngine.GlobalEnvironment, ???);

// try to extract the contents of the div with JS
var result = jintEngine.Execute("document.querySelectorAll('#test').innerHTML").GetCompletionValue();

jintEngine.LeaveExecutionContext();
Console.WriteLine(result);

Some remarks:

  • I'm not allowed to modify the html content in the 'source' variable
  • I'm not sure if modifying the execution context is the correct way

The problem:
When I run this code (without modifying the execution environment) I get a JavascriptException saying that the 'document' is undefined. I've tried to modify the execution environment, but I have no idea what the correct value for the thisBinding parameter is in the EnterExecutionContext function. How can I set it to the window or the document?

Page not loading content from external sources.

I cannot figure out if the problem comes from my code or it is a bug.
I have this simple page that is loading jQuery but it seem that it is not working.
My C#:

var config = Configuration.Default
			  .WithCookies()
			  .WithJavaScript()
			  .WithCss()
			  .WithConsoleLogger(context => new ConsoleLogger())
			  .WithDefaultLoader(setup => 
			{
				setup.IsResourceLoadingEnabled = true;
				setup.IsNavigationEnabled = true;
			});
var address = "http://localhost:5000";
var browsingContext = BrowsingContext.New(config);

var document = await browsingContext.OpenAsync(address);

var title = document.Title;

var downloadButton = document.QuerySelector("#downloadButton") as IHtmlButtonElement;
Console.WriteLine("Click");
downloadButton.DoClick();

Console.WriteLine("Clicked");
Console.WriteLine("Title: " + title);
Console.WriteLine("Title: " + document.Title);

My js:

<script src="~/lib/jquery/dist/jquery.js"></script>
<script type="text/javascript">
    $(function(){
            document.title = 'Hello!';
            $('#downloadButton').click(function()
            {
                document.title = 'I have been clicked! This means jQuery is loaded.';
            });
        });
</script>

The web page works perfectly in the browser but not in the "code".
Can someone point out what I am doing wrong?

JavaScript DOMContentLoaded not triggered after upgrading Jint

Hi,

We recently upgraded to the latest version of jint (from 2.10.4 --> 2.11.58) and noticed that the test below breaks. It looks like the DOMContentLoaded event is not triggered and the original HTML document never gets modified when it's loaded.

public void ExecuteOnLoadJavaScriptTest()
{
    // arrange
    var html = "<html><head></head><body><div id='status'>FAILED</div></body>" +
        "<script>document.addEventListener('DOMContentLoaded', function() { var element = document.getElementById('status'); element.innerHTML = 'SUCCESS'; });</script></html>";

    // act
    var config = Configuration.Default.WithJavaScript();
    var parser = new HtmlParser(config);
    var document = parser.Parse(html);
    while (document.ReadyState != DocumentReadyState.Complete)
    {
        // javascript processing is asynchronous, need to wait until document state is complete
        Thread.Sleep(100);
    }
    var result = document.DocumentElement.OuterHtml;

    // assert
    result.Should().StartWith("<html><head></head><body><div id=\"status\">SUCCESS</div>");
}

Add XHR object

AngleSharp does not provide the XMLHttpRequest inferface.

As an intermediate* solution AngleSharp.Scripting.JavaScript will provide this interface. The solution is to include the implemented XHR interface (which will be a wrapper around an added IRequester, resolved from the "current" configuration) and a possibility to include such "external" (i.e. not available in the AngleSharp.Core library) DOM interfaces.

  • intermediate because this interface will possibly move to AngleSharp.Browser (once established), which will provide all the utility methods and more found in standard browsers (but: no rendering or anything related to presentation). The scripting library will (in the long-run) be focused on providing the methods and constructs to include interfaces / implementations from external libraries, which can be added or removed at will.

Enable instance creator factory

The right object needs to be created for the resulting DOM objects. Here we should use a very fast factory. How is the specific binding decided?

Documentation

For the version v1 of this project (or partially when AngleSharp.Core reaches v1) some documentation is required.

The outline for the scripting project is (roughly):

  • Introduction
  • Additions / scripting engines (e.g., JS engine)
  • Available extension methods and tooling
  • (Sample) use-cases w. (simple) examples
  • Core interfaces
  • Services and extensibility

Construct correct prototype chain

Originally issue FlorianRappl/AngleSharp#44 (5):

DomNodeInstance does not have a prototype nor set as extensible nor declares its own class name. This results in some weird Jint exceptions.

Replace Div with attribute, insert Razor section

Hi, this is great!! 💯 I am trying your scripting using the sample where I need to replace many items for print depending on the machine etc

can you please share a sample on can we find div with attributes? and replace the tags with a section - while keeping the same text or html - content on the inside.

find this <div class=print> <div class=machine >print stuff only </div></div> insert this with same old content -> @section print { <div class=@machine > print stuff only </div> }

  1. query and replace DIV's containing Class="Print Media"
  2. and then replace with Razor section like @section print {}

thanks

Still active?

Is this project still alive? I see there hasn't been much activity in a while.

Exception when loading site with JavaScript

Whne loading site http://www.eco2energie.biz/ I got this exception:

   à AngleSharp.Scripting.JavaScript.DomFunctionInstance.Call(JsValue thisObject, JsValue[] arguments) dans c:\Users\lemoussel\AngleSharp\AngleSharp.Scripting\AngleSharp.Scripting.JavaScript\DomFunctionInstance.cs:ligne 38
   à Jint.Runtime.ExpressionInterpreter.EvaluateCallExpression(CallExpression callExpression)
   à Jint.Engine.EvaluateExpression(Expression expression)
   à Jint.Runtime.ExpressionInterpreter.EvaluateExpression(Expression expression)
   à Jint.Runtime.ExpressionInterpreter.EvaluateAssignmentExpression(AssignmentExpression assignmentExpression)
   à Jint.Engine.EvaluateExpression(Expression expression)
   à Jint.Runtime.StatementInterpreter.ExecuteExpressionStatement(ExpressionStatement expressionStatement)
   à Jint.Engine.ExecuteStatement(Statement statement)
   à Jint.Runtime.StatementInterpreter.ExecuteStatement(Statement statement)
   à Jint.Runtime.StatementInterpreter.ExecuteStatementList(IEnumerable`1 statementList)
            IConfiguration config = new Configuration().WithDefaultLoader().WithCss().WithCookies().WithJavaScript();
            IBrowsingContext context = BrowsingContext.New(config);
            IDocument document = await context.OpenAsync("http://www.eco2energie.biz/");
            await Task.WhenAll(document.Requests);

Allow extensibility of scripting engine

Originally issue FlorianRappl/AngleSharp#44 (1):

The Navigator property of the AnalysisWindow can't be set as there is no setter. This forced me to specifically implement IWindow.Navigator on top of AnalysisWindow just to put some value there.

Execute <script> tags added from javascript

I'm trying to render some html page that contains the following script :

<script>
    var d = document, s = d.createElement('script');
    s.src = 'dynamicload.js';
    (d.head || d.body).appendChild(s);
</script>

The resulting html is ok :
... <head><script src="dynamicload.js"></script></head> ...
But dynamicload.js does not seem to be loaded.

When I load directly the html <script src="dynamicload.js"></script>, everything works fine.

Am I missing something ?

QuerySelectorAll gives empty list

Page I want to scrape: https://www.olx.com.pk/items

My code:

var config = AngleSharp.Configuration.Default.WithDefaultLoader();
          var document = await BrowsingContext.New(config).OpenAsync(pageLink);

          var titleSelector = ".fhlkh";
          var titlecells = document.QuerySelectorAll(titleSelector); //no results, empty list
          var titles = titlecells.Select(m => m.GetAttribute("href"));

The QuerySelectorAll() gives empty list
Note: The page to be scraped don't have jquery included.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.