yui / yui3 Goto Github PK
View Code? Open in Web Editor NEWA library for building richly interactive web applications.
Home Page: http://yuilibrary.com/
License: Other
A library for building richly interactive web applications.
Home Page: http://yuilibrary.com/
License: Other
duplicated
App's showView()
method can take a view name or an existing view instance. A problem arises with ad-hoc attributes in the following scenario:
var view = new Y.View();
Y.log(view.template); // => ""
app.showView(view, {template: 'bla bla'}, {update: true}, function (view) {
Y.log(view.template); // => ""
Y.log(view.get('template')); // => "bla bla"
});
When passing an existing view instance with the update
option set, the showView()
method will call setAttrs()
on the view instance with anything in the config
argument. This means that a template
attribute is created.
Compare the above with calling showView()
using a named view:
app.showView('someView', {template: 'bla bla'}, function (view) {
Y.log(view.template); // => "bla bla"
Y.log(view.get('template')); // => undefined
});
The problem is that non-ad-hoc attributes specified in a view class' _NON_ATTRS_CFG
property only apply at construction time.
Some possible solutions:
_NON_ATTRS_CFG
when showView()
is updating an existing view.showView()
's update
option, and let people who are managing their own view life cycles, also manage updating their view's properties and attributes.I don't see a great solution above to address this. I'm open to hear other ones and/or which of the above you like best.
As per my thread in the forums, I would have 2 endpoints for loading my assets:
/assets/js //for javascript files
/assets/css //for css files
This means I have these 2 endpoints to manage all sorts of javascript and css assets in the app (not just combo loading for yui).
In addition, the endpoints above supports combo loading:
/assets/js?some-js/some-js-min.js&some-js2/some-js2-min.js`
/assets/css?some-css/some-css-min.css&some-css2/some-css2-min.css`
I have been trying to find ways on how to make all css requests point towards /assets/css
and javascript towards /assets/js
So far, I don't think this is possible, but if we can have access to more info in pattern's test function, I think it would be possible:
Currently, for patterns, the test
function only has access to the module name. The configFn
function has access to a whole bunch of info about the module, including the full script name etc. If we can get access to this info in test
, then we can check the extension of the full script name and act accordingly:
YUI.applyConfig({
comboBase: "/assets/js?",
combine: true,
groups:{
css:{
comboBase: "/assets/css?",
patterns:{
css:{
test: function(name, me) {
//do some testing here. Me would be the "me" passed to the configFn function
},
}
}
}
}
});
I also noticed that yui's core modules will never use any of the patterns. Is there anyway to force them to do so?
Finally, if the above is available, how should I define my modules?
YUI.applyConfig({
comboBase: "/assets/js?",
combine: true,
groups:{
css:{
comboBase: "/assets/css?",
patterns:{
css:{
test: function(name, me) {
//do some testing here. Me would be the "me" passed to the configFn function
},
}
}
}
},
"modules": {
"my-module": {
"requires": ["node", "loader"],
"path": "my-module/my-module-min.js"
},
}
});
In the above, will the loader first use the patterns to determine the comboBase and then use the module definitions below (but not inside any groups) to determine the dependencies and path?
So we can run code that relies on the view being rendered, just after it's been rendered.
If you have a ModelList-instance where comparator is defined, then new or removed Models will get in the right place.
However, if you change a Model's attribute, then sort() is not triggered.
It should be, because the Model-instance might be repositioned.
Regards,
Marco.
Reproduce procedure:
I have a Y.Datatable
associate with a Y.Model
, and the model have an name
attribute.
Every time i called modifyRow()
, the model's name
attribute would be overridden by the model's name. I think it's because "name" is both an attribute and property.
Of course if I rename the name
attribute, it works, but that make me feel uneasy.
Finally i found it's because of this line:
model.setAttrs.apply(model, args);
https://github.com/yui/yui3/blob/master/src/datatable/js/mutable.js#L380
Why did you guys use apply
, how about model.setAttrs(args)
directly.
Take a look at this: http://pivotal.github.com/jasmine/#section-Spies
Coming from JasmineJS background, the ability to spy on any object proven to be very useful. I would like to see this functionality in YUI Test as well.
P.S. I would love to swap out YUITest for JasmineJS in my Mojito app if I knew how. :)
https://github.com/yui/yui3/blob/master/src/base/js/BaseObservable.js#L144-159
The documentation for Y.Base
's destroy
event discusses how destruction can be prevented. If the event is prevented, the instance can never be destroyed. It's a valid use case to want to prevent destruction at certain moments, but this is misleading. I would assume that if destruction was prevented, it would still be able to occur sometime later. I'm not sure why anyone would want to prevent destruction from occurring ever.
https://github.com/yui/yui3/blob/master/src/base/js/BaseObservable.js#L61-77
The functionality of and documentation for Y.Base
's init
event is similar.
This issue is related to issue #505.
In HTC butterfly buildin browser, tested with yui 3.9.0, there is no callback when node.transition(cfg, callback);
When we tested with yui 3.6.0, callback works.
After we tracedown, we found in yui 3.6.0, Y.Transition listen on webkitTransitionEnd , in yui 3.9.0, Y.Transition listen on transitionend.
But, if we tested HTC butterfly chrome browser, everything works fine.
Here is a patch to fix this issue:
Add these 3 lines in transition.js @ end of file....
if (navigator.userAgent.match(/Butterfly/) && ! Y.UA.chrome) {
TRANSITION_END = 'webkitTransitionEnd';
}
Appearantly a very small error,
but it drove me nuts.... So please correct it:
http://yuilibrary.com/yui/docs/template/#inline-code-code-blocks
<li class="<% i % 2 ? 'odd' : 'even' %>">
should be:
<li class="<%= i % 2 ? 'odd' : 'even' %>">
Regards,
Marco.
Noticed that cssgrids has optional dependencies of:
These should be replaced with cssnormalize.
/cc @msweeney and @tilomitra
Here is a special case. When we create a scrollView like this:
var SC = new Y.ScrollView({axis: 'y', render: true});
And, sometimes the content size is same as scrollView size......then,
this cause javascript error in IE7 . we traced the code found scrollview-scrollbars try
to setStyle top to 'NaNpx' . Later a suggested patch will be attached.
Nowadays, YUI3 has lots of modules, and the same as our project. A problem is becoming more and more obvious: configuration of module dependencies is very annoying, some times missing some modules, sometimes overloading some modules, and the latter occurs frequently.
So, why not let machine do this complicated job?
Our team is now trying to automate dependency configuration. The simple idea is to build a API-module map, so that a new module dependency can be determined through parsing code and API calculation. But we find out that, some YUI modules don't expose APIs, instead, they just mix some properties to prototype, like node-event-delegate. In such situation, manual intervention is necessary.
Maybe there are other better ways to automate dependency configuration, any idea is appreciated.
Do YUI team has any plan to automate dependency configuration? Can you help us make the API-module map more accurate?
http://yuilibrary.com/yui/docs/api/files/transition_js_transition-native.js.html
In HTC butterfly, the default browser, the transition end event is determined as 'transitionend', but actually it is 'webkitTransitionEnd'. So all the callback of the transition fails in that machine.
YUI global object name is hard coded. Can we make it configurable?
Would like to be able to say
MyNameSpace.use(...) vs. YUI.use(...)
Thoughts?
At present the only place where SimpleYUI is documented is on the blog post introducing it in 3.2.0: http://www.yuiblog.com/blog/2010/09/03/coming-inyui-3-2-0-simpleyui/
It doesn't appear anywhere in the API docs, or the User Guides.
Tabview source code links a private _classNames variable in its method implementations and properties initializations.
This practice doesn't allow class extensions to overwrite those values in the proper way. In order to get fixed, it needs to read the fresh values from the static reference instead.
var list = new Y.LazyModelList();
var items = [{country: 'Netherlands'}];
list.add(items);
var firstObject = list.item(0);
var firstModel = list.revive(firstObject);
firstModel.set('country', 'USA');
firstObject.country // <-- is still 'Netherlands'
firstModel.get('country') // <-- is 'USA'
Regards,
Marco.
Related to #547
Widgets should have an eventlistener on the boundingBox, that when the widget's boundingBox is destroyed (on-destroy, not after), that the widgets destructor is being called.
This way, whenever a parentNode is removed with parentNode.destroy(true), that the widget is cleaned up properly.
Regards,
Marco.
Node.load()
Node.setHTML()
Node.remove()
Node.removeChild()
Node.replace()
Node.replaceChild()
should all get the posibility to do a destroy and recursive destroy.
At the moment it seems that from all Node's replace-methods, these are the posibilities:
load --> no destroy no recursive destroy
setHTML -> no destroy, no recursive destroy
remove -> with destroy, no recursive destroy
removeChild -> no destroy, no recursive destroy
replace -> no destroy, no recursive destroy
replaceChild -> no destroy, no recursive destroy
empty -> always destroy, always recursive destroy
I think, this should go along with the automatic destruction of widgets within the 'destroy'-method (#547 (comment))
Marco.
Hi,
Do you plan to integrate a chunk upload functionality? That should be really nice for big files.
Thank you
I have a YUI config object that looks something like this:
{
base: '/static/yui/',
combine: true,
comboBase: '/combo?',
groups: {
mygroup: {
base: '/static/mystuff/',
combine: true,
comboBase: '/combo?',
filter: 'debug'
}
}
}
Both YUI and mygroup
are using the same combo URL but I want debug versions of my own files while leaving YUI minified. But the mygroup
filter is applied to the YUI files as well.
Button container node is always being inserted 'after' on:
this.setStdModContent(section, buttonContainer, 'after');
In some situations this can be inserted in any position desired by the class extending Y.WidgetButtons. Separate this piece of code into a protected method simplifies customization.
Adding text-rendering: optimizeLegibility
to HTML/BODY causes the last unit to drop in Chrome.
You can see the problem here: http://jsfiddle.net/MpsGU/
list = new Y.LazyModelList();
items = [{country: 'Netherlands'}];
list.add(items);
firstObject = list.item(0);
firstModel = list.revive(firstObject);
firstObject.clientId // <-- model_1
firstModel.get('clientId') // <-- model_2
Regards,
Marco.
I ran into a case where I need to use basic HTTP authentication when making web service requests from Node.js. I browsed through the IO user guide, examples, and API docs here
I couldn't find any information about basic HTTP authentication. A google search led me to http://yuilibrary.com/projects/yui3/ticket/2530023 where it says the functionality has been added, but another comment on that ticket says it does not work in Node.js.
I found this: https://github.com/yui/yui3/blob/master/src/io/js/io-base.js#L711
but I'm not quite certain what it's doing and don't have time at the moment to dig into it deeper.
I researched basic HTTP authentication here: http://en.wikipedia.org/wiki/Basic_access_authentication so my plan is to manually set an Authorization header.
Support for basic HTTP authentication in Y.io would be great to have. Documentation for basic HTTP authentication in Y.io would also be great to have.
According to this,
http://yuilibrary.com/yui/docs/yui/#instance-config
The configuration options supplied as an argument to YUI()
should "only apply to this specific instance of YUI." I'm finding that changing a group's properties in the YUI instance configuration also modifies the global config object:
>>> YUI.GlobalConfig = { groups: { grpName: { combine: false }}};
Object { groups={...}}
>>> YUI.GlobalConfig.groups.grpName.combine;
false
>>> YUI({ groups: { grpName: { combine: true }}});
Object { version= "3.7.3" , Env={...}, _yuid= "yui_3_7_3_2_1359658521445_1" , more...}
>>> YUI.GlobalConfig.groups.grpName.combine;
true
This causes subsequent invocations of YUI()
to pick up the instance-specific config property.
When you set up an event listener within a view there's inconsistency in what the "this" keyword refers to within the listener.
If you set up a click listener, "this" refers to the view, whereas if you set up a gesture listener (e.g. gesturemovestart), the this keyword refers to the DOM element that triggered the event.
There are ways to work around this, but if the gesture events are supposed to be the catch-all replacement for touch/mouse listeners, having consistent behavior would be nice.
I have a very simple config like this:
YUI.applyConfig({
"comboBase": "/assets/js?",
"root": "yui-3.9.0/",
"groups": {
"template": {
"root": "template/",
"modules": {
"some-module": {
"requires": ["node"],
"path": "some-module/some-module-min.js"
},
"some-module2": {
"requires": ["node"],
"path": "some-module2/some-module2-min.js"
},
}
}
}
});
The documentation states that combine
should be true
by default.
So, if I run this code (http://jsfiddle.net/KVBHW/):
YUI.Env.Sandbox = YUI().use('selector-css3', 'some-module', 'some-module2', function (Y) {
});
I would expect that my modules are combined. However, firebug shows otherwise:
In addition, instead of using my comboBase
, it tried to load those modules from yahoo's CDN. From my understanding of the docs, when we set a comboBase
, in the root of the config, all other groups should use it, unless they have overridden it.
However, if combine
is explicitly set to true
within a group it uses the correct combo base and combines the files (http://jsfiddle.net/GbpJu/):
YUI.applyConfig({
"comboBase": "/assets/js?",
"root": "yui-3.9.0/",
"groups": {
"template": {
"combine": true,
"root": "template/",
"modules": {
"some-module": {
"requires": ["node"],
"path": "some-module/some-module-min.js"
},
"some-module2": {
"requires": ["node"],
"path": "some-module2/some-module2-min.js"
},
}
}
}
});
It'd be sweet if Node#getHTML()
magically worked on document fragments. It's a simple workaround (create a throwaway <div>
, append fragment to div, return div.innerHTML
) that I often find myself implementing in my own code.
I keep meaning to send a pull request for this, so consider this issue a reminder to myself if nobody else gets to it first.
If you have a transition that has a specified end and start function, the end function is not fired in firefox if the transition value doesn't change. Here is some example code that demonstrates this issue. To see the error, click on 'transition' multiple times and the end function will not print to console in firefox. This is in version 3.8.0
YUI().use('node', 'anim', 'event','transition', function (Y) {
var moveNode = Y.one('img.image');
var endFunction = function(){
console.log('in start function');
}
var startFunction = function(){
console.log('in start function');
}
var transParamters = {
duration: 0.50,
easing: 'ease-out',
left: 0,
on: {
start: function() {
console.log('in start function');
},
end: function() {
console.log('in end function');
}
}
};
Y.one('a.btn1').on('click', function(e){
transParamters.left = '50%';
moveNode.transition(transParamters);
});
Y.one('a.btn2').on('click', function(e){
transParamters.left = '0%';
moveNode.transition(transParamters);
});
});
Tabview source code links a private _classNames variable in its method implementations and properties initializations.
This practice doesn't allow class extensions to overwrite those values in the proper way. In order to get fixed, it needs to read the fresh values from the static reference instead.
Native transitions do not appear to work correctly on Samsung Galaxy and similar devices. The problem appears to happen because the transition lib is using CSS properties without the '-webkit' prefix in some cases on these devices.
Y.Model
has a lovely feature for supporting aliases for its id
attribute, which enables the following:
Y.MyModel = Y.Base.create('myModel', Y.Model, [], {
idAttribute: 'uid'
});
var model = new Y.Model({uid: 1});
Y.log(model.get('uid')); // => 1
Y.log(model.get('id')); // => 1
var data = model.toJSON();
Y.log(data.id); // => undefined
Y.log(data.uid); // => 1
This allows other code working with models to always assume it can access the model's id via its id
attribute, even if the specific model subclass actually uses a different attribute for its "real" id. Y.Model
is also smart about data serialization; and if the model subclass defines an idAttribute
, Y.Model
will make sure that attribute value is represented while discarding the default id
attribute alias.
Simply put, Y.Model
's id
attribute alias feature is a hack, and breaks down in several ways:
ATTRS
configs.change
event.)Y.Attribute
methods.A better place to implement the attribute alias feature is in Y.Attribute
, it could even be a class extension if there would be a performance hit. This would alleviate Y.Model
from having to hack-in this feature, and open it up to other components which use attributes.
To optimize the event performance, Y.EventTarget
may also need to change to accommodate aliases; this is still TDB.
These are some code in src/yui.js:
var YUI = function() {
var Y = this;
// set up the core environment
Y._init();
Y._setup();
};
var proto, prop,
instances = {};
proto = {
applyConfig: ,
_init: function() {
var Y = this;
instances[Y.id] = Y;
},
_setup: ,
add: ,
use:
// other methods
};
YUI.prototype = proto;
for(prop in proto) {
if(proto.hasOwnProperty(prop)) {
YUI[prop] = proto[prop];
}
}
// set up the environment
YUI._init();
It means YUI itself was treated as an Y sandbox too, so you should can do this:
YUI.use('datatable', function(Y) {
// Y.DataTable available and ready for use
});
But now YUI.use isn't work correctly.
I was looking to use the Sortable plugin for a project. I went to the docs to see the details and I found that none of the examples were working. I checked Firefox, Chrome and they seemed to have the same problem the basic drag functionality was broken and I was only able to select text. IE10 worked fine surprisingly.
Demo:
http://jsfiddle.net/2ejQ6/
Also all the drag demos are broken in Chrome and Firefox.
PS I'm on Windows 8 if that is a factor.
Use this example :
YUI({
debug: true,
combine: false,
filter: "raw"
}).use('app', function (Y) {
var app = new Y.App();
app.route('/*', 'fooBar', function(req, res, next) {
});
app.render().dispatch();
});
You will have this error : Uncaught TypeError: Cannot call method 'call' of undefined
The problem is come from router.js#L652
There is not check on the function availability.
I know the problem is coming from the user. But, user could spend many time to see his mistake.
PS : I'm really new on YUI, that why I'm not making a PR.
The YUI: User Agent test fails on IE6.
in IE 10/Windows 8 App test: not win8 app: Value should be false. Expected: false (boolean) Actual: true (boolean)
Here's a simple repo ( http://jsfiddle.net/tPFTX/ ):
YUI.applyConfig({
"combine": true,
// "comboBase": "/combo?", //Use Yahoo's CDN
"modules": {
"some-module": {
"requires": ["node"],
"path": "some-module/some-module.js"
},
}
});
YUI().use('selector-css3', 'node', 'json', 'anim', 'transition', 'widget', 'button', function (Y) {
YUI.add('button2', function(Y) {
}, '1.0.0', { requires: ['node','base','widget','selector-css3', 'button']});
YUI.add('button3', function(Y) {
}, '1.0.0', { requires: ['node','base','widget','selector-css3', 'button']});
YUI.add('button4', function(Y) {
}, '1.0.0', { requires: ['node','base','widget','selector-css3', 'button']});
Y.use('button2', 'button3');
Y.use('button4');
});
If I run this, notice that the css for widget-base
and cssbutton
is downloaded once.
However, if I now set my own comboBase
: http://jsfiddle.net/JYdPB/
We see that the css for widget-base
and cssbutton
is downloaded multiple times:
The setStyle() method is now separated out into the node-style module, while hide() is still in node-base. Unfortunately node-base does not pull in node-style automatically, so hide() is busted.
node-base either needs to pull in node-style, or hide() (and friends) need to be moved out of node-base.
(former title: 'Destroying a Node should also destroy Widgets associated with that Node')
I think this is extremely important.
Especially when you do a recursive destroy where a childnode might be a widget.
Of coarse, you can say it's the resposibility of the programmer to hande and destroy widgets themself, but there are cases where you are not aware if or what widget are defined inside a node and you still need to destroy the node.
(former codesuggestion, not relevant anymore):
destroy: function(recursive) {
var UID = Y.config.doc.uniqueID ? 'uniqueID' : '_yuid',
instance, widgetInstance;
this.purge(); // TODO: only remove events add via this Node
if (this.unplug) { // may not be a PluginHost
this.unplug();
}
this.clearData();
if (this.hasClass('.yui3-widget') && Y.Widget) {
widgetInstance = YWidget.getByNode(this);
if (widgetInstance) {
widgetInstance.destroy(true);
}
}
if (recursive) {
Y.NodeList.each(this.all('*'), function(node) {
instance = Y_Node._instances[node[UID]];
if (instance) {
instance.destroy();
} else { // purge in case added by other means
Y.Event.purgeElement(node);
}
});
}
this._node = null;
this._stateProxy = null;
delete Y_Node._instances[this._yuid];
},
Regards,
Marco
This is an enhancement request and a defect report.
I've demonstrated the behavior here: http://jsbin.com/ihumah/1/edit
A fireOnce
event only has one opportunity to either complete or not complete. If it gets prevented, it can't get fired later. I suppose this makes sense; it can literally be .fire
d once. I would like to be able to create an event very similar to a fireOnce
event, but if it gets prevented, it can continue to be fired again until it completes.
After a fireOnce
event gets prevented, new subscribers to .on
and .after
get executed immediately. This seems very broken. This might be a copy of http://yuilibrary.com/projects/yui3/ticket/2530477
I noticed that the default combo loader settings results in something like:
http://yui.yahooapis.com/combo?3.8.1/build/oop/oop-min.js&3.8.1/build/dom-core/dom-core-min.js&3.8.1/build/dom-base/dom-base-min.js&3.8.1/build/selector-native/selector-native-min.js&3.8.1/build/selector/selector-min.js&3.8.1/build/selector-css2/selector-css2-min.js&3.8.1/build/selector-css3/selector-css3-min.js
However, on yuilibrary.com, the following is used:
http://yui.yahooapis.com/combo?3.8.1/oop/oop-min.js&3.8.1/attribute-core/attribute-core-min.js&3.8.1/event-custom-base/event-custom-base-min.js&3.8.1/event-custom-complex/event-custom-complex-min.js&3.8.1/attribute-observable/attribute-observable-min.js&3.8.1/attribute-extras/attribute-extras-min.js&3.8.1/attribute-base/attribute-base-min.js&3.8.1/attribute-complex/attribute-complex-min.js&3.8.1/base-core/base-core-min.js&3.8.1/base-observable/base-observable-min.js
On yuilibrary.com, the root 3.8.1
is used instead of 3.8.1/build
. In addition, 3.8.1/build
and 3.8.1
serves the exact same result.
I think the build
is extraneous and can be safely removed in future builds to save some characters so we can perhaps load a few more extra scripts in that request.
Further more, since there is only 1 script per folder, say attribute-core-min.js
and its other variants, -min
, -debug
will only exist in the folder attribute-core
, it might be more efficient if we had:
http://yui.yahooapis.com/combo?3.8.1/attribute-core-min.js&....
The server can then work out what folder to find the js
file by inspecting the name of the script. That means we have even fewer requests to get the same amount of scripts.
A lot of good stuff has happened to Handlebars in the latest RC release, it's time to update our wrapped version.
The biggest issue is their lack of a changelog which makes it really difficult to figure out what needs to change :( See: handlebars-lang/handlebars.js#327
https://gist.github.com/jamessanders/0e28e2fda0b87e685c13#file-example-html
In the gist above I create a swipe area using the YUI scrollview and the scrollview-paginator modules. If you visit the demo on an iPhone and swipe between the pages you will occasionally see that the page transition does not happen (making it appear that the swipe had no effect) even though the "indexChange" event was still fired. I have see this happen on iPhone, Android and Firefox.
Currently, DT is set up to rerender the entire table if anything changes. Obviously, this needs to be changed to modify only those elements that need to be changed.
However, as a stop gap measure, and potentially in other places as well, DT should call destroy()
on the table Nodes recursively to purge the Nodes._instances
collection and any orphaned event subscribers from the cells that were replaced.
I would recommend scheduling this work in a setTimeout
rather than inline the work because it would definitely impact performance.
Also, when the work is done to avoid full table render on every change, you might look at doing the work using new Y.Node()
rather than Y.one()
to avoid populating Node._instances
with nodes that were only used transactionally.
When Node.remove(true) is called, all its descendent nodes should be destroyed at the same time. I read the source code and find that only destroy() is called, not destroy(true) , why?
input.simulate('blur') does not fire a simulated event on input elements in IE10
In the following jsbin I have written workaround for anyone who runs into this issue in the meantime:
Hi!
There has been a regression in the ResizeProxy Plugin. Currently (from 3.7.0 up until now), elements aren't resized while the mouse is on top of them, which didn't happen before.
You can verify this with this basic example. Simply try to drag the element by dragging the resize handles to the middle of the element, and check the difference between the two yui versions.
<html>
<head>
<script src="http://yui.yahooapis.com/3.7.0/build/yui/yui-min.js"></script>
<!--<script src="http://yui.yahooapis.com/3.6.0/build/yui/yui-min.js"></script>-->
<style type="text/css">
#demo {
height: 100px;
width: 100px;
border: 1px solid black;
background-color: #8DD5E7;
position: relative;
padding: 1em;
margin: 2em;
}
</style>
</head>
<body>
<div id="demo">Resize Me</div>
<script type="text/javascript">
YUI().use('resize', 'resize-proxy', function(Y) {
var resize = new Y.Resize({
node: '#demo',
handles: 'r,br,b'
});
resize.plug(Y.Plugin.ResizeProxy);
});
</script>
</body>
</html>
It seems to be caused by 36a51b7
Thanks!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.