Mass rename of "widget" to "component" in files

This commit is contained in:
Patrick Steele-Idem 2017-02-20 16:30:16 -07:00
parent 377ab30e79
commit ad00eb2aeb
351 changed files with 2660 additions and 2660 deletions

View File

@ -103,7 +103,7 @@ Every issue should be assigned one of these.
![](https://img.shields.io/badge/scope-compiler-cc0077.svg)
![](https://img.shields.io/badge/scope-runtime-eebb00.svg)
![](https://img.shields.io/badge/scope-core%20taglib-00cccc.svg)
![](https://img.shields.io/badge/scope-widgets-9900aa.svg)
![](https://img.shields.io/badge/scope-components-9900aa.svg)
![](https://img.shields.io/badge/scope-tools-fef2c0.svg)
What part of the Marko stack does this issue apply to? In most cases there should only be one of these.
@ -112,7 +112,7 @@ What part of the Marko stack does this issue apply to? In most cases there shoul
- **compiler**: Relates to the compiler (server only)
- **runtime**: Relates to the runtime (isomorphic/universal)
- **core-taglib**: Relates to custom tags that ship with Marko
- **widgets**: Relates to `marko-widgets`
- **components**: Relates to `marko-components`
- **tools**: Relates to editor plugins, commandline tools, etc.
### Difficulty

View File

@ -124,7 +124,7 @@ require('marko/node-require').install({
### 3.7.4
- Fixed [#339](https://github.com/marko-js/marko/issues/339) - Tag transformers are not being applied to tags with a dynamic tag name (fixes [#146](https://github.com/marko-js/marko-widgets/issues/146) for Marko Widgets)
- Fixed [#339](https://github.com/marko-js/marko/issues/339) - Tag transformers are not being applied to tags with a dynamic tag name (fixes [#146](https://github.com/marko-js/marko-components/issues/146) for Marko Components)
### 3.7.3

View File

@ -179,22 +179,22 @@ template.stream(templateData).pipe(process.stdout);
# UI Components
Marko Widgets is a minimalist library for building isomorphic/universal UI components with the help of the
[Marko templating engine](http://markojs.com/docs/). Marko renders the HTML for UI components, while Marko Widgets adds client-side behavior. Client-side behavior includes the following:
Marko Components is a minimalist library for building isomorphic/universal UI components with the help of the
[Marko templating engine](http://markojs.com/docs/). Marko renders the HTML for UI components, while Marko Components adds client-side behavior. Client-side behavior includes the following:
- Handling DOM events
- Emitting custom events
- Handling custom events emitted by other widgets
- Handling custom events emitted by other components
- Manipulating and updating the DOM
Marko Widgets offers advanced features like DOM-diffing, batched updates, stateful widgets, declarative event binding and efficient event delegation.
Marko Components offers advanced features like DOM-diffing, batched updates, stateful components, declarative event binding and efficient event delegation.
Changing a widgets state or properties will result in the DOM automatically being updated without writing extra code. Marko Widgets has adopted many of the good design principles promoted by the [React](https://facebook.github.io/react/index.html) team, but aims to be much lighter and often faster (especially on the server). When updating the view for a widget, Marko Widgets uses DOM diffing to make the minimum number of changes to the DOM through the use of the [morphdom](https://github.com/patrick-steele-idem/morphdom) module.
Changing a components state or properties will result in the DOM automatically being updated without writing extra code. Marko Components has adopted many of the good design principles promoted by the [React](https://facebook.github.io/react/index.html) team, but aims to be much lighter and often faster (especially on the server). When updating the view for a component, Marko Components uses DOM diffing to make the minimum number of changes to the DOM through the use of the [morphdom](https://github.com/patrick-steele-idem/morphdom) module.
UI components are defined using very clean JavaScript code. For example:
```javascript
module.exports = require('marko-widgets').defineComponent({
module.exports = require('marko-components').defineComponent({
/**
* The template to use as the view
*/
@ -213,7 +213,7 @@ module.exports = require('marko-widgets').defineComponent({
/**
* Return an object that is used as the template data. The
* template data should be based on the current widget state
* template data should be based on the current component state
* that is passed in as the first argument
*/
getTemplateData: function(state) {
@ -228,13 +228,13 @@ module.exports = require('marko-widgets').defineComponent({
},
/**
* This is the constructor for the widget. Called once when
* the widget is first added to the DOM.
* This is the constructor for the component. Called once when
* the component is first added to the DOM.
*/
init: function() {
var el = this.el;
// "el" will be reference the raw HTML element that this
// widget is bound to. You can do whatever you want with it...
// component is bound to. You can do whatever you want with it...
// el.style.color = 'red';
},
@ -272,9 +272,9 @@ And, here is the corresponding Marko template for the UI component:
</div>
```
<a href="http://markojs.com/marko-widgets/try-online/" target="_blank">Try Marko Widgets Online!</a>
<a href="http://markojs.com/marko-components/try-online/" target="_blank">Try Marko Components Online!</a>
For more details on Marko Widgets, please check out the [Marko Widgets Documentation](http://markojs.com/docs/marko-widgets/).
For more details on Marko Components, please check out the [Marko Components Documentation](http://markojs.com/docs/marko-components/).
# Common issues

View File

@ -51,13 +51,13 @@ You can easily `require`/`import` a single file component and interact with it u
```js
var myCounter = require('./src/components/my-counter');
var widget = myCounter.renderSync({
var component = myCounter.renderSync({
value: 10
})
.appendTo(document.body)
.getWidget();
.getComponent();
widget.increment();
component.increment();
```
Of course, a single file component can also be embedded in another template as a custom tag:
@ -131,17 +131,17 @@ The VDOM output allows optimizations that were previously not possible:
Our initial benchmarks show a significant improvement in rendering time and we are consistently outperforming React. The independent [morphdom](https://github.com/patrick-steele-idem/morphdom) library has been tweaked to support diffing with both a real DOM and a Marko virtual DOM.
### Merge in Marko Widgets ([#390](https://github.com/marko-js/marko/issues/390))
### Merge in Marko Components ([#390](https://github.com/marko-js/marko/issues/390))
A big part of this release is a shift in focus from Marko being merely a templating language to a complete UI library. As such, we are providing first-class support for components.
You will no longer need to install `marko-widgets` as an external library, and there is more cohesion between the templates and components/widgets.
You will no longer need to install `marko-components` as an external library, and there is more cohesion between the templates and components/components.
### Improved component lifecycle methods ([#396](https://github.com/marko-js/marko/issues/396))
- `getInitialState()``onInput(input)`
- `getWidgetConfig()` ➔ `onInput(input)`
- `getComponentConfig()` ➔ `onInput(input)`
- `init(config)``onMount()`
- `getTemplateData(input, state)` ➔ (no longer needed)
- `getInitialProps(input)` ➔ (no longer needed)
@ -167,7 +167,7 @@ class {
}
onRender(out) {
// Called for every render. This widget
// Called for every render. This component
// may or may not be mounted.
// During render we have access to the `out`.
console.log('The template is about to be rendered!');
@ -204,7 +204,7 @@ class {
}
```
### Automatically watch widget state object for changes ([#406](https://github.com/marko-js/marko/issues/406))
### Automatically watch component state object for changes ([#406](https://github.com/marko-js/marko/issues/406))
**Old:**
@ -675,7 +675,7 @@ or, with the non-concise syntax:
**New:**
```html
<div widget="./widget.js">
<div component="./component.js">
...
</div>
```
@ -683,13 +683,13 @@ or, with the non-concise syntax:
Or, applied as a tag (see next: multiple top level DOM elements):
```html
<script widget="./widget.js"/>
<script component="./component.js"/>
<div>
...
</div>
```
Or, since `widget.js` is automatically recognized
Or, since `component.js` is automatically recognized
```html
<div>
@ -697,11 +697,11 @@ Or, since `widget.js` is automatically recognized
</div>
```
### Deprecate `widget-types` ([#514](https://github.com/marko-js/marko/issues/514))
### Deprecate `component-types` ([#514](https://github.com/marko-js/marko/issues/514))
**Old:**
```html
<widget-types default="./widget" mobile="./widget-mobile"/>
<component-types default="./component" mobile="./component-mobile"/>
<div w-bind=(data.isMobile ? 'default' : 'mobile')>
...
@ -775,7 +775,7 @@ or
**New:**
**Automatic widget initialization!**
**Automatic component initialization!**
### Deprecate `w-body` and replace with `include` ([#418](https://github.com/marko-js/marko/issues/418))
@ -854,7 +854,7 @@ Or, with an argument value:
</div>
```
### Deprecate `w-extend` and allow multiple widgets to be bound to the same HTML element ([#392](https://github.com/marko-js/marko/issues/392))
### Deprecate `w-extend` and allow multiple components to be bound to the same HTML element ([#392](https://github.com/marko-js/marko/issues/392))
> `w-extend` is now deprecated
@ -874,7 +874,7 @@ or
<some-component onEvent('handleEvent')/>
```
NOTE: The outer most widget is what is returned when calling `getWidget()`/`getWidgetForEl()`.
NOTE: The outer most component is what is returned when calling `getComponent()`/`getComponentForEl()`.
<a name="breaking-changes"></a>
@ -894,9 +894,9 @@ template.render(data); // returns `out`
template.render(data, (err, html, out) => {});
template.renderSync(data); // returns a String representing the HTML output
widget.render(data); // returns a `RenderResult`
widget.render(data, (err, renderResult) => {});
widget.renderSync(data); // throws an error, not a method.
component.render(data); // returns a `RenderResult`
component.render(data, (err, renderResult) => {});
component.renderSync(data); // throws an error, not a method.
```
**New:**
@ -909,12 +909,12 @@ template.render(data); // returns `out`
template.render(data, (err, out) => {});
template.renderSync(data); // returns `out`
widget.render(data); // returns `out`
widget.render(data, (err, out) => {});
widget.renderSync(data); // returns `out`
component.render(data); // returns `out`
component.render(data, (err, out) => {});
component.renderSync(data); // returns `out`
```
Also, `out` has been updated to implement DOM manipulation methods like `appendTo` that were previously only available from the `RenderResult` returned from widget renders.
Also, `out` has been updated to implement DOM manipulation methods like `appendTo` that were previously only available from the `RenderResult` returned from component renders.
NOTE: We will implement `out.toString()` and `out.toJSON()` so in many cases the `out` can be used as a string.

View File

@ -1,7 +1,7 @@
{
"dependencies": [
"../taglibs/compiler.browser.json",
"../widgets/compiler.browser.json",
"../components/compiler.browser.json",
"../runtime/compiler.browser.json"
]
}

View File

@ -239,7 +239,7 @@ registerTaglib(require('../taglibs/html/marko.json'), require.resolve('../taglib
registerTaglib(require('../taglibs/svg/marko.json'), require.resolve('../taglibs/svg/marko.json'));
registerTaglib(require('../taglibs/async/marko.json'), require.resolve('../taglibs/async/marko.json'));
registerTaglib(require('../taglibs/cache/marko.json'), require.resolve('../taglibs/cache/marko.json'));
registerTaglib(require('../widgets/taglib/marko.json'), require.resolve('../widgets/taglib/marko.json'));
registerTaglib(require('../components/taglib/marko.json'), require.resolve('../components/taglib/marko.json'));
exports.registerTaglib = function(filePath) {
ok(typeof filePath === 'string', '"filePath" shouldbe a string');

View File

@ -3,13 +3,13 @@
var domInsert = require('../runtime/dom-insert');
var marko = require('../');
var widgetsUtil = require('./util');
var getWidgetForEl = widgetsUtil.$__getWidgetForEl;
var widgetLookup = widgetsUtil.$__widgetLookup;
var emitLifecycleEvent = widgetsUtil.$__emitLifecycleEvent;
var destroyWidgetForEl = widgetsUtil.$__destroyWidgetForEl;
var destroyElRecursive = widgetsUtil.$__destroyElRecursive;
var getElementById = widgetsUtil.$__getElementById;
var componentsUtil = require('./util');
var getComponentForEl = componentsUtil.$__getComponentForEl;
var componentLookup = componentsUtil.$__componentLookup;
var emitLifecycleEvent = componentsUtil.$__emitLifecycleEvent;
var destroyComponentForEl = componentsUtil.$__destroyComponentForEl;
var destroyElRecursive = componentsUtil.$__destroyElRecursive;
var getElementById = componentsUtil.$__getElementById;
var EventEmitter = require('events-light');
var RenderResult = require('../runtime/RenderResult');
var SubscriptionTracker = require('listener-tracker');
@ -35,34 +35,34 @@ function removeListener(removeEventListenerHandle) {
removeEventListenerHandle();
}
function hasCompatibleWidget(widgetsContext, existingWidget) {
var id = existingWidget.id;
var newWidgetDef = widgetsContext.$__widgetsById[id];
return newWidgetDef && existingWidget.$__type == newWidgetDef.$__widget.$__type;
function hasCompatibleComponent(componentsContext, existingComponent) {
var id = existingComponent.id;
var newComponentDef = componentsContext.$__componentsById[id];
return newComponentDef && existingComponent.$__type == newComponentDef.$__component.$__type;
}
function handleCustomEventWithMethodListener(widget, targetMethodName, args, extraArgs) {
function handleCustomEventWithMethodListener(component, targetMethodName, args, extraArgs) {
// Remove the "eventType" argument
args.push(widget);
args.push(component);
if (extraArgs) {
args = extraArgs.concat(args);
}
var targetWidget = widgetLookup[widget.$__scope];
var targetMethod = targetWidget[targetMethodName];
var targetComponent = componentLookup[component.$__scope];
var targetMethod = targetComponent[targetMethodName];
if (!targetMethod) {
throw Error('Method not found: ' + targetMethodName);
}
targetMethod.apply(targetWidget, args);
targetMethod.apply(targetComponent, args);
}
function getElIdHelper(widget, widgetElId, index) {
var id = widget.id;
function getElIdHelper(component, componentElId, index) {
var id = component.id;
var elId = widgetElId != null ? id + '-' + widgetElId : id;
var elId = componentElId != null ? id + '-' + componentElId : id;
if (index != null) {
elId += '[' + index + ']';
@ -78,7 +78,7 @@ function getElIdHelper(widget, widgetElId, index) {
* looping over and invoking the custom update handlers.
* @return {boolean} Returns true if if the DOM was updated. False, otherwise.
*/
function processUpdateHandlers(widget, stateChanges, oldState) {
function processUpdateHandlers(component, stateChanges, oldState) {
var handlerMethod;
var handlers;
@ -86,7 +86,7 @@ function processUpdateHandlers(widget, stateChanges, oldState) {
if (stateChanges.hasOwnProperty(propName)) {
var handlerMethodName = 'update_' + propName;
handlerMethod = widget[handlerMethodName];
handlerMethod = component[handlerMethodName];
if (handlerMethod) {
(handlers || (handlers=[])).push([propName, handlerMethod]);
} else {
@ -111,18 +111,18 @@ function processUpdateHandlers(widget, stateChanges, oldState) {
var newValue = stateChanges[propertyName];
var oldValue = oldState[propertyName];
handlerMethod.call(widget, newValue, oldValue);
handlerMethod.call(component, newValue, oldValue);
}
emitLifecycleEvent(widget, 'update');
emitLifecycleEvent(component, 'update');
widget.$__reset();
component.$__reset();
}
return true;
}
function checkInputChanged(existingWidget, oldInput, newInput) {
function checkInputChanged(existingComponent, oldInput, newInput) {
if (oldInput != newInput) {
if (oldInput == null || newInput == null) {
return true;
@ -148,7 +148,7 @@ function checkInputChanged(existingWidget, oldInput, newInput) {
function handleNodeDiscarded(node) {
if (node.nodeType == 1) {
destroyWidgetForEl(node);
destroyComponentForEl(node);
}
}
@ -156,14 +156,14 @@ function handleBeforeNodeDiscarded(node) {
return eventDelegation.$__handleNodeDetach(node);
}
var widgetProto;
var componentProto;
/**
* Base widget type.
* Base component type.
*
* NOTE: Any methods that are prefixed with an underscore should be considered private!
*/
function Widget(id, doc) {
function Component(id, doc) {
EventEmitter.call(this);
this.id = id;
this.el =
@ -186,8 +186,8 @@ function Widget(id, doc) {
this.$__document = doc;
}
Widget.prototype = widgetProto = {
$__isWidget: true,
Component.prototype = componentProto = {
$__isComponent: true,
subscribeTo: function(target) {
if (!target) {
@ -196,7 +196,7 @@ Widget.prototype = widgetProto = {
var subscriptions = this.$__subscriptions || (this.$__subscriptions = new SubscriptionTracker());
var subscribeToOptions = target.$__isWidget ?
var subscribeToOptions = target.$__isComponent ?
WIDGET_SUBSCRIBE_TO_OPTIONS :
NON_WIDGET_SUBSCRIBE_TO_OPTIONS;
@ -219,14 +219,14 @@ Widget.prototype = widgetProto = {
return emit.apply(this, arguments);
}
},
getElId: function (widgetElId, index) {
return getElIdHelper(this, widgetElId, index);
getElId: function (componentElId, index) {
return getElIdHelper(this, componentElId, index);
},
getEl: function (widgetElId, index) {
getEl: function (componentElId, index) {
var doc = this.$__document;
if (widgetElId != null) {
return getElementById(doc, getElIdHelper(this, widgetElId, index));
if (componentElId != null) {
return getElementById(doc, getElIdHelper(this, componentElId, index));
} else {
return this.el || getElementById(doc, getElIdHelper(this));
}
@ -241,18 +241,18 @@ Widget.prototype = widgetProto = {
}
return els;
},
getWidget: function(id, index) {
return widgetLookup[getElIdHelper(this, id, index)];
getComponent: function(id, index) {
return componentLookup[getElIdHelper(this, id, index)];
},
getWidgets: function(id) {
var widgets = [];
getComponents: function(id) {
var components = [];
var i = 0;
var widget;
while((widget = widgetLookup[getElIdHelper(this, id, i)])) {
widgets.push(widget);
var component;
while((component = componentLookup[getElIdHelper(this, id, i)])) {
components.push(component);
i++;
}
return widgets;
return components;
},
destroy: function() {
if (this.$__destroyed) {
@ -265,10 +265,10 @@ Widget.prototype = widgetProto = {
this.$__destroyShallow();
var rootWidgets = this.$__rootWidgets;
if (rootWidgets) {
for (i=0, len=rootWidgets.length; i<len; i++) {
rootWidgets[i].destroy();
var rootComponents = this.$__rootComponents;
if (rootComponents) {
for (i=0, len=rootComponents.length; i<len; i++) {
rootComponents[i].destroy();
}
}
@ -302,7 +302,7 @@ Widget.prototype = widgetProto = {
this.$__subscriptions = null;
}
delete widgetLookup[this.id];
delete componentLookup[this.id];
},
isDestroyed: function() {
@ -407,7 +407,7 @@ Widget.prototype = widgetProto = {
$__queueUpdate: function() {
if (!this.$__updateQueued) {
updateManager.$__queueWidgetUpdate(this);
updateManager.$__queueComponentUpdate(this);
}
},
@ -492,27 +492,27 @@ Widget.prototype = widgetProto = {
var result = new RenderResult(out);
var targetNode = out.$__getOutput();
var widgetsContext = out.global.widgets;
var componentsContext = out.global.components;
function onBeforeElUpdated(fromEl, toEl) {
var id = fromEl.id;
var existingWidget;
var existingComponent;
if (widgetsContext && id) {
var preserved = widgetsContext.$__preserved[id];
if (componentsContext && id) {
var preserved = componentsContext.$__preserved[id];
if (preserved && !preserved.$__bodyOnly) {
// Don't morph elements that are associated with widgets that are being
// reused or elements that are being preserved. For widgets being reused,
// the morphing will take place when the reused widget updates.
// Don't morph elements that are associated with components that are being
// reused or elements that are being preserved. For components being reused,
// the morphing will take place when the reused component updates.
return MORPHDOM_SKIP;
} else {
existingWidget = getWidgetForEl(fromEl);
if (existingWidget && !hasCompatibleWidget(widgetsContext, existingWidget)) {
// We found a widget in an old DOM node that does not have
// a compatible widget that was rendered so we need to
// destroy the old widget
existingWidget.$__destroyShallow();
existingComponent = getComponentForEl(fromEl);
if (existingComponent && !hasCompatibleComponent(componentsContext, existingComponent)) {
// We found a component in an old DOM node that does not have
// a compatible component that was rendered so we need to
// destroy the old component
existingComponent.$__destroyShallow();
}
}
}
@ -520,8 +520,8 @@ Widget.prototype = widgetProto = {
function onBeforeElChildrenUpdated(el) {
var id = el.id;
if (widgetsContext && id) {
var preserved = widgetsContext.$__preserved[id];
if (componentsContext && id) {
var preserved = componentsContext.$__preserved[id];
if (preserved && preserved.$__bodyOnly) {
// Don't morph the children since they are preserved
return MORPHDOM_SKIP;
@ -559,25 +559,25 @@ Widget.prototype = widgetProto = {
result.afterInsert(doc);
out.emit('$__widgetsInitialized');
out.emit('$__componentsInitialized');
});
},
$__getRootEls: function(rootEls) {
var i, len;
var widgetEls = this.els;
var componentEls = this.els;
for (i=0, len=widgetEls.length; i<len; i++) {
var widgetEl = widgetEls[i];
rootEls[widgetEl.id] = widgetEl;
for (i=0, len=componentEls.length; i<len; i++) {
var componentEl = componentEls[i];
rootEls[componentEl.id] = componentEl;
}
var rootWidgets = this.$__rootWidgets;
if (rootWidgets) {
for (i=0, len=rootWidgets.length; i<len; i++) {
var rootWidget = rootWidgets[i];
rootWidget.$__getRootEls(rootEls);
var rootComponents = this.$__rootComponents;
if (rootComponents) {
for (i=0, len=rootComponents.length; i<len; i++) {
var rootComponent = rootComponents[i];
rootComponent.$__getRootEls(rootEls);
}
}
@ -598,9 +598,9 @@ Widget.prototype = widgetProto = {
}
};
widgetProto.elId = widgetProto.getElId;
componentProto.elId = componentProto.getElId;
// Add all of the following DOM methods to Widget.prototype:
// Add all of the following DOM methods to Component.prototype:
// - appendTo(referenceEl)
// - replace(referenceEl)
// - replaceChildrenOf(referenceEl)
@ -608,12 +608,12 @@ widgetProto.elId = widgetProto.getElId;
// - insertAfter(referenceEl)
// - prependTo(referenceEl)
domInsert(
widgetProto,
function getEl(widget) {
componentProto,
function getEl(component) {
var els = this.els;
var elCount = els.length;
if (elCount > 1) {
var fragment = widget.$__document.createDocumentFragment();
var fragment = component.$__document.createDocumentFragment();
for (var i=0; i<elCount; i++) {
fragment.appendChild(els[i]);
}
@ -622,10 +622,10 @@ domInsert(
return els[0];
}
},
function afterInsert(widget) {
return widget;
function afterInsert(component) {
return component;
});
inherit(Widget, EventEmitter);
inherit(Component, EventEmitter);
module.exports = Widget;
module.exports = Component;

View File

@ -1,31 +1,31 @@
'use strict';
var nextRepeatedId = require('./nextRepeatedId');
var repeatedRegExp = /\[\]$/;
var widgetUtil = require('./util');
var nextWidgetId = widgetUtil.$__nextWidgetId;
var attachBubblingEvent = widgetUtil.$__attachBubblingEvent;
var componentUtil = require('./util');
var nextComponentId = componentUtil.$__nextComponentId;
var attachBubblingEvent = componentUtil.$__attachBubblingEvent;
var extend = require('raptor-util/extend');
var registry = require('./registry');
/**
* A WidgetDef is used to hold the metadata collected at runtime for
* a single widget and this information is used to instantiate the widget
* A ComponentDef is used to hold the metadata collected at runtime for
* a single component and this information is used to instantiate the component
* later (after the rendered HTML has been added to the DOM)
*/
function WidgetDef(widget, widgetId, out, widgetStack, widgetStackLen) {
this.$__out = out; // The AsyncWriter that this widget is associated with
this.$__widgetStack = widgetStack;
this.$__widgetStackLen = widgetStackLen;
this.$__widget = widget;
this.id = widgetId;
function ComponentDef(component, componentId, out, componentStack, componentStackLen) {
this.$__out = out; // The AsyncWriter that this component is associated with
this.$__componentStack = componentStack;
this.$__componentStackLen = componentStackLen;
this.$__component = component;
this.id = componentId;
this.$__scope = // The ID of the widget that this widget is scoped within
this.$__scope = // The ID of the component that this component is scoped within
this.$__customEvents = // An array containing information about custom events
this.$__roots = // IDs of root elements if there are multiple root elements
this.$__children = // An array of nested WidgetDef instances
this.$__children = // An array of nested ComponentDef instances
this.$__domEvents = // An array of DOM events that need to be added (in sets of three)
this.$__bubblingDomEvents = // Used to keep track of bubbling DOM events for widgets rendered on the server
this.$__bubblingDomEvents = // Used to keep track of bubbling DOM events for components rendered on the server
undefined;
this.$__isExisting = false;
@ -33,28 +33,28 @@ function WidgetDef(widget, widgetId, out, widgetStack, widgetStackLen) {
this.$__nextIdIndex = 0; // The unique integer to use for the next scoped ID
}
WidgetDef.prototype = {
ComponentDef.prototype = {
$__end: function() {
this.$__widgetStack.length = this.$__widgetStackLen;
this.$__componentStack.length = this.$__componentStackLen;
},
/**
* Register a nested widget for this widget. We maintain a tree of widgets
* so that we can instantiate nested widgets before their parents.
* Register a nested component for this component. We maintain a tree of components
* so that we can instantiate nested components before their parents.
*/
$__addChild: function (widgetDef) {
$__addChild: function (componentDef) {
var children = this.$__children;
if (children) {
children.push(widgetDef);
children.push(componentDef);
} else {
this.$__children = [widgetDef];
this.$__children = [componentDef];
}
},
/**
* This helper method generates a unique and fully qualified DOM element ID
* that is unique within the scope of the current widget. This method prefixes
* the the nestedId with the ID of the current widget. If nestedId ends
* that is unique within the scope of the current component. This method prefixes
* the the nestedId with the ID of the current component. If nestedId ends
* with `[]` then it is treated as a repeated ID and we will generate
* an ID with the current index for the current nestedId.
* (e.g. "myParentId-foo[0]", "myParentId-foo[1]", etc.)
@ -72,10 +72,10 @@ WidgetDef.prototype = {
},
/**
* Registers a DOM event for a nested HTML element associated with the
* widget. This is only done for non-bubbling events that require
* component. This is only done for non-bubbling events that require
* direct event listeners to be added.
* @param {String} type The DOM event type ("mouseover", "mousemove", etc.)
* @param {String} targetMethod The name of the method to invoke on the scoped widget
* @param {String} targetMethod The name of the method to invoke on the scoped component
* @param {String} elId The DOM element ID of the DOM element that the event listener needs to be added too
*/
e: function(type, targetMethod, elId, extraArgs) {
@ -93,12 +93,12 @@ WidgetDef.prototype = {
extraArgs]);
},
/**
* Returns the next auto generated unique ID for a nested DOM element or nested DOM widget
* Returns the next auto generated unique ID for a nested DOM element or nested DOM component
*/
$__nextId: function() {
return this.id ?
this.id + '-w' + (this.$__nextIdIndex++) :
nextWidgetId(this.$__out);
nextComponentId(this.$__out);
},
d: function(handlerMethodName, extraArgs) {
@ -106,25 +106,25 @@ WidgetDef.prototype = {
}
};
WidgetDef.$__deserialize = function(o, types) {
ComponentDef.$__deserialize = function(o, types) {
var id = o[0];
var typeName = types[o[1]];
var input = o[2];
var extra = o[3];
var state = extra.s;
var widgetProps = extra.w;
var componentProps = extra.w;
var widget = typeName /* legacy */ && registry.$__createWidget(typeName, id);
var component = typeName /* legacy */ && registry.$__createComponent(typeName, id);
if (extra.b) {
widget.$__bubblingDomEvents = extra.b;
component.$__bubblingDomEvents = extra.b;
}
// Preview newly created widget from being queued for update since we area
// Preview newly created component from being queued for update since we area
// just building it from the server info
widget.$__updateQueued = true;
component.$__updateQueued = true;
if (state) {
var undefinedPropNames = extra.u;
@ -135,17 +135,17 @@ WidgetDef.$__deserialize = function(o, types) {
}
// We go through the setter here so that we convert the state object
// to an instance of `State`
widget.state = state;
component.state = state;
}
widget.$__input = input;
component.$__input = input;
if (widgetProps) {
extend(widget, widgetProps);
if (componentProps) {
extend(component, componentProps);
}
return {
$__widget: widget,
$__component: component,
$__roots: extra.r,
$__scope: extra.p,
$__domEvents: extra.d,
@ -153,4 +153,4 @@ WidgetDef.$__deserialize = function(o, types) {
};
};
module.exports = WidgetDef;
module.exports = ComponentDef;

View File

@ -1,57 +1,57 @@
'use strict';
var WidgetDef = require('./WidgetDef');
var initWidgets = require('./init-widgets');
var ComponentDef = require('./ComponentDef');
var initComponents = require('./init-components');
var EMPTY_OBJECT = {};
function WidgetsContext(out, root) {
function ComponentsContext(out, root) {
if (!root) {
root = new WidgetDef(null, null, out);
root = new ComponentDef(null, null, out);
}
this.$__out = out;
this.$__widgetStack = [root];
this.$__componentStack = [root];
this.$__preserved = EMPTY_OBJECT;
this.$__widgetsById = {};
this.$__componentsById = {};
}
WidgetsContext.prototype = {
get $__widgets() {
return this.$__widgetStack[0].$__children;
ComponentsContext.prototype = {
get $__components() {
return this.$__componentStack[0].$__children;
},
$__beginWidget: function(widget) {
$__beginComponent: function(component) {
var self = this;
var widgetStack = self.$__widgetStack;
var origLength = widgetStack.length;
var parent = widgetStack[origLength - 1];
var componentStack = self.$__componentStack;
var origLength = componentStack.length;
var parent = componentStack[origLength - 1];
var widgetId = widget.id;
var componentId = component.id;
if (!widgetId) {
widgetId = widget.id = parent.$__nextId();
if (!componentId) {
componentId = component.id = parent.$__nextId();
}
var widgetDef = new WidgetDef(widget, widgetId, this.$__out, widgetStack, origLength);
this.$__widgetsById[widgetId] = widgetDef;
parent.$__addChild(widgetDef);
widgetStack.push(widgetDef);
var componentDef = new ComponentDef(component, componentId, this.$__out, componentStack, origLength);
this.$__componentsById[componentId] = componentDef;
parent.$__addChild(componentDef);
componentStack.push(componentDef);
return widgetDef;
return componentDef;
},
$__clearWidgets: function () {
this.$__widgetStack = [new WidgetDef(null /* id */, this.$__out)];
$__clearComponents: function () {
this.$__componentStack = [new ComponentDef(null /* id */, this.$__out)];
},
$__initWidgets: function (doc) {
var widgetDefs = this.$__widgets;
if (widgetDefs) {
initWidgets.$__initClientRendered(widgetDefs, doc);
this.$__clearWidgets();
$__initComponents: function (doc) {
var componentDefs = this.$__components;
if (componentDefs) {
initComponents.$__initClientRendered(componentDefs, doc);
this.$__clearComponents();
}
},
$__nextWidgetId: function() {
var widgetStack = this.$__widgetStack;
var parent = widgetStack[widgetStack.length - 1];
$__nextComponentId: function() {
var componentStack = this.$__componentStack;
var parent = componentStack[componentStack.length - 1];
return parent.$__nextId();
},
$__preserveDOMNode: function(elId, bodyOnly) {
@ -63,12 +63,12 @@ WidgetsContext.prototype = {
}
};
WidgetsContext.$__getWidgetsContext = function (out) {
ComponentsContext.$__getComponentsContext = function (out) {
var global = out.global;
return out.data.widgets ||
global.widgets ||
(global.widgets = new WidgetsContext(out));
return out.data.components ||
global.components ||
(global.components = new ComponentsContext(out));
};
module.exports = WidgetsContext;
module.exports = ComponentsContext;

View File

@ -14,8 +14,8 @@ function ensure(state, propertyName) {
}
}
function State(widget, initialState) {
this.$__widget = widget;
function State(component, initialState) {
this.$__component = component;
this.$__raw = initialState || {};
this.$__dirty = false;
@ -73,14 +73,14 @@ State.prototype = {
}
if (!this.$__dirty) {
// This is the first time we are modifying the widget state
// This is the first time we are modifying the component state
// so introduce some properties to do some tracking of
// changes to the state
this.$__dirty = true; // Mark the widget state as dirty (i.e. modified)
this.$__dirty = true; // Mark the component state as dirty (i.e. modified)
this.$__old = rawState;
this.$__raw = rawState = extend({}, rawState);
this.$__changes = {};
this.$__widget.$__queueUpdate();
this.$__component.$__queueUpdate();
}
this.$__changes[name] = value;
@ -89,7 +89,7 @@ State.prototype = {
// Don't store state properties with an undefined or null value
delete rawState[name];
} else {
// Otherwise, store the new value in the widget state
// Otherwise, store the new value in the component state
rawState[name] = value;
}
},

View File

@ -2,9 +2,9 @@ var eventDelegation = require('./event-delegation');
var delegateEvent = eventDelegation.$__delegateEvent;
var getEventAttribute = eventDelegation.$__getEventAttribute;
var widgetsUtil = require('./util');
var destroyElRecursive = widgetsUtil.$__destroyElRecursive;
var destroyWidgetForEl = widgetsUtil.$__destroyWidgetForEl;
var componentsUtil = require('./util');
var destroyElRecursive = componentsUtil.$__destroyElRecursive;
var destroyComponentForEl = componentsUtil.$__destroyComponentForEl;
function handleNodeAttach(node, out) {
if (node.nodeType === 1) {
@ -15,7 +15,7 @@ function handleNodeAttach(node, out) {
var attachTargets = data.$__attachTargets;
if (!attachTargets) {
attachTargets = data.$__attachTargets = [];
out.on('$__widgetsInitialized', function() {
out.on('$__componentsInitialized', function() {
for (var i=0; i<attachTargets.length; i+=2) {
var node = attachTargets[i];
var target = attachTargets[i+1];
@ -39,7 +39,7 @@ function handleNodeDetach(node) {
delegateEvent(node, target, {
preventDefault: function() {
allowDetach = false;
destroyWidgetForEl(node);
destroyComponentForEl(node);
destroyElRecursive(node);
},
detach: function() {

View File

@ -1 +1 @@
require('./init-widgets').$__initServerRendered();
require('./init-components').$__initServerRendered();

View File

@ -4,13 +4,13 @@
"type": "require",
"path": "./boot",
"run": true,
"if": "!flags.contains('marko/widgets/no-boot')"
"if": "!flags.contains('marko/components/no-boot')"
}
],
"requireRemap": [
{
"from": "./loadWidget.js",
"to": "./loadWidget-dynamic.js"
"from": "./loadComponent.js",
"to": "./loadComponent-dynamic.js"
}
]
}

View File

@ -2,23 +2,23 @@
/* jshint newcap:false */
var BaseState;
var BaseWidget;
var BaseComponent;
var inherit;
module.exports = function defineWidget(def, renderer) {
if (def.$__isWidget) {
module.exports = function defineComponent(def, renderer) {
if (def.$__isComponent) {
return def;
}
var WidgetClass;
var ComponentClass;
var proto;
if (typeof def === 'function') {
WidgetClass = def;
proto = WidgetClass.prototype;
ComponentClass = def;
proto = ComponentClass.prototype;
} else if (typeof def === 'object') {
WidgetClass = function() {};
proto = WidgetClass.prototype = def;
ComponentClass = function() {};
proto = ComponentClass.prototype = def;
} else {
throw TypeError();
}
@ -26,38 +26,38 @@ module.exports = function defineWidget(def, renderer) {
// We don't use the constructor provided by the user
// since we don't invoke their constructor until
// we have had a chance to do our own initialization.
// Instead, we store their constructor in the "initWidget"
// Instead, we store their constructor in the "initComponent"
// property and that method gets called later inside
// init-widgets-browser.js
function Widget(id, doc) {
BaseWidget.call(this, id, doc);
// init-components-browser.js
function Component(id, doc) {
BaseComponent.call(this, id, doc);
}
if (!proto.$__isWidget) {
// Inherit from Widget if they didn't already
inherit(WidgetClass, BaseWidget);
if (!proto.$__isComponent) {
// Inherit from Component if they didn't already
inherit(ComponentClass, BaseComponent);
}
// The same prototype will be used by our constructor after
// we he have set up the prototype chain using the inherit function
proto = Widget.prototype = WidgetClass.prototype;
proto = Component.prototype = ComponentClass.prototype;
proto.onCreate = proto.onCreate || WidgetClass;
proto.onCreate = proto.onCreate || ComponentClass;
proto.constructor = def.constructor = Widget;
proto.constructor = def.constructor = Component;
// Set a flag on the constructor function to make it clear this is
// a widget so that we can short-circuit this work later
Widget.$__isWidget = true;
// a component so that we can short-circuit this work later
Component.$__isComponent = true;
function State() { BaseState.apply(this, arguments); }
inherit(State, BaseState);
proto.$__State = State;
proto.renderer = renderer;
return Widget;
return Component;
};
BaseState = require('./State');
BaseWidget = require('./Widget');
BaseComponent = require('./Component');
inherit = require('raptor-util/inherit');

View File

@ -1,4 +1,4 @@
var widgetLookup = require('./util').$__widgetLookup;
var componentLookup = require('./util').$__componentLookup;
var isArray = Array.isArray;
var listenersAttached;
@ -11,7 +11,7 @@ function getEventAttribute(el, attrName) {
} else {
var attrValue = el.getAttribute(attrName);
if (attrValue) {
// <method_name> <widget_id>[ <extra_args_index]
// <method_name> <component_id>[ <extra_args_index]
var parts = attrValue.split(' ');
if (parts.length == 3) {
parts[2] = parseInt(parts[2], 10);
@ -24,35 +24,35 @@ function getEventAttribute(el, attrName) {
function delegateEvent(node, target, event) {
var targetMethod = target[0];
var targetWidgetId = target[1];
var targetComponentId = target[1];
var extraArgs = target[2];
var targetWidget = widgetLookup[targetWidgetId];
var targetComponent = componentLookup[targetComponentId];
if (!targetWidget) {
if (!targetComponent) {
return;
}
var targetFunc = targetWidget[targetMethod];
var targetFunc = targetComponent[targetMethod];
if (!targetFunc) {
throw Error('Method not found: ' + targetMethod);
}
if (extraArgs != null) {
if (typeof extraArgs === 'number') {
extraArgs = targetWidget.$__bubblingDomEvents[extraArgs];
extraArgs = targetComponent.$__bubblingDomEvents[extraArgs];
if (!isArray(extraArgs)) {
extraArgs = [extraArgs];
}
}
}
// Invoke the widget method
// Invoke the component method
if (extraArgs) {
targetFunc.apply(targetWidget, extraArgs.concat(event, node));
targetFunc.apply(targetComponent, extraArgs.concat(event, node));
} else {
targetFunc.call(targetWidget, event, node);
targetFunc.call(targetComponent, event, node);
}
}
@ -64,7 +64,7 @@ function attachBubbleEventListeners(doc) {
// document.body element. When we get notified of a triggered event,
// we again walk up the tree starting at the target associated
// with the event to find any mappings for event. Each mapping
// is from a DOM event type to a method of a widget.
// is from a DOM event type to a method of a component.
require('./bubble').forEach(function addBubbleHandler(eventType) {
body.addEventListener(eventType, function(event) {
var propagationStopped = false;
@ -83,12 +83,12 @@ function attachBubbleEventListeners(doc) {
}
// Search up the tree looking DOM events mapped to target
// widget methods
// component methods
var attrName = 'data-_on' + eventType;
var target;
// Attributes will have the following form:
// on<event_type>("<target_method>|<widget_id>")
// on<event_type>("<target_method>|<component_id>")
do {
if ((target = getEventAttribute(curNode, attrName))) {

View File

@ -1,18 +1,18 @@
var events = require('../runtime/events');
var Widget = require('./Widget');
var widgetsUtil = require('./util');
var Component = require('./Component');
var componentsUtil = require('./util');
function onInitWidget(listener) {
events.on('initWidget', listener);
function onInitComponent(listener) {
events.on('initComponent', listener);
}
exports.onInitWidget = onInitWidget;
exports.Widget = Widget;
exports.getWidgetForEl = widgetsUtil.$__getWidgetForEl;
exports.initWidgets = require('./init-widgets').$__initServerRendered;
exports.onInitComponent = onInitComponent;
exports.Component = Component;
exports.getComponentForEl = componentsUtil.$__getComponentForEl;
exports.initComponents = require('./init-components').$__initServerRendered;
exports.w = require('./defineWidget'); // Referenced by compiled templates
exports.c = require('./defineComponent'); // Referenced by compiled templates
exports.r = require('./renderer'); // Referenced by compiled templates
exports.rw = require('./registry').$__register; // Referenced by compiled templates
exports.rc = require('./registry').$__register; // Referenced by compiled templates
window.$__MARKO_WIDGETS = exports; // Helpful when debugging... WARNING: DO NOT USE IN REAL CODE!
window.$__MARKO_COMPONENTS = exports; // Helpful when debugging... WARNING: DO NOT USE IN REAL CODE!

View File

@ -1,26 +1,26 @@
/**
* Module to manage the lifecycle of widgets
* Module to manage the lifecycle of components
*
*/
'use strict';
var warp10 = require('warp10');
var WidgetsContext = require('./WidgetsContext');
var ComponentsContext = require('./ComponentsContext');
var escapeEndingScriptTagRegExp = /<\//g;
function flattenHelper(widgets, flattened, typesArray, typesLookup) {
for (var i = 0, len = widgets.length; i < len; i++) {
var widgetDef = widgets[i];
var customEvents = widgetDef.$__customEvents;
var id = widgetDef.id;
var widget = widgetDef.$__widget;
var state = widget.state;
var input = widget.input;
var typeName = widget.typeName;
function flattenHelper(components, flattened, typesArray, typesLookup) {
for (var i = 0, len = components.length; i < len; i++) {
var componentDef = components[i];
var customEvents = componentDef.$__customEvents;
var id = componentDef.id;
var component = componentDef.$__component;
var state = component.state;
var input = component.input;
var typeName = component.typeName;
widget.state = undefined; // We don't use `delete` to avoid V8 deoptimization
widget.input = undefined; // We don't use `delete` to avoid V8 deoptimization
widget.typeName = undefined;
widget.id = undefined;
component.state = undefined; // We don't use `delete` to avoid V8 deoptimization
component.input = undefined; // We don't use `delete` to avoid V8 deoptimization
component.typeName = undefined;
component.id = undefined;
if (!typeName) {
continue;
@ -33,7 +33,7 @@ function flattenHelper(widgets, flattened, typesArray, typesLookup) {
typesLookup[typeName] = typeIndex;
}
var children = widgetDef.$__children;
var children = componentDef.$__children;
if (children) {
// Depth-first search (children should be initialized before parent)
@ -43,8 +43,8 @@ function flattenHelper(widgets, flattened, typesArray, typesLookup) {
var hasProps = false;
for (var key in widget) {
if (widget.hasOwnProperty(key) && widget[key] !== undefined) {
for (var key in component) {
if (component.hasOwnProperty(key) && component[key] !== undefined) {
hasProps = true;
}
}
@ -67,13 +67,13 @@ function flattenHelper(widgets, flattened, typesArray, typesLookup) {
}
var extra = {
p: customEvents && widgetDef.$__scope, // Only serialize scope if we need to attach custom events
d: widgetDef.$__domEvents,
b: widgetDef.$__bubblingDomEvents,
e: widgetDef.$__customEvents,
w: hasProps ? widget : undefined,
p: customEvents && componentDef.$__scope, // Only serialize scope if we need to attach custom events
d: componentDef.$__domEvents,
b: componentDef.$__bubblingDomEvents,
e: componentDef.$__customEvents,
w: hasProps ? component : undefined,
s: state,
r: widgetDef.$__roots,
r: componentDef.$__roots,
u: undefinedPropNames
};
@ -86,9 +86,9 @@ function flattenHelper(widgets, flattened, typesArray, typesLookup) {
}
}
function getRenderedWidgets(widgetsContext) {
var widgets = widgetsContext.$__widgets;
if (!widgets || !widgets.length) {
function getRenderedComponents(componentsContext) {
var components = componentsContext.$__components;
if (!components || !components.length) {
return;
}
@ -96,14 +96,14 @@ function getRenderedWidgets(widgetsContext) {
var typesLookup = {};
var typesArray = [];
flattenHelper(widgets, flattened, typesArray, typesLookup);
flattenHelper(components, flattened, typesArray, typesLookup);
return {w: flattened, t: typesArray};
}
function writeInitWidgetsCode(widgetsContext, out) {
var renderedWidgets = getRenderedWidgets(widgetsContext);
if (!renderedWidgets) {
function writeInitComponentsCode(componentsContext, out) {
var renderedComponents = getRenderedComponents(componentsContext);
if (!renderedComponents) {
return;
}
@ -111,42 +111,42 @@ function writeInitWidgetsCode(widgetsContext, out) {
var nonceAttr = cspNonce ? ' nonce='+JSON.stringify(cspNonce) : '';
out.write('<script' + nonceAttr + '>' +
'(function(){var w=window;w.$widgets=(w.$widgets||[]).concat(' +
warp10.stringify(renderedWidgets).replace(escapeEndingScriptTagRegExp, '\\u003C/') +
')||w.$widgets})()</script>');
'(function(){var w=window;w.$components=(w.$components||[]).concat(' +
warp10.stringify(renderedComponents).replace(escapeEndingScriptTagRegExp, '\\u003C/') +
')||w.$components})()</script>');
widgetsContext.$__clearWidgets();
componentsContext.$__clearComponents();
}
exports.writeInitWidgetsCode = writeInitWidgetsCode;
exports.writeInitComponentsCode = writeInitComponentsCode;
/**
* Returns an object that can be sent to the browser using JSON.stringify. The parsed object should be
* passed to require('marko-widgets').initWidgets(...);
* passed to require('marko-components').initComponents(...);
*
* @param {WidgetsContext|AsyncWriter} widgetsContext A WidgetsContext or an AsyncWriter
* @return {Object} An object with information about the rendered widgets that can be serialized to JSON. The object should be treated as opaque
* @param {ComponentsContext|AsyncWriter} componentsContext A ComponentsContext or an AsyncWriter
* @return {Object} An object with information about the rendered components that can be serialized to JSON. The object should be treated as opaque
*/
exports.getRenderedWidgets = function(widgetsContext) {
if (!(widgetsContext instanceof WidgetsContext)) {
// Assume that the provided "widgetsContext" argument is
exports.getRenderedComponents = function(componentsContext) {
if (!(componentsContext instanceof ComponentsContext)) {
// Assume that the provided "componentsContext" argument is
// actually an AsyncWriter
var out = widgetsContext;
var out = componentsContext;
if (!out.global) {
throw new Error('Invalid argument: ' + widgetsContext);
throw new Error('Invalid argument: ' + componentsContext);
}
widgetsContext = WidgetsContext.$__getWidgetsContext(out);
componentsContext = ComponentsContext.$__getComponentsContext(out);
}
var renderedWidgets = getRenderedWidgets(widgetsContext);
return warp10.stringifyPrepare(renderedWidgets);
var renderedComponents = getRenderedComponents(componentsContext);
return warp10.stringifyPrepare(renderedComponents);
};
exports.r = require('./renderer');
exports.w = function() { /* no op for defining a widget on teh server */ };
exports.c = function() { /* no op for defining a component on teh server */ };
// registerWidget is a no-op on the server.
// Fixes https://github.com/marko-js/marko-widgets/issues/111
exports.rw = function(typeName) { return typeName; };
// registerComponent is a no-op on the server.
// Fixes https://github.com/marko-js/marko-components/issues/111
exports.rc = function(typeName) { return typeName; };

View File

@ -4,20 +4,20 @@ var eventDelegation = require('./event-delegation');
var win = window;
var defaultDocument = document;
var events = require('../runtime/events');
var widgetsUtil = require('./util');
var widgetLookup = widgetsUtil.$__widgetLookup;
var getElementById = widgetsUtil.$__getElementById;
var WidgetDef = require('./WidgetDef');
var componentsUtil = require('./util');
var componentLookup = componentsUtil.$__componentLookup;
var getElementById = componentsUtil.$__getElementById;
var ComponentDef = require('./ComponentDef');
// var extend = require('raptor-util/extend');
// var registry = require('./registry');
function invokeWidgetEventHandler(widget, targetMethodName, args) {
var method = widget[targetMethodName];
function invokeComponentEventHandler(component, targetMethodName, args) {
var method = component[targetMethodName];
if (!method) {
throw Error('Method not found: ' + targetMethodName);
}
method.apply(widget, args);
method.apply(component, args);
}
function addEventListenerHelper(el, eventType, listener) {
@ -27,79 +27,79 @@ function addEventListenerHelper(el, eventType, listener) {
};
}
function addDOMEventListeners(widget, el, eventType, targetMethodName, extraArgs, handles) {
function addDOMEventListeners(component, el, eventType, targetMethodName, extraArgs, handles) {
var removeListener = addEventListenerHelper(el, eventType, function(event) {
var args = [event, el];
if (extraArgs) {
args = extraArgs.concat(args);
}
invokeWidgetEventHandler(widget, targetMethodName, args);
invokeComponentEventHandler(component, targetMethodName, args);
});
handles.push(removeListener);
}
function initWidget(widgetDef, doc) {
var widget = widgetDef.$__widget;
function initComponent(componentDef, doc) {
var component = componentDef.$__component;
if (!widget || !widget.$__isWidget) {
if (!component || !component.$__isComponent) {
return; // legacy
}
var scope = widgetDef.$__scope;
var domEvents = widgetDef.$__domEvents;
var customEvents = widgetDef.$__customEvents;
var scope = componentDef.$__scope;
var domEvents = componentDef.$__domEvents;
var customEvents = componentDef.$__customEvents;
widget.$__reset();
widget.$__document = doc;
component.$__reset();
component.$__document = doc;
var isExisting = widgetDef.$__isExisting;
var isExisting = componentDef.$__isExisting;
var i;
var len;
var eventType;
var targetMethodName;
var extraArgs;
var id = widget.id;
var id = component.id;
var rootIds = widgetDef.$__roots;
var rootIds = componentDef.$__roots;
if (rootIds) {
var rootWidgets;
var rootComponents;
var els = [];
for (i=0, len=rootIds.length; i<len; i++) {
var rootId = rootIds[i];
var nestedId = id + '-' + rootId;
var rootWidget = widgetLookup[nestedId];
if (rootWidget) {
rootWidget.$__rootFor = widget;
if (rootWidgets) {
rootWidgets.push(rootWidget);
var rootComponent = componentLookup[nestedId];
if (rootComponent) {
rootComponent.$__rootFor = component;
if (rootComponents) {
rootComponents.push(rootComponent);
} else {
rootWidgets = widget.$__rootWidgets = [rootWidget];
rootComponents = component.$__rootComponents = [rootComponent];
}
} else {
var rootEl = getElementById(doc, nestedId);
if (rootEl) {
rootEl._w = widget;
rootEl._w = component;
els.push(rootEl);
}
}
}
widget.el = els[0];
widget.els = els;
widgetLookup[id] = widget;
component.el = els[0];
component.els = els;
componentLookup[id] = component;
} else if (!isExisting) {
var el = getElementById(doc, id);
el._w = widget;
widget.el = el;
widget.els = [el];
widgetLookup[id] = widget;
el._w = component;
component.el = el;
component.els = [el];
componentLookup[id] = component;
}
if (isExisting) {
widget.$__removeDOMEventListeners();
component.$__removeDOMEventListeners();
}
if (domEvents) {
@ -112,98 +112,98 @@ function initWidget(widgetDef, doc) {
extraArgs = domEvents[i+3];
// The event mapping is for a DOM event (not a custom event)
addDOMEventListeners(widget, eventEl, eventType, targetMethodName, extraArgs, eventListenerHandles);
addDOMEventListeners(component, eventEl, eventType, targetMethodName, extraArgs, eventListenerHandles);
}
if (eventListenerHandles.length) {
widget.$__domEventListenerHandles = eventListenerHandles;
component.$__domEventListenerHandles = eventListenerHandles;
}
}
if (customEvents) {
widget.$__customEvents = {};
widget.$__scope = scope;
component.$__customEvents = {};
component.$__scope = scope;
for (i=0, len=customEvents.length; i<len; i+=3) {
eventType = customEvents[i];
targetMethodName = customEvents[i+1];
extraArgs = customEvents[i+2];
widget.$__customEvents[eventType] = [targetMethodName, extraArgs];
component.$__customEvents[eventType] = [targetMethodName, extraArgs];
}
}
if (isExisting) {
widget.$__emitLifecycleEvent('update');
component.$__emitLifecycleEvent('update');
} else {
events.emit('mountWidget', widget);
widget.$__emitLifecycleEvent('mount');
events.emit('mountComponent', component);
component.$__emitLifecycleEvent('mount');
}
}
/**
* This method is used to initialized widgets associated with UI components
* rendered in the browser. While rendering UI components a "widgets context"
* is added to the rendering context to keep up with which widgets are rendered.
* When ready, the widgets can then be initialized by walking the widget tree
* in the widgets context (nested widgets are initialized before ancestor widgets).
* @param {Array<marko-widgets/lib/WidgetDef>} widgetDefs An array of WidgetDef instances
* This method is used to initialized components associated with UI components
* rendered in the browser. While rendering UI components a "components context"
* is added to the rendering context to keep up with which components are rendered.
* When ready, the components can then be initialized by walking the component tree
* in the components context (nested components are initialized before ancestor components).
* @param {Array<marko-components/lib/ComponentDef>} componentDefs An array of ComponentDef instances
*/
function initClientRendered(widgetDefs, doc) {
function initClientRendered(componentDefs, doc) {
// Ensure that event handlers to handle delegating events are
// always attached before initializing any widgets
// always attached before initializing any components
eventDelegation.$__init(doc);
doc = doc || defaultDocument;
for (var i=0,len=widgetDefs.length; i<len; i++) {
var widgetDef = widgetDefs[i];
for (var i=0,len=componentDefs.length; i<len; i++) {
var componentDef = componentDefs[i];
if (widgetDef.$__children) {
initClientRendered(widgetDef.$__children, doc);
if (componentDef.$__children) {
initClientRendered(componentDef.$__children, doc);
}
initWidget(
widgetDef,
initComponent(
componentDef,
doc);
}
}
/**
* This method initializes all widgets that were rendered on the server by iterating over all
* of the widget IDs.
* This method initializes all components that were rendered on the server by iterating over all
* of the component IDs.
*/
function initServerRendered(renderedWidgets, doc) {
function initServerRendered(renderedComponents, doc) {
var i=0, len;
if (!arguments.length) {
renderedWidgets = win.$widgets;
renderedComponents = win.$components;
win.$widgets = {
win.$components = {
concat: initServerRendered
};
if (renderedWidgets && (len=renderedWidgets.length)) {
if (renderedComponents && (len=renderedComponents.length)) {
for (; i<len; i++) {
initServerRendered(renderedWidgets[i], doc);
initServerRendered(renderedComponents[i], doc);
}
}
return;
}
// Ensure that event handlers to handle delegating events are
// always attached before initializing any widgets
// always attached before initializing any components
eventDelegation.$__init(doc || defaultDocument);
renderedWidgets = warp10Finalize(renderedWidgets);
renderedComponents = warp10Finalize(renderedComponents);
var widgetDefs = renderedWidgets.w;
var typesArray = renderedWidgets.t;
var componentDefs = renderedComponents.w;
var typesArray = renderedComponents.t;
if (!doc) {
doc = defaultDocument;
}
for (len=widgetDefs.length; i<len; i++) {
var widgetDef = WidgetDef.$__deserialize(widgetDefs[i], typesArray);
initWidget(widgetDef, doc);
for (len=componentDefs.length; i<len; i++) {
var componentDef = ComponentDef.$__deserialize(componentDefs[i], typesArray);
initComponent(componentDef, doc);
}
}

View File

@ -1,14 +1,14 @@
/**
* Define a new UI component that includes widget and renderer.
* Define a new UI component that includes component and renderer.
*
* @param {Object} def The definition of the UI component (widget methods, widget constructor, rendering methods, etc.)
* @return {Widget} The resulting Widget with renderer
* @param {Object} def The definition of the UI component (component methods, component constructor, rendering methods, etc.)
* @return {Component} The resulting Component with renderer
*/
var defineRenderer;
var defineWidget;
var defineComponent;
module.exports = function defineComponent(def) {
if (def.$__isWidget) {
if (def.$__isComponent) {
return def;
}
@ -20,9 +20,9 @@ module.exports = function defineComponent(def) {
throw new Error('Expected "template" or "renderer"');
}
return defineWidget(def, renderer);
return defineComponent(def, renderer);
};
defineRenderer = require('./defineRenderer-legacy');
defineWidget = require('./defineWidget-legacy');
defineComponent = require('./defineComponent-legacy');

View File

@ -17,7 +17,7 @@ module.exports = function defineRenderer(renderingLogic) {
if (!renderer) {
// Create a renderer function that takes care of translating
// the input properties to a view state. Also, this renderer
// takes care of re-using existing widgets.
// takes care of re-using existing components.
renderer = function renderer(input, out) {
// Render the template associated with the component using the final template
// data that we constructed

View File

@ -2,18 +2,18 @@
/* jshint newcap:false */
var BaseState;
var BaseWidget;
var BaseComponent;
var inherit;
module.exports = function defineWidget(def, renderer) {
def = def.Widget || def;
def = def.Component || def;
if (def.$__isWidget) {
if (def.$__isComponent) {
return def;
}
var WidgetClass = function() {};
var ComponentClass = function() {};
var proto;
if (typeof def === 'function') {
@ -25,28 +25,28 @@ module.exports = function defineWidget(def, renderer) {
throw TypeError();
}
WidgetClass.prototype = proto;
ComponentClass.prototype = proto;
// We don't use the constructor provided by the user
// since we don't invoke their constructor until
// we have had a chance to do our own initialization.
// Instead, we store their constructor in the "initWidget"
// Instead, we store their constructor in the "initComponent"
// property and that method gets called later inside
// init-widgets-browser.js
function Widget(id, doc) {
BaseWidget.call(this, id, doc);
// init-components-browser.js
function Component(id, doc) {
BaseComponent.call(this, id, doc);
}
if (!proto.$__isWidget) {
// Inherit from Widget if they didn't already
inherit(WidgetClass, BaseWidget);
if (!proto.$__isComponent) {
// Inherit from Component if they didn't already
inherit(ComponentClass, BaseComponent);
}
// The same prototype will be used by our constructor after
// we he have set up the prototype chain using the inherit function
proto = Widget.prototype = WidgetClass.prototype;
proto = Component.prototype = ComponentClass.prototype;
proto.constructor = def.constructor = Widget;
proto.constructor = def.constructor = Component;
// get legacy methods
var init = proto.init;
@ -100,8 +100,8 @@ module.exports = function defineWidget(def, renderer) {
// Set a flag on the constructor function to make it clear this is
// a widget so that we can short-circuit this work later
Widget.$__isWidget = true;
// a component so that we can short-circuit this work later
Component.$__isComponent = true;
function State() { BaseState.apply(this, arguments); }
inherit(State, BaseState);
@ -109,7 +109,7 @@ module.exports = function defineWidget(def, renderer) {
if (!renderer) {
renderer = WidgetClass.renderer || WidgetClass.prototype.renderer;
renderer = ComponentClass.renderer || ComponentClass.prototype.renderer;
if (renderer) {
// Legacy support
var createOut = renderer.createOut;
@ -133,15 +133,15 @@ module.exports = function defineWidget(def, renderer) {
if (renderer) {
// Add the rendering related methods as statics on the
// new widget constructor function
Widget.renderer = proto.renderer = renderer;
Widget.render = renderer.render;
Widget.renderSync = renderer.renderSync;
// new component constructor function
Component.renderer = proto.renderer = renderer;
Component.render = renderer.render;
Component.renderSync = renderer.renderSync;
}
return Widget;
return Component;
};
BaseState = require('../State');
BaseWidget = require('../Widget');
BaseComponent = require('../Component');
inherit = require('raptor-util/inherit');

View File

@ -1,17 +1,17 @@
module.exports = function defineWidget(def, renderer) {
if (def.$__isWidget) {
if (def.$__isComponent) {
return def;
}
if (renderer) {
return {
$__isWidget: true,
$__isComponent: true,
renderer: renderer,
render: renderer.render,
renderSync: renderer.renderSync,
template: renderer.template
};
} else {
return {$__isWidget: true};
return {$__isComponent: true};
}
};

View File

@ -2,27 +2,27 @@ var modern = require('../index');
// legacy api
exports.defineComponent = require('./defineComponent-legacy');
exports.defineWidget = require('./defineWidget-legacy');
exports.defineComponent = require('./defineComponent-legacy');
exports.defineRenderer = require('./defineRenderer-legacy');
exports.makeRenderable = exports.renderable = require('../../runtime/renderable');
// referenced by compiled templates
exports.w = require('./defineWidget-legacy');
exports.w = require('./defineComponent-legacy');
exports.rw = modern.rw;
exports.r = require('./renderer-legacy');
// server only
exports.writeInitWidgetsCode = modern.writeInitWidgetsCode;
exports.getRenderedWidgets = modern.getRenderedWidgets;
exports.writeInitComponentsCode = modern.writeInitComponentsCode;
exports.getRenderedComponents = modern.getRenderedComponents;
// browser only
var Widget = exports.Widget = modern.Widget;
exports.onInitWidget = modern.onInitWidget;
exports.getWidgetForEl = modern.getWidgetForEl;
exports.initWidgets = modern.initWidgets;
var Component = exports.Component = modern.Component;
exports.onInitComponent = modern.onInitComponent;
exports.getComponentForEl = modern.getComponentForEl;
exports.initComponents = modern.initComponents;
// monkey patch Widget
if (Widget) {
var WidgetProto = Widget.prototype;
WidgetProto.setProps = WidgetProto.$__setInput;
// monkey patch Component
if (Component) {
var ComponentProto = Component.prototype;
ComponentProto.setProps = ComponentProto.$__setInput;
}

View File

@ -1,17 +1,17 @@
var widgetLookup = require('../util').$__widgetLookup;
var WidgetsContext = require('../WidgetsContext');
var componentLookup = require('../util').$__componentLookup;
var ComponentsContext = require('../ComponentsContext');
var registry = require('../registry');
var modernRenderer = require('../renderer');
var resolveWidgetRef = modernRenderer.$__resolveWidgetRef;
var preserveWidgetEls = modernRenderer.$__preserveWidgetEls;
var resolveComponentRef = modernRenderer.$__resolveComponentRef;
var preserveComponentEls = modernRenderer.$__preserveComponentEls;
var handleBeginAsync = modernRenderer.$__handleBeginAsync;
var WIDGETS_BEGIN_ASYNC_ADDED_KEY = '$wa';
function createRendererFunc(templateRenderFunc, widgetProps) {
var typeName = widgetProps.type;
var roots = widgetProps.roots;
var assignedId = widgetProps.id;
function createRendererFunc(templateRenderFunc, componentProps) {
var typeName = componentProps.type;
var roots = componentProps.roots;
var assignedId = componentProps.id;
return function renderer(input, out, renderingLogic) {
var outGlobal = out.global;
@ -24,105 +24,105 @@ function createRendererFunc(templateRenderFunc, widgetProps) {
var getInitialProps;
var getTemplateData;
var getInitialState;
var getWidgetConfig;
var getComponentConfig;
var getInitialBody;
if (renderingLogic) {
getInitialProps = renderingLogic.getInitialProps;
getTemplateData = renderingLogic.getTemplateData;
getInitialState = renderingLogic.getInitialState;
getWidgetConfig = renderingLogic.getWidgetConfig;
getComponentConfig = renderingLogic.getComponentConfig;
getInitialBody = renderingLogic.getInitialBody;
}
var widgetConfig;
var widgetBody;
var widgetState;
var componentConfig;
var componentBody;
var componentState;
var widget = outGlobal.$w;
var fakeWidget;
var isRerender = widget !== undefined;
var component = outGlobal.$w;
var fakeComponent;
var isRerender = component !== undefined;
var id = assignedId;
var isExisting;
var customEvents;
var scope;
if (widget) {
id = widget.id;
if (component) {
id = component.id;
isExisting = true;
outGlobal.$w = null;
} else {
var widgetArgs = input && input.$w || out.data.$w;
var componentArgs = input && input.$w || out.data.$w;
if (widgetArgs) {
scope = widgetArgs[0];
if (componentArgs) {
scope = componentArgs[0];
if (scope) {
scope = scope.id;
}
var ref = widgetArgs[1];
var ref = componentArgs[1];
if (ref != null) {
ref = ref.toString();
}
id = id || resolveWidgetRef(out, ref, scope);
customEvents = widgetArgs[2];
id = id || resolveComponentRef(out, ref, scope);
customEvents = componentArgs[2];
delete input.$w;
}
}
var widgetsContext = WidgetsContext.$__getWidgetsContext(out);
id = id || widgetsContext.$__nextWidgetId();
var componentsContext = ComponentsContext.$__getComponentsContext(out);
id = id || componentsContext.$__nextComponentId();
if (registry.$__isServer && typeName) {
widget = { id:id, typeName:typeName };
component = { id:id, typeName:typeName };
} else {
if (!widget) {
if (!component) {
if (isRerender) {
// Look in in the DOM to see if a widget with the same ID and type already exists.
widget = widgetLookup[id];
if (widget && widget.$__type !== typeName) {
widget = undefined;
// Look in in the DOM to see if a component with the same ID and type already exists.
component = componentLookup[id];
if (component && component.$__type !== typeName) {
component = undefined;
}
}
if (widget) {
if (component) {
isExisting = true;
} else {
isExisting = false;
// We need to create a new instance of the widget
// We need to create a new instance of the component
if (typeName) {
widget = registry.$__createWidget(typeName, id);
component = registry.$__createComponent(typeName, id);
}
}
}
}
if (input) {
if (getWidgetConfig) {
// If getWidgetConfig() was implemented then use that to
// get the widget config. The widget config will be passed
// to the widget constructor. If rendered on the server the
// widget config will be serialized to a JSON-like data
if (getComponentConfig) {
// If getComponentConfig() was implemented then use that to
// get the component config. The component config will be passed
// to the component constructor. If rendered on the server the
// component config will be serialized to a JSON-like data
// structure and stored in a "data-w-config" attribute.
widgetConfig = getWidgetConfig(input, out);
componentConfig = getComponentConfig(input, out);
} else {
widgetConfig = input.widgetConfig;
componentConfig = input.componentConfig;
}
if (widgetConfig) {
widget.$c = widgetConfig;
if (componentConfig) {
component.$c = componentConfig;
}
if (getInitialBody) {
// If we have widget a widget body then pass it to the template
// so that it is available to the widget tag and can be inserted
// If we have component a component body then pass it to the template
// so that it is available to the component tag and can be inserted
// at the w-body marker
widgetBody = getInitialBody(input, out);
componentBody = getInitialBody(input, out);
}
// If we do not have state then we need to go through the process
// of converting the input to a widget state, or simply normalizing
// of converting the input to a component state, or simply normalizing
// the input using getInitialProps
if (getInitialProps) {
@ -131,59 +131,59 @@ function createRendererFunc(templateRenderFunc, widgetProps) {
}
if (getInitialState) {
// This optional method is used to derive the widget state
// This optional method is used to derive the component state
// from the input properties
widget.state = widgetState = getInitialState(input, out);
component.state = componentState = getInitialState(input, out);
}
if (!widgetBody) {
// Default to using the nested content as the widget body
widgetBody = input.renderBody;
if (!componentBody) {
// Default to using the nested content as the component body
componentBody = input.renderBody;
}
}
if (widget && isExisting) {
if (!widget.$__isDirty || !widget.shouldUpdate(input, widget.$__state)) {
preserveWidgetEls(widget, out, widgetsContext);
if (component && isExisting) {
if (!component.$__isDirty || !component.shouldUpdate(input, component.$__state)) {
preserveComponentEls(component, out, componentsContext);
return;
}
}
if (!widget) {
fakeWidget = {};
if (!component) {
fakeComponent = {};
} else {
widgetState = widget.$__rawState;
componentState = component.$__rawState;
}
var templateInput = getTemplateData ?
getTemplateData(widgetState, input, out) :
widgetState || input || {};
getTemplateData(componentState, input, out) :
componentState || input || {};
var widgetDef = widgetsContext.$__beginWidget(widget || fakeWidget);
widgetDef.$__customEvents = customEvents;
widgetDef.$__scope = scope;
widgetDef.$__roots = roots;
widgetDef.$__widget = fakeWidget ? null : widget;
widgetDef.$__isExisting = isExisting;
widgetDef.b = widgetBody;
widgetDef.c = function(widgetConfig) {
widget.$c = widgetConfig;
var componentDef = componentsContext.$__beginComponent(component || fakeComponent);
componentDef.$__customEvents = customEvents;
componentDef.$__scope = scope;
componentDef.$__roots = roots;
componentDef.$__component = fakeComponent ? null : component;
componentDef.$__isExisting = isExisting;
componentDef.b = componentBody;
componentDef.c = function(componentConfig) {
component.$c = componentConfig;
};
widgetDef.t = function(typeName) {
componentDef.t = function(typeName) {
if (typeName) {
this.$__widget = widget = registry.$__createWidget(typeName, fakeWidget.id);
this.$__component = component = registry.$__createComponent(typeName, fakeComponent.id);
}
};
if (widget && isExisting) {
widget.$__emitLifecycleEvent('$__legacyRender');
if (component && isExisting) {
component.$__emitLifecycleEvent('$__legacyRender');
}
// Render the template associated with the component using the final template
// data that we constructed
templateRenderFunc(templateInput, out, widgetDef);
templateRenderFunc(templateInput, out, componentDef);
widgetDef.$__end();
componentDef.$__end();
};
}

View File

@ -1,7 +1,7 @@
'use strict';
module.exports = function load(typeName) {
// We make the assumption that the widget type name is a path to a
// We make the assumption that the component type name is a path to a
// fully resolved module path and that the module exists
// as a CommonJS module
return require(typeName);

View File

@ -1,8 +1,8 @@
{
"browser": {
"./index.js": "./index-browser.js",
"./init-widgets.js": "./init-widgets-browser.js",
"./legacy/defineWidget-legacy.js": "./legacy/defineWidget-legacy-browser.js",
"./init-components.js": "./init-components-browser.js",
"./legacy/defineComponent-legacy.js": "./legacy/defineComponent-legacy-browser.js",
"./registry.js": "./registry-browser.js",
"./util.js": "./util-browser.js"
}

View File

@ -1,13 +1,13 @@
var loadWidget = require('./loadWidget');
var defineWidget = require('./defineWidget');
var loadComponent = require('./loadComponent');
var defineComponent = require('./defineComponent');
var registered = {};
var loaded = {};
var widgetTypes = {};
var componentTypes = {};
function register(typeName, def) {
if (typeof def === 'function') {
// We do this to kick off registering of nested widgets
// We do this to kick off registering of nested components
// but we don't use the return value just yet since there
// is a good chance that it resulted in a circular dependency
def();
@ -15,7 +15,7 @@ function register(typeName, def) {
registered[typeName] = def;
delete loaded[typeName];
delete widgetTypes[typeName];
delete componentTypes[typeName];
return typeName;
}
@ -28,7 +28,7 @@ function load(typeName) {
target = target();
}
if (!target) {
target = loadWidget(typeName); // Assume the typeName has been fully resolved already
target = loadComponent(typeName); // Assume the typeName has been fully resolved already
}
loaded[typeName] = target || null;
}
@ -39,42 +39,42 @@ function load(typeName) {
return target;
}
function getWidgetClass(typeName) {
var WidgetClass = widgetTypes[typeName];
function getComponentClass(typeName) {
var ComponentClass = componentTypes[typeName];
if (WidgetClass) {
return WidgetClass;
if (ComponentClass) {
return ComponentClass;
}
WidgetClass = load(typeName);
ComponentClass = load(typeName);
if (WidgetClass.Widget) {
WidgetClass = WidgetClass.Widget;
if (ComponentClass.Component) {
ComponentClass = ComponentClass.Component;
}
if (!WidgetClass.$__isWidget) {
WidgetClass = defineWidget(WidgetClass, WidgetClass.renderer);
if (!ComponentClass.$__isComponent) {
ComponentClass = defineComponent(ComponentClass, ComponentClass.renderer);
}
// Make the widget "type" accessible on each widget instance
WidgetClass.prototype.$__type = typeName;
// Make the component "type" accessible on each component instance
ComponentClass.prototype.$__type = typeName;
widgetTypes[typeName] = WidgetClass;
componentTypes[typeName] = ComponentClass;
return WidgetClass;
return ComponentClass;
}
function createWidget(typeName, id) {
var WidgetClass = getWidgetClass(typeName);
var widget;
if (typeof WidgetClass === 'function') {
// The widget is a constructor function that we can invoke to create a new instance of the widget
widget = new WidgetClass(id);
} else if (WidgetClass.initWidget) {
widget = WidgetClass;
function createComponent(typeName, id) {
var ComponentClass = getComponentClass(typeName);
var component;
if (typeof ComponentClass === 'function') {
// The component is a constructor function that we can invoke to create a new instance of the component
component = new ComponentClass(id);
} else if (ComponentClass.initComponent) {
component = ComponentClass;
}
return widget;
return component;
}
exports.$__register = register;
exports.$__createWidget = createWidget;
exports.$__createComponent = createComponent;

View File

@ -3,8 +3,8 @@
const extend = require('raptor-util/extend');
const SERVER_WIDGET_KEY = Symbol();
function createServerWidgetClass(renderingLogic) {
class ServerWidget {
function createServerComponentClass(renderingLogic) {
class ServerComponent {
constructor(id, input, out, typeName) {
this.id = id;
this.$__updatedInput = undefined;
@ -53,19 +53,19 @@ function createServerWidgetClass(renderingLogic) {
}
}
extend(ServerWidget.prototype, renderingLogic);
extend(ServerComponent.prototype, renderingLogic);
return ServerWidget;
return ServerComponent;
}
function createWidget(renderingLogic, id, input, out, typeName) {
var ServerWidget = renderingLogic[SERVER_WIDGET_KEY];
if (!ServerWidget) {
ServerWidget = renderingLogic[SERVER_WIDGET_KEY] = createServerWidgetClass(renderingLogic);
function createComponent(renderingLogic, id, input, out, typeName) {
var ServerComponent = renderingLogic[SERVER_WIDGET_KEY];
if (!ServerComponent) {
ServerComponent = renderingLogic[SERVER_WIDGET_KEY] = createServerComponentClass(renderingLogic);
}
var widget = new ServerWidget(id, input, out, typeName);
return widget;
var component = new ServerComponent(id, input, out, typeName);
return component;
}
exports.$__isServer = true;
exports.$__createWidget = createWidget;
exports.$__createComponent = createComponent;

View File

@ -1,14 +1,14 @@
var widgetsUtil = require('./util');
var widgetLookup = widgetsUtil.$__widgetLookup;
var emitLifecycleEvent = widgetsUtil.$__emitLifecycleEvent;
var componentsUtil = require('./util');
var componentLookup = componentsUtil.$__componentLookup;
var emitLifecycleEvent = componentsUtil.$__emitLifecycleEvent;
var nextRepeatedId = require('./nextRepeatedId');
var repeatedRegExp = /\[\]$/;
var WidgetsContext = require('./WidgetsContext');
var ComponentsContext = require('./ComponentsContext');
var registry = require('./registry');
var WIDGETS_BEGIN_ASYNC_ADDED_KEY = '$wa';
function resolveWidgetRef(out, ref, scope) {
function resolveComponentRef(out, ref, scope) {
if (ref.charAt(0) === '#') {
return ref.substring(1);
} else {
@ -24,8 +24,8 @@ function resolveWidgetRef(out, ref, scope) {
}
}
function preserveWidgetEls(existingWidget, out, widgetsContext) {
var rootEls = existingWidget.$__getRootEls({});
function preserveComponentEls(existingComponent, out, componentsContext) {
var rootEls = existingComponent.$__getRootEls({});
for (var elId in rootEls) {
var el = rootEls[elId];
@ -34,37 +34,37 @@ function preserveWidgetEls(existingWidget, out, widgetsContext) {
// DOM node is matched up correctly when using morphdom.
out.element(el.tagName, { id: elId });
widgetsContext.$__preserveDOMNode(elId); // Mark the element as being preserved (for morphdom)
componentsContext.$__preserveDOMNode(elId); // Mark the element as being preserved (for morphdom)
}
existingWidget.$__reset(); // The widget is no longer dirty so reset internal flags
existingComponent.$__reset(); // The component is no longer dirty so reset internal flags
return true;
}
function handleBeginAsync(event) {
var parentOut = event.parentOut;
var asyncOut = event.out;
var widgetsContext = asyncOut.global.widgets;
var widgetStack;
var componentsContext = asyncOut.global.components;
var componentStack;
if (widgetsContext && (widgetStack = widgetsContext.$__widgetStack)) {
// All of the widgets in this async block should be
// initialized after the widgets in the parent. Therefore,
// we will create a new WidgetsContext for the nested
// async block and will create a new widget stack where the current
// widget in the parent block is the only widget in the nested
// stack (to begin with). This will result in top-level widgets
// of the async block being added as children of the widget in the
if (componentsContext && (componentStack = componentsContext.$__componentStack)) {
// All of the components in this async block should be
// initialized after the components in the parent. Therefore,
// we will create a new ComponentsContext for the nested
// async block and will create a new component stack where the current
// component in the parent block is the only component in the nested
// stack (to begin with). This will result in top-level components
// of the async block being added as children of the component in the
// parent block.
var nestedWidgetsContext = new WidgetsContext(asyncOut, widgetStack[widgetStack.length-1]);
asyncOut.data.widgets = nestedWidgetsContext;
var nestedComponentsContext = new ComponentsContext(asyncOut, componentStack[componentStack.length-1]);
asyncOut.data.components = nestedComponentsContext;
}
asyncOut.data.$w = parentOut.data.$w;
}
function createRendererFunc(templateRenderFunc, widgetProps, renderingLogic) {
function createRendererFunc(templateRenderFunc, componentProps, renderingLogic) {
if (typeof renderingLogic == 'function') {
var ctor = renderingLogic;
renderingLogic = renderingLogic.prototype;
@ -73,9 +73,9 @@ function createRendererFunc(templateRenderFunc, widgetProps, renderingLogic) {
renderingLogic = renderingLogic || {};
var onInput = renderingLogic.onInput;
var typeName = widgetProps.type;
var roots = widgetProps.roots;
var assignedId = widgetProps.id;
var typeName = componentProps.type;
var roots = componentProps.roots;
var assignedId = componentProps.id;
return function renderer(input, out) {
var outGlobal = out.global;
@ -87,101 +87,101 @@ function createRendererFunc(templateRenderFunc, widgetProps, renderingLogic) {
}
}
var widget = outGlobal.$w;
var isRerender = widget !== undefined;
var component = outGlobal.$w;
var isRerender = component !== undefined;
var id = assignedId;
var isExisting;
var customEvents;
var scope;
if (widget) {
id = widget.id;
if (component) {
id = component.id;
isExisting = true;
outGlobal.$w = null;
} else {
var widgetArgs = input && input.$w || out.data.$w;
var componentArgs = input && input.$w || out.data.$w;
if (widgetArgs) {
scope = widgetArgs[0];
if (componentArgs) {
scope = componentArgs[0];
if (scope) {
scope = scope.id;
}
var ref = widgetArgs[1];
var ref = componentArgs[1];
if (ref != null) {
ref = ref.toString();
}
id = id || resolveWidgetRef(out, ref, scope);
customEvents = widgetArgs[2];
id = id || resolveComponentRef(out, ref, scope);
customEvents = componentArgs[2];
delete input.$w;
}
}
var widgetsContext = WidgetsContext.$__getWidgetsContext(out);
id = id || widgetsContext.$__nextWidgetId();
var componentsContext = ComponentsContext.$__getComponentsContext(out);
id = id || componentsContext.$__nextComponentId();
if (registry.$__isServer) {
widget = registry.$__createWidget(renderingLogic, id, input, out, typeName);
input = widget.$__updatedInput;
widget.$__updatedInput = undefined; // We don't want $__updatedInput to be serialized to the browser
component = registry.$__createComponent(renderingLogic, id, input, out, typeName);
input = component.$__updatedInput;
component.$__updatedInput = undefined; // We don't want $__updatedInput to be serialized to the browser
} else {
if (!widget) {
if (!component) {
if (isRerender) {
// Look in in the DOM to see if a widget with the same ID and type already exists.
widget = widgetLookup[id];
if (widget && widget.$__type !== typeName) {
widget = undefined;
// Look in in the DOM to see if a component with the same ID and type already exists.
component = componentLookup[id];
if (component && component.$__type !== typeName) {
component = undefined;
}
}
if (widget) {
if (component) {
isExisting = true;
} else {
isExisting = false;
// We need to create a new instance of the widget
widget = registry.$__createWidget(typeName, id);
// We need to create a new instance of the component
component = registry.$__createComponent(typeName, id);
}
// Set this flag to prevent the widget from being queued for update
// based on the new input. The widget is about to be rerendered
// Set this flag to prevent the component from being queued for update
// based on the new input. The component is about to be rerendered
// so we don't want to queue it up as a result of calling `setInput()`
widget.$__updateQueued = true;
component.$__updateQueued = true;
if (!isExisting) {
emitLifecycleEvent(widget, 'create', input, out);
emitLifecycleEvent(component, 'create', input, out);
}
input = widget.$__setInput(input, onInput, out);
input = component.$__setInput(input, onInput, out);
if (isExisting) {
if (!widget.$__isDirty || !widget.shouldUpdate(input, widget.$__state)) {
preserveWidgetEls(widget, out, widgetsContext);
if (!component.$__isDirty || !component.shouldUpdate(input, component.$__state)) {
preserveComponentEls(component, out, componentsContext);
return;
}
}
}
emitLifecycleEvent(widget, 'render', out);
emitLifecycleEvent(component, 'render', out);
}
var widgetDef = widgetsContext.$__beginWidget(widget);
widgetDef.$__customEvents = customEvents;
widgetDef.$__scope = scope;
widgetDef.$__roots = roots;
widgetDef.$__isExisting = isExisting;
var componentDef = componentsContext.$__beginComponent(component);
componentDef.$__customEvents = customEvents;
componentDef.$__scope = scope;
componentDef.$__roots = roots;
componentDef.$__isExisting = isExisting;
// Render the template associated with the component using the final template
// data that we constructed
templateRenderFunc(input, out, widgetDef, widget.$__rawState);
templateRenderFunc(input, out, componentDef, component.$__rawState);
widgetDef.$__end();
componentDef.$__end();
};
}
module.exports = createRendererFunc;
// exports used by the legacy renderer
createRendererFunc.$__resolveWidgetRef = resolveWidgetRef;
createRendererFunc.$__preserveWidgetEls = preserveWidgetEls;
createRendererFunc.$__resolveComponentRef = resolveComponentRef;
createRendererFunc.$__preserveComponentEls = preserveComponentEls;
createRendererFunc.$__handleBeginAsync = handleBeginAsync;

View File

@ -1,6 +1,6 @@
'use strict';
class WidgetArgs {
class ComponentArgs {
constructor() {
this.id = null;
@ -41,14 +41,14 @@ class WidgetArgs {
var id = this.id;
var customEvents = this.customEvents;
// Make sure the nested widget has access to the ID of the containing
// widget if it is needed
// Make sure the nested component has access to the ID of the containing
// component if it is needed
var shouldProvideScope = id || customEvents;
var args = [];
if (shouldProvideScope) {
args.push(builder.identifier('widget'));
args.push(builder.identifier('component'));
} else {
args.push(builder.literalNull());
}
@ -66,34 +66,34 @@ class WidgetArgs {
if (el.tagDef && el.tagDef.template) {
el.setAttributeValue('$w', builder.literal(args));
} else {
let widgetArgsVar = transformHelper.context.addStaticVar('marko_widgetArgs',
builder.require(builder.literal('marko/widgets/taglib/helpers/widgetArgs')));
let componentArgsVar = transformHelper.context.addStaticVar('marko_componentArgs',
builder.require(builder.literal('marko/components/taglib/helpers/componentArgs')));
let widgetArgsFunctionCall = builder.functionCall(widgetArgsVar, [
let componentArgsFunctionCall = builder.functionCall(componentArgsVar, [
builder.identifierOut(),
builder.literal(args)
]);
let cleanupWidgetArgsFunctionCall = this.buildCleanupWidgetArgsFunctionCall(transformHelper);
let cleanupComponentArgsFunctionCall = this.buildCleanupComponentArgsFunctionCall(transformHelper);
el.onBeforeGenerateCode((event) => {
event.insertCode(widgetArgsFunctionCall);
event.insertCode(componentArgsFunctionCall);
});
el.onAfterGenerateCode((event) => {
event.insertCode(cleanupWidgetArgsFunctionCall);
event.insertCode(cleanupComponentArgsFunctionCall);
});
}
}
buildCleanupWidgetArgsFunctionCall(transformHelper) {
buildCleanupComponentArgsFunctionCall(transformHelper) {
var context = transformHelper.context;
var builder = transformHelper.builder;
var cleanupWidgetArgsVar = context.addStaticVar('marko_cleanupWidgetArgs',
'marko_widgetArgs.cleanup');
var cleanupComponentArgsVar = context.addStaticVar('marko_cleanupComponentArgs',
'marko_componentArgs.cleanup');
return builder.functionCall(cleanupWidgetArgsVar, [builder.identifierOut()]);
return builder.functionCall(cleanupComponentArgsVar, [builder.identifierOut()]);
}
}
module.exports = WidgetArgs;
module.exports = ComponentArgs;

View File

@ -1,33 +1,33 @@
'use strict';
module.exports = function assignWidgetId(isRepeated) {
module.exports = function assignComponentId(isRepeated) {
// First check if we have already assigned an ID to thie element
var widgetIdInfo = this.widgetIdInfo;
var componentIdInfo = this.componentIdInfo;
if (widgetIdInfo) {
return this.widgetIdInfo;
if (componentIdInfo) {
return this.componentIdInfo;
}
var el = this.el;
var context = this.context;
var builder = this.builder;
let widgetRef;
let componentRef;
var nestedIdExpression;
var idExpression;
if (!this.hasBoundWidgetForTemplate()) {
// We are assigning a widget ID to a nested widget in a template that does not have a widget.
// That means we do not have access to the parent widget variable as part of a closure. We
if (!this.hasBoundComponentForTemplate()) {
// We are assigning a component ID to a nested component in a template that does not have a component.
// That means we do not have access to the parent component variable as part of a closure. We
// need to look it up out of the `out.data` map
if (!context.isFlagSet('hasWidgetVar')) {
context.setFlag('hasWidgetVar');
if (!context.isFlagSet('hasComponentVar')) {
context.setFlag('hasComponentVar');
var getCurrentWidgetVar = context.importModule('marko_getCurrentWidget',
this.getMarkoWidgetsRequirePath('marko/widgets/taglib/helpers/getCurrentWidget'));
var getCurrentComponentVar = context.importModule('marko_getCurrentComponent',
this.getMarkoComponentsRequirePath('marko/components/taglib/helpers/getCurrentComponent'));
context.addVar('widget', builder.functionCall(getCurrentWidgetVar, [builder.identifierOut()]));
context.addVar('component', builder.functionCall(getCurrentComponentVar, [builder.identifierOut()]));
}
}
@ -46,35 +46,35 @@ module.exports = function assignWidgetId(isRepeated) {
var isCustomTag = el.type !== 'HtmlElement';
if (el.hasAttribute('key')) {
widgetRef = el.getAttributeValue('key');
componentRef = el.getAttributeValue('key');
el.removeAttribute('key');
} else if (el.hasAttribute('ref')) {
context.deprecate('The "ref" attribute is deprecated. Please use "key" instead.');
widgetRef = el.getAttributeValue('ref');
componentRef = el.getAttributeValue('ref');
el.removeAttribute('ref');
}
if (el.hasAttribute('w-id')) {
context.deprecate('The "w-id" attribute is deprecated. Please use "key" instead.');
if (widgetRef) {
if (componentRef) {
this.addError('The "w-id" attribute cannot be used in conjuction with the "ref" or "key" attributes.');
return;
}
widgetRef = el.getAttributeValue('w-id');
componentRef = el.getAttributeValue('w-id');
el.removeAttribute('w-id');
}
if (widgetRef) {
idExpression = this.buildWidgetElIdFunctionCall(widgetRef);
if (componentRef) {
idExpression = this.buildComponentElIdFunctionCall(componentRef);
nestedIdExpression = widgetRef;
nestedIdExpression = componentRef;
if (isCustomTag) {
// The element is a custom tag
this.getWidgetArgs().setId(nestedIdExpression);
this.getComponentArgs().setId(nestedIdExpression);
} else {
if (el.hasAttribute('id')) {
this.addError('The "ref", "key", and "w-id" attributes cannot be used in conjuction with the "id" attribute.');
@ -85,9 +85,9 @@ module.exports = function assignWidgetId(isRepeated) {
} else if (el.hasAttribute('id')) {
idExpression = el.getAttributeValue('id');
if (el.isFlagSet('hasWidgetBind')) {
// We have to attach a listener to the root element of the widget
// We will use an empty string as an indicator that it is the root widget
if (el.isFlagSet('hasComponentBind')) {
// We have to attach a listener to the root element of the component
// We will use an empty string as an indicator that it is the root component
// element.
nestedIdExpression = builder.literal('');
} else {
@ -103,10 +103,10 @@ module.exports = function assignWidgetId(isRepeated) {
nestedIdExpression = isRepeated ? builder.literal(uniqueElId + '[]') : builder.literal(uniqueElId);
idExpression = this.buildWidgetElIdFunctionCall(nestedIdExpression);
idExpression = this.buildComponentElIdFunctionCall(nestedIdExpression);
if (isCustomTag) {
this.getWidgetArgs().setId(nestedIdExpression);
this.getComponentArgs().setId(nestedIdExpression);
} else {
el.setAttributeValue('id', idExpression);
}
@ -114,7 +114,7 @@ module.exports = function assignWidgetId(isRepeated) {
var transformHelper = this;
this.widgetIdInfo = {
this.componentIdInfo = {
idExpression: idExpression,
nestedIdExpression: nestedIdExpression,
idVarNode: null,
@ -124,7 +124,7 @@ module.exports = function assignWidgetId(isRepeated) {
}
let uniqueElId = transformHelper.nextUniqueId();
let idVarName = '__widgetId' + uniqueElId;
let idVarName = '__componentId' + uniqueElId;
let idVar = builder.identifier(idVarName);
this.idVarNode = builder.vars([
@ -141,7 +141,7 @@ module.exports = function assignWidgetId(isRepeated) {
idVar);
if (isCustomTag) {
transformHelper.getWidgetArgs().setId(nestedIdExpression);
transformHelper.getComponentArgs().setId(nestedIdExpression);
} else {
el.setAttributeValue('id', idExpression);
}
@ -150,5 +150,5 @@ module.exports = function assignWidgetId(isRepeated) {
}
};
return this.widgetIdInfo;
return this.componentIdInfo;
};

View File

@ -17,14 +17,14 @@ function isTemplateMainEntry(context) {
return filename === 'index';
}
function checkCombinedComponent(widgetModulePath) {
let filename = path.basename(widgetModulePath);
function checkCombinedComponent(componentModulePath) {
let filename = path.basename(componentModulePath);
let ext = path.extname(filename);
if (ext) {
filename = filename.slice(0, 0 - ext.length);
}
return filename !== 'widget';
return filename !== 'component';
}
function checkSplitComponent(context) {
@ -38,7 +38,7 @@ function checkIsInnerBind(el) {
var curNode = el;
while (true) {
if (curNode.data.hasBoundWidget) {
if (curNode.data.hasBoundComponent) {
return true;
}
@ -52,20 +52,20 @@ function checkIsInnerBind(el) {
return false;
}
module.exports = function handleWidgetBind() {
module.exports = function handleComponentBind() {
let el = this.el;
let context = this.context;
let builder = this.builder;
let internalBindAttr = el.getAttribute('_widgetbind');
let internalBindAttr = el.getAttribute('_componentbind');
let bindAttr = el.getAttribute('w-bind');
let bindAttrValue;
if (internalBindAttr == null && bindAttr == null) {
return;
} else if (bindAttr != null) {
context.deprecate('Legacy widgets using w-bind and defineRenderer/defineWidget or defineComponent are deprecated. See: https://github.com/marko-js/marko/issues/421');
this.isLegacyWidget = true;
context.deprecate('Legacy components using w-bind and defineRenderer/defineComponent or defineComponent are deprecated. See: https://github.com/marko-js/marko/issues/421');
this.isLegacyComponent = true;
// Remove the w-bind attribute since we don't want it showing up in the output DOM
el.removeAttribute('w-bind');
@ -73,20 +73,20 @@ module.exports = function handleWidgetBind() {
// Read the value for the w-bind attribute. This will be an AST node for the parsed JavaScript
bindAttrValue = bindAttr.value;
} else if (internalBindAttr != null) {
el.removeAttribute('_widgetbind');
el.removeAttribute('_componentbind');
}
this.setHasBoundWidgetForTemplate();
this.setHasBoundComponentForTemplate();
var isInnerBind = checkIsInnerBind(el.parentNode);
el.data.hasBoundWidget = true;
el.data.hasBoundComponent = true;
// A widget is bound to the el...
// A component is bound to the el...
let modulePath;
var widgetProps = isInnerBind ? {} : this.getWidgetProps();
var componentProps = isInnerBind ? {} : this.getComponentProps();
let isMain = isTemplateMainEntry(context);
let transformHelper = this;
@ -97,19 +97,19 @@ module.exports = function handleWidgetBind() {
let isRendererExport;
let rendererPath;
const hasWidgetTypes = context.isFlagSet('hasWidgetTypes');
const hasComponentTypes = context.isFlagSet('hasComponentTypes');
if (hasWidgetTypes) {
context.deprecate('The <widget-types> tag is deprecated. Please remove it. See: https://github.com/marko-js/marko/issues/514');
if (hasComponentTypes) {
context.deprecate('The <component-types> tag is deprecated. Please remove it. See: https://github.com/marko-js/marko/issues/514');
}
if (bindAttrValue == null) {
if (inlineComponent) {
modulePath = context.filename;
} else {
modulePath = this.getDefaultWidgetModule();
modulePath = this.getDefaultComponentModule();
if (!modulePath) {
this.addError('No corresponding JavaScript module found in the same directory (either "widget.js" or "index.js"). Actual: ' + modulePath);
this.addError('No corresponding JavaScript module found in the same directory (either "component.js" or "index.js"). Actual: ' + modulePath);
return;
}
}
@ -120,18 +120,18 @@ module.exports = function handleWidgetBind() {
return;
}
} else {
// This is a dynamic expression. The <widget-types> should have been found.
if (!hasWidgetTypes) {
this.addError('The <widget-types> tag must be used to declare widgets when the value of the "w-bind" attribute is a dynamic expression.');
// This is a dynamic expression. The <component-types> should have been found.
if (!hasComponentTypes) {
this.addError('The <component-types> tag must be used to declare components when the value of the "w-bind" attribute is a dynamic expression.');
return;
}
el.insertSiblingBefore(
builder.functionCall(
builder.memberExpression(builder.identifier('widget'), builder.identifier('t')),
builder.memberExpression(builder.identifier('component'), builder.identifier('t')),
[
builder.memberExpression(
builder.identifier('marko_widgetTypes'),
builder.identifier('marko_componentTypes'),
bindAttrValue,
true /* computed */)
]));
@ -162,30 +162,30 @@ module.exports = function handleWidgetBind() {
}
if (modulePath) {
let widgetTypeNode;
let componentTypeNode;
var widgetPath = modulePath;
var widgetTypeImport;
var componentPath = modulePath;
var componentTypeImport;
if (isMain && isComponentExport) {
widgetPath = './' + path.basename(context.filename);
widgetTypeImport = builder.functionDeclaration(null, [], [
componentPath = './' + path.basename(context.filename);
componentTypeImport = builder.functionDeclaration(null, [], [
builder.returnStatement(builder.memberExpression(builder.identifier('module'), builder.identifier('exports')))
]);
}
context.addDependency({ type:'require', path:widgetPath });
context.addDependency({ type:'require', path:'marko/widgets' });
context.addDependency({ type:'require', path:componentPath });
context.addDependency({ type:'require', path:'marko/components' });
widgetTypeNode = context.addStaticVar('marko_widgetType', this.buildWidgetTypeNode(widgetPath, widgetTypeImport));
componentTypeNode = context.addStaticVar('marko_componentType', this.buildComponentTypeNode(componentPath, componentTypeImport));
widgetProps.type = widgetTypeNode;
componentProps.type = componentTypeNode;
}
if (el.hasAttribute('w-config')) {
el.insertSiblingBefore(
builder.functionCall(
builder.memberExpression(builder.identifier('widget'), builder.identifier('c')),
builder.memberExpression(builder.identifier('component'), builder.identifier('c')),
[
el.getAttributeValue('w-config')
]));
@ -196,37 +196,37 @@ module.exports = function handleWidgetBind() {
let id = el.getAttributeValue('id');
if (id) {
widgetProps.id = id;
componentProps.id = id;
}
if (isInnerBind) {
// let widgetOptionsVar = context.addStaticVar(
// 'widgetOptions',
// let componentOptionsVar = context.addStaticVar(
// 'componentOptions',
// builder.functionCall(
// builder.memberExpression(transformHelper.markoWidgetsVar, builder.identifier('r')),
// builder.memberExpression(transformHelper.markoComponentsVar, builder.identifier('r')),
// [
// builder.renderBodyFunction([el]),
// builder.literal(widgetProps)
// builder.literal(componentProps)
// ]));
//
// widgetProps._ = widgetOptionsVar;
// componentProps._ = componentOptionsVar;
el.setAttributeValue('id',
builder.memberExpression(
builder.identifier('widget'),
builder.identifier('component'),
builder.identifier('id')));
// TODO Deprecation warning for inner binds
let widgetNode = context.createNodeForEl('_widget', {
props: builder.literal(widgetProps)
let componentNode = context.createNodeForEl('_component', {
props: builder.literal(componentProps)
});
el.wrapWith(widgetNode);
el.wrapWith(componentNode);
return;
}
if (this.firstBind) {
this.context.on('beforeGenerateCode:TemplateRoot', function(eventArgs) {
eventArgs.node.addRenderFunctionParam(builder.identifier('widget'));
eventArgs.node.addRenderFunctionParam(builder.identifier('component'));
eventArgs.node.addRenderFunctionParam(builder.identifier('state'));
eventArgs.node.generateAssignRenderCode = function(eventArgs) {
let nodes = [];
@ -236,7 +236,7 @@ module.exports = function handleWidgetBind() {
var createRendererArgs = [
renderFunctionVar,
builder.literal(widgetProps)
builder.literal(componentProps)
];
if (renderingLogic) {
@ -246,14 +246,14 @@ module.exports = function handleWidgetBind() {
nodes.push(builder.assignment(
templateRendererMember,
builder.functionCall(
builder.memberExpression(transformHelper.markoWidgetsVar, builder.identifier('r')),
builder.memberExpression(transformHelper.markoComponentsVar, builder.identifier('r')),
createRendererArgs)));
if (inlineComponent || isComponentExport) {
nodes.push(builder.assignment(
builder.memberExpression(templateVar, builder.identifier('Widget')),
builder.memberExpression(templateVar, builder.identifier('Component')),
builder.functionCall(
builder.memberExpression(transformHelper.markoWidgetsVar, builder.identifier('w')),
builder.memberExpression(transformHelper.markoComponentsVar, builder.identifier('w')),
[
renderingLogic,
templateRendererMember
@ -265,36 +265,36 @@ module.exports = function handleWidgetBind() {
});
}
// let widgetNode = el.data.widgetNode;
// let componentNode = el.data.componentNode;
//
// if (widgetNode) {
// widgetNode.setAttributeValues(widgetProps);
// if (componentNode) {
// componentNode.setAttributeValues(componentProps);
// } else {
// widgetNode = context.createNodeForEl('_widget', widgetProps);
// el.wrapWith(widgetNode);
// componentNode = context.createNodeForEl('_component', componentProps);
// el.wrapWith(componentNode);
// }
if (el.hasAttribute('key')) {
if (!widgetProps.roots) {
widgetProps.roots = [];
if (!componentProps.roots) {
componentProps.roots = [];
}
var key = el.getAttributeValue('key');
widgetProps.roots.push(key);
componentProps.roots.push(key);
} else if (el.hasAttribute('ref')) {
if (!widgetProps.roots) {
widgetProps.roots = [];
if (!componentProps.roots) {
componentProps.roots = [];
}
var ref = el.getAttributeValue('ref');
widgetProps.roots.push(ref);
componentProps.roots.push(ref);
} else {
el.setAttributeValue('id',
builder.memberExpression(
builder.identifier('widget'),
builder.identifier('component'),
builder.identifier('id')));
}
// this.widgetStack.push({
// widgetNode: widgetNode,
// this.componentStack.push({
// componentNode: componentNode,
// el: el,
// extend: false
// });

View File

@ -19,15 +19,15 @@ function isUpperCase(c) {
function addBubblingEventListener(transformHelper, eventType, targetMethod, extraArgs) {
var el = transformHelper.el;
if (transformHelper.hasBoundWidgetForTemplate() === false) {
transformHelper.addError('Unable to handle event ' + eventType + '. HTML element is not nested within a widget.');
if (transformHelper.hasBoundComponentForTemplate() === false) {
transformHelper.addError('Unable to handle event ' + eventType + '. HTML element is not nested within a component.');
return;
}
var builder = transformHelper.builder;
var addBubblingEventMethod = builder.memberExpression(
builder.identifier('widget'),
builder.identifier('component'),
builder.identifier('d'));
var addBubblingEventArgs = [
@ -46,7 +46,7 @@ function addBubblingEventListener(transformHelper, eventType, targetMethod, extr
if (!transformHelper.context.data[ATTACH_DETACH_KEY]) {
transformHelper.context.data[ATTACH_DETACH_KEY] = true;
let requireFuncCall = builder.require(builder.literal('marko/widgets/attach-detach'));
let requireFuncCall = builder.require(builder.literal('marko/components/attach-detach'));
transformHelper.context.addStaticCode(requireFuncCall);
}
@ -58,16 +58,16 @@ function addDirectEventListener(transformHelper, eventType, targetMethod, extraA
var el = transformHelper.el;
var addDomEvent = builder.memberExpression(
builder.identifier('widget'),
builder.identifier('component'),
builder.identifier('e'));
let widgetIdInfo = transformHelper.assignWidgetId(true /* repeated */);
let idVarNode = widgetIdInfo.idVarNode ? null : widgetIdInfo.createIdVarNode();
let componentIdInfo = transformHelper.assignComponentId(true /* repeated */);
let idVarNode = componentIdInfo.idVarNode ? null : componentIdInfo.createIdVarNode();
var helperArgs = [
eventType,
targetMethod,
widgetIdInfo.idExpression
componentIdInfo.idExpression
];
if (extraArgs) {
@ -87,17 +87,17 @@ function addDirectEventListener(transformHelper, eventType, targetMethod, extraA
function addCustomEventListener(transformHelper, eventType, targetMethod, extraArgs) {
var builder = transformHelper.builder;
// Make sure the widget has an assigned scope ID so that we can bind the custom event listener
var widgetArgs = transformHelper.getWidgetArgs();
// Make sure the component has an assigned scope ID so that we can bind the custom event listener
var componentArgs = transformHelper.getComponentArgs();
if (extraArgs) {
extraArgs = builder.arrayExpression(extraArgs);
}
widgetArgs.addCustomEvent(eventType, targetMethod, extraArgs);
componentArgs.addCustomEvent(eventType, targetMethod, extraArgs);
}
module.exports = function handleWidgetEvents() {
module.exports = function handleComponentEvents() {
var el = this.el;
var builder = this.builder;
var context = this.context;
@ -106,9 +106,9 @@ module.exports = function handleWidgetEvents() {
// have one or more attributes that match the "w-on*" pattern.
// We still need to loop over the properties to find and handle
// the properties corresponding to those attributes.
var hasWidgetEvents = this.el.isFlagSet('hasWidgetEvents') === true;
var hasComponentEvents = this.el.isFlagSet('hasComponentEvents') === true;
if (hasWidgetEvents) {
if (hasComponentEvents) {
var attrs = el.getAttributes().concat([]);
attrs.forEach((attr) => {
@ -152,7 +152,7 @@ module.exports = function handleWidgetEvents() {
el.removeAttribute(attrName);
if (isCustomTag) {
this.assignWidgetId(true /* repeated */);
this.assignComponentId(true /* repeated */);
// We are adding an event listener for a custom event (not a DOM event)
if (eventType.startsWith('-')) {
@ -192,7 +192,7 @@ module.exports = function handleWidgetEvents() {
// that can be used to handle the event. We will add
// a "data-w-on{eventType}" attribute to the output HTML
// for this element that will be used to map the event
// to a method on the containing widget.
// to a method on the containing component.
addBubblingEventListener(this, eventType, targetMethod, extraArgs);
} else {
// The event does not bubble so we must attach a DOM

View File

@ -1,29 +1,29 @@
module.exports = function handleWidgetFor() {
module.exports = function handleComponentFor() {
var el = this.el;
var context = this.context;
var widgetFor;
var componentFor;
if (el.hasAttribute('for-ref')) {
context.deprecate('The "for-ref" tag is deprecated. Please use "for-key" instead.');
widgetFor = el.getAttributeValue('for-ref');
componentFor = el.getAttributeValue('for-ref');
el.removeAttribute('for-ref');
} else if (el.hasAttribute('for-key')) {
widgetFor = el.getAttributeValue('for-key');
componentFor = el.getAttributeValue('for-key');
el.removeAttribute('for-key');
}
if (el.hasAttribute('w-for')) {
context.deprecate('The "w-for" tag is deprecated. Please use "for-ref" instead.');
if (widgetFor) {
if (componentFor) {
this.addError('The "w-for" tag cannot be used with "for-ref" or "for-key".');
return;
} else {
widgetFor = el.getAttributeValue('w-for');
componentFor = el.getAttributeValue('w-for');
}
el.removeAttribute('w-for');
}
if (widgetFor == null) {
if (componentFor == null) {
return;
}
@ -33,6 +33,6 @@ module.exports = function handleWidgetFor() {
} else {
el.setAttributeValue(
'for',
this.buildWidgetElIdFunctionCall(widgetFor));
this.buildComponentElIdFunctionCall(componentFor));
}
};

View File

@ -15,8 +15,8 @@ function addPreserve(transformHelper, bodyOnly, condition) {
preserveAttrs['if'] = condition;
}
let widgetIdInfo = transformHelper.assignWidgetId(true /* repeated */);
let idVarNode = widgetIdInfo.idVarNode ? null : widgetIdInfo.createIdVarNode();
let componentIdInfo = transformHelper.assignComponentId(true /* repeated */);
let idVarNode = componentIdInfo.idVarNode ? null : componentIdInfo.createIdVarNode();
preserveAttrs.id = transformHelper.getIdExpression();
@ -153,7 +153,7 @@ const preserveTypes = [
}
];
module.exports = function handleWidgetPreserve() {
module.exports = function handleComponentPreserve() {
let el = this.el;
for (let i = 0; i < preserveTypes.length; i++) {

View File

@ -1,6 +1,6 @@
const NO_UPDATE_ATTR_SUFFIX = ':no-update';
function handleWidgetPreserveAttrs() {
function handleComponentPreserveAttrs() {
var el = this.el;
var context = this.context;
var builder = context.builder;
@ -36,4 +36,4 @@ function handleWidgetPreserveAttrs() {
}
}
module.exports = handleWidgetPreserveAttrs;
module.exports = handleComponentPreserveAttrs;

View File

@ -1,11 +1,11 @@
'use strict';
var includeTagForWidgets = require.resolve('../include-tag');
var includeTagForComponents = require.resolve('../include-tag');
module.exports = function(includeNode) {
var context = this.context;
if (!this.hasBoundWidgetForTemplate()) {
if (!this.hasBoundComponentForTemplate()) {
return;
}
@ -19,26 +19,26 @@ module.exports = function(includeNode) {
if (parentNode.childCount === 1) {
if (includeNode.hasAttribute('key') || includeNode.hasAttribute('ref')) {
this.assignWidgetId();
this.assignComponentId();
}
let parentTransformHelper = this.getTransformHelper(parentNode);
if (includeNode.data.bodySlot) {
parentTransformHelper.assignWidgetId(false /* not repeated */);
var widgetProps = this.getWidgetProps();
widgetProps.body = parentTransformHelper.getNestedIdExpression();
parentTransformHelper.assignComponentId(false /* not repeated */);
var componentProps = this.getComponentProps();
componentProps.body = parentTransformHelper.getNestedIdExpression();
} else {
let widgetIdInfo = parentTransformHelper.assignWidgetId(true /* repeated */);
if (!widgetIdInfo.idVarNode) {
let idVarNode = widgetIdInfo.createIdVarNode();
let componentIdInfo = parentTransformHelper.assignComponentId(true /* repeated */);
if (!componentIdInfo.idVarNode) {
let idVarNode = componentIdInfo.createIdVarNode();
parentNode.onBeforeGenerateCode((event) => {
event.insertCode(idVarNode);
});
}
}
includeNode.setRendererPath(includeTagForWidgets);
includeNode.setRendererPath(includeTagForComponents);
includeNode.onBeforeGenerateCode(function() {
includeNode.addProp('_elId', parentTransformHelper.getIdExpression());
@ -55,7 +55,7 @@ module.exports = function(includeNode) {
// data = builder.literal(null);
// }
//
// let includeVar = context.importModule('marko_widget_include', this.getMarkoWidgetsRequirePath('marko/widgets/taglib/helpers/include'));
// let includeVar = context.importModule('marko_component_include', this.getMarkoComponentsRequirePath('marko/components/taglib/helpers/include'));
//
// let includeArgs = [
// target,

View File

@ -94,7 +94,7 @@ function handleScriptElement(scriptEl, transformHelper) {
componentVar = builder.identifier('marko_component');
}
transformHelper.setHasBoundWidgetForTemplate();
transformHelper.setHasBoundComponentForTemplate();
transformHelper.setInlineComponent(componentVar);
transformHelper.context.addStaticCode(escodegen.generate(updatedTree));
scriptEl.detach();
@ -216,7 +216,7 @@ function handleClassDeclaration(classEl, transformHelper) {
let object = classToObject(expression);
let componentVar = transformHelper.context.addStaticVar('marko_component', escodegen.generate(object));
transformHelper.setHasBoundWidgetForTemplate();
transformHelper.setHasBoundComponentForTemplate();
transformHelper.setInlineComponent(componentVar);
classEl.detach();
}
@ -234,7 +234,7 @@ module.exports = function handleRootNodes() {
var filematch = '('+filename.replace(/\./g, '\\.') + '\\.' + (isEntry ? '|' : '') + ')';
var stylematch = new RegExp('^'+filematch+'style\\.\\w+$');
var componentmatch = new RegExp('^'+filematch+'component\\.\\w+$');
var widgetmatch = new RegExp('^'+filematch+'widget\\.\\w+$');
var componentmatch = new RegExp('^'+filematch+'component\\.\\w+$');
var templateRoot = this.el;
@ -244,9 +244,9 @@ module.exports = function handleRootNodes() {
fs.readdirSync(dirname).forEach(file => {
if(stylematch.test(file)) {
context.addDependency('./' + file);
} else if(componentmatch.test(file) || widgetmatch.test(file)) {
} else if(componentmatch.test(file) || componentmatch.test(file)) {
hasBindTarget = true;
this.context.data.widgetModule = './'+file.slice(0, file.lastIndexOf('.'));
this.context.data.componentModule = './'+file.slice(0, file.lastIndexOf('.'));
}
});
@ -265,7 +265,7 @@ module.exports = function handleRootNodes() {
// Don't worry about the TemplateRoot or an Container node
} else if (node.type === 'HtmlElement') {
if (node.hasAttribute('w-bind')) {
transformHelper.setHasBoundWidgetForTemplate();
transformHelper.setHasBoundComponentForTemplate();
hasExplicitBind = true;
} else {
if (node.hasAttribute('id')) {
@ -321,17 +321,17 @@ module.exports = function handleRootNodes() {
}
if (rootNodes.length > 1 && hasIdCount > 0) {
// We can only bind a widget to multiple top-level elements if we can assign
// We can only bind a component to multiple top-level elements if we can assign
// all of the IDs
return;
}
transformHelper.setHasBoundWidgetForTemplate();
transformHelper.setHasBoundComponentForTemplate();
var nextKey = 0;
rootNodes.forEach((curNode, i) => {
curNode.setAttributeValue('_widgetbind');
curNode.setAttributeValue('_componentbind');
if (!curNode.hasAttribute('key') && !curNode.hasAttribute('ref')) {
if (curNode.type === 'CustomTag' || rootNodes.length > 1) {

View File

@ -1,7 +1,7 @@
'use strict';
var WidgetArgs = require('./WidgetArgs');
var ComponentArgs = require('./ComponentArgs');
var getRequirePath = require('../getRequirePath');
var buildWidgetTypeNode = require('../util/buildWidgetTypeNode');
var buildComponentTypeNode = require('../util/buildComponentTypeNode');
var resolveFrom = require('resolve-from');
var INLINE_COMPONENT_KEY = Symbol('INLINE_COMPONENT');
var MARKO_WIDGETS_VAR_KEY = Symbol('MARKO_WIDGETS_VAR');
@ -15,82 +15,82 @@ class TransformHelper {
this.builder = context.builder;
this.dirname = context.dirname;
this.widgetNextElId = 0;
this.widgetArgs = undefined;
this.containingWidgetNode = undefined;
this._markoWidgetsVar = context.data.markoWidgetsVar;
this.componentNextElId = 0;
this.componentArgs = undefined;
this.containingComponentNode = undefined;
this._markoComponentsVar = context.data.markoComponentsVar;
this.firstBind = false;
}
setHasBoundWidgetForTemplate() {
setHasBoundComponentForTemplate() {
this.context.data[HAS_WIDGET_KEY] = true;
}
hasBoundWidgetForTemplate() {
hasBoundComponentForTemplate() {
return this.context.data[HAS_WIDGET_KEY] || this.context.data[WIDGET_PROPS_KEY] != null;
}
getWidgetProps() {
var widgetProps = this.context.data[WIDGET_PROPS_KEY];
if (!widgetProps) {
getComponentProps() {
var componentProps = this.context.data[WIDGET_PROPS_KEY];
if (!componentProps) {
this.firstBind = true;
widgetProps = this.context.data[WIDGET_PROPS_KEY] = {};
componentProps = this.context.data[WIDGET_PROPS_KEY] = {};
}
return widgetProps;
return componentProps;
}
addError(message, code) {
this.context.addError(this.el, message, code);
}
getWidgetArgs() {
return this.widgetArgs || (this.widgetArgs = new WidgetArgs());
getComponentArgs() {
return this.componentArgs || (this.componentArgs = new ComponentArgs());
}
nextUniqueId() {
var widgetNextElId = this.context.data.widgetNextElId;
if (widgetNextElId == null) {
this.context.data.widgetNextElId = 0;
var componentNextElId = this.context.data.componentNextElId;
if (componentNextElId == null) {
this.context.data.componentNextElId = 0;
}
return (this.context.data.widgetNextElId++);
return (this.context.data.componentNextElId++);
}
getNestedIdExpression() {
this.assignWidgetId();
return this.getWidgetIdInfo().nestedIdExpression;
this.assignComponentId();
return this.getComponentIdInfo().nestedIdExpression;
}
getIdExpression() {
this.assignWidgetId();
return this.getWidgetIdInfo().idExpression;
this.assignComponentId();
return this.getComponentIdInfo().idExpression;
}
set widgetIdInfo(value) {
this.el.data.widgetIdInfo = value;
set componentIdInfo(value) {
this.el.data.componentIdInfo = value;
}
get widgetIdInfo() {
return this.el.data.widgetIdInfo;
get componentIdInfo() {
return this.el.data.componentIdInfo;
}
getWidgetIdInfo() {
return this.widgetIdInfo;
getComponentIdInfo() {
return this.componentIdInfo;
}
getCompileContext() {
return this.context;
}
getDefaultWidgetModule() {
getDefaultComponentModule() {
var dirname = this.dirname;
if (this.context.data.widgetModule) {
return this.context.data.widgetModule;
if (this.context.data.componentModule) {
return this.context.data.componentModule;
} else if (resolveFrom(dirname, './component')) {
return './component';
} else if (resolveFrom(dirname, './component')) {
return './component';
} else if (resolveFrom(dirname, './widget')) {
return './widget';
} else if (resolveFrom(dirname, './')) {
return './';
} else {
@ -98,37 +98,37 @@ class TransformHelper {
}
}
getMarkoWidgetsRequirePath(target) {
getMarkoComponentsRequirePath(target) {
return getRequirePath(target, this.context);
}
set markoWidgetsVar(value) {
set markoComponentsVar(value) {
this.context.data[MARKO_WIDGETS_VAR_KEY] = value;
}
get markoWidgetsVar() {
get markoComponentsVar() {
if (!this.context.data[MARKO_WIDGETS_VAR_KEY]) {
this.context.data[MARKO_WIDGETS_VAR_KEY] =
this.context.importModule(
'marko_widgets',
this.getMarkoWidgetsRequirePath(this.isLegacyWidget ? 'marko/widgets/legacy' : 'marko/widgets'));
'marko_components',
this.getMarkoComponentsRequirePath(this.isLegacyComponent ? 'marko/components/legacy' : 'marko/components'));
}
return this.context.data[MARKO_WIDGETS_VAR_KEY];
}
buildWidgetElIdFunctionCall(id) {
buildComponentElIdFunctionCall(id) {
var builder = this.builder;
var widgetElId = builder.memberExpression(
builder.identifier('widget'),
var componentElId = builder.memberExpression(
builder.identifier('component'),
builder.identifier('elId'));
return builder.functionCall(widgetElId, arguments.length === 0 ? [] : [ id ]);
return builder.functionCall(componentElId, arguments.length === 0 ? [] : [ id ]);
}
buildWidgetTypeNode(path, def) {
return buildWidgetTypeNode(path, this.dirname, def, this);
buildComponentTypeNode(path, def) {
return buildComponentTypeNode(path, this.dirname, def, this);
}
getTransformHelper(el) {
@ -148,13 +148,13 @@ class TransformHelper {
}
}
TransformHelper.prototype.assignWidgetId = require('./assignWidgetId');
TransformHelper.prototype.assignComponentId = require('./assignComponentId');
TransformHelper.prototype.handleRootNodes = require('./handleRootNodes');
TransformHelper.prototype.handleIncludeNode = require('./handleIncludeNode');
TransformHelper.prototype.handleWidgetEvents = require('./handleWidgetEvents');
TransformHelper.prototype.handleWidgetPreserve = require('./handleWidgetPreserve');
TransformHelper.prototype.handleWidgetPreserveAttrs = require('./handleWidgetPreserveAttrs');
TransformHelper.prototype.handleWidgetBind = require('./handleWidgetBind');
TransformHelper.prototype.handleWidgetFor = require('./handleWidgetFor');
TransformHelper.prototype.handleComponentEvents = require('./handleComponentEvents');
TransformHelper.prototype.handleComponentPreserve = require('./handleComponentPreserve');
TransformHelper.prototype.handleComponentPreserveAttrs = require('./handleComponentPreserveAttrs');
TransformHelper.prototype.handleComponentBind = require('./handleComponentBind');
TransformHelper.prototype.handleComponentFor = require('./handleComponentFor');
module.exports = TransformHelper;

View File

@ -6,6 +6,6 @@ module.exports = function transform(el, context) {
let awaitReorderer = context.createNodeForEl('await-reorderer');
el.appendChild(awaitReorderer);
let initWidgetsNode = context.createNodeForEl('init-widgets');
el.appendChild(initWidgetsNode);
let initComponentsNode = context.createNodeForEl('init-components');
el.appendChild(initComponentsNode);
};

View File

@ -7,25 +7,25 @@ module.exports = function codeGenerator(el, codegen) {
var bodyFunc = builder.renderBodyFunction(el.body, [
builder.identifierOut(),
builder.identifier('widget'),
builder.identifier('component'),
builder.identifier('state')
]);
var widgetProps = el.getAttributeValue('props');
var componentProps = el.getAttributeValue('props');
var bindWidgetVar = context.addStaticVar('marko_bindWidget',
var bindComponentVar = context.addStaticVar('marko_bindComponent',
builder.require(
builder.literal('marko/widgets/taglib/helpers/bindWidget')));
builder.literal('marko/components/taglib/helpers/bindComponent')));
if (context.data[BIND_WIDGET_KEY] == null) {
context.data[BIND_WIDGET_KEY] = 0;
}
var varName = context.addStaticVar(
'marko_bindWidget' + (context.data[BIND_WIDGET_KEY]++),
builder.functionCall(bindWidgetVar, [
widgetProps
'marko_bindComponent' + (context.data[BIND_WIDGET_KEY]++),
builder.functionCall(bindComponentVar, [
componentProps
]));
return builder.functionCall(varName, [bodyFunc, builder.identifierOut()]);

View File

@ -4,7 +4,7 @@ module.exports = function codeGenerator(el, codegen) {
var context = codegen.context;
var transformHelper = getTransformHelper(el, context);
transformHelper.isLegacyWidget = true;
transformHelper.isLegacyComponent = true;
var builder = codegen.builder;
@ -14,14 +14,14 @@ module.exports = function codeGenerator(el, codegen) {
attrs.forEach((attr) => {
if (!attr.isLiteralString()) {
codegen.addError('Widget type should be a string');
codegen.addError('Component type should be a string');
return;
}
typesObject[attr.name] = transformHelper.buildWidgetTypeNode(attr.literalValue);
typesObject[attr.name] = transformHelper.buildComponentTypeNode(attr.literalValue);
});
codegen.addStaticVar('marko_widgetTypes', builder.literal(typesObject));
codegen.addStaticVar('marko_componentTypes', builder.literal(typesObject));
return null;
};

View File

@ -19,7 +19,7 @@ module.exports = function transform(el, context) {
if (!bodyValue) {
bodyValue = builder.memberExpression(
builder.identifier('widget'),
builder.identifier('component'),
builder.identifier('b'));
includeNode.data.bodySlot = true;
@ -29,11 +29,11 @@ module.exports = function transform(el, context) {
el.appendChild(includeNode);
}
if (el.tagName === 'widget-types') {
context.setFlag('hasWidgetTypes');
if (el.tagName === 'component-types') {
context.setFlag('hasComponentTypes');
} else if (el.tagName === 'include') {
transformHelper.handleIncludeNode(el);
transformHelper.getWidgetArgs().compile(transformHelper);
transformHelper.getComponentArgs().compile(transformHelper);
return;
}
@ -42,9 +42,9 @@ module.exports = function transform(el, context) {
return;
}
if (el.hasAttribute('_widgetbind') || el.hasAttribute('w-bind')) {
el.setFlag('hasWidgetBind');
transformHelper.handleWidgetBind();
if (el.hasAttribute('_componentbind') || el.hasAttribute('w-bind')) {
el.setFlag('hasComponentBind');
transformHelper.handleComponentBind();
}
if (/* New preserve attributes */
@ -57,32 +57,32 @@ module.exports = function transform(el, context) {
el.hasAttribute('w-preserve-body') ||
el.hasAttribute('w-preserve-if') ||
el.hasAttribute('w-preserve-body-if')) {
transformHelper.handleWidgetPreserve();
transformHelper.handleComponentPreserve();
}
if (el.hasAttribute('key') || el.hasAttribute('ref') || el.hasAttribute('w-id')) {
transformHelper.assignWidgetId();
transformHelper.assignComponentId();
}
if (el.hasAttribute('for-key') || el.hasAttribute('for-ref') || el.hasAttribute('w-for')) {
transformHelper.handleWidgetFor();
transformHelper.handleComponentFor();
}
if (el.hasAttribute('w-body')) {
transformHelper.handleWidgetBody();
transformHelper.handleComponentBody();
}
// Handle w-preserve-attrs and :no-update attributes
transformHelper.handleWidgetPreserveAttrs();
transformHelper.handleComponentPreserveAttrs();
// Handle w-on* properties
transformHelper.handleWidgetEvents();
transformHelper.handleComponentEvents();
// If we need to pass any information to a nested widget then
// If we need to pass any information to a nested component then
// we start that information in the "out" so that it can be picked
// up later by the nested widget. We call this "widget args" and
// we generate compiled code that stores the widget args in the out
// for the next widget and then we also insert cleanup code to remove
// up later by the nested component. We call this "component args" and
// we generate compiled code that stores the component args in the out
// for the next component and then we also insert cleanup code to remove
// the data out of the out
transformHelper.getWidgetArgs().compile(transformHelper);
transformHelper.getComponentArgs().compile(transformHelper);
};

View File

@ -1,14 +1,14 @@
var createRendererFunc = require('../../renderer');
module.exports = function(widgetProps) {
module.exports = function(componentProps) {
var renderer = createRendererFunc(
function(data, out, widget, state) {
data.$renderBody(out, widget, state);
function(data, out, component, state) {
data.$renderBody(out, component, state);
},
widgetProps,
componentProps,
null);
return function bindWidget(renderBody, out) {
return function bindComponent(renderBody, out) {
renderer({
$renderBody: renderBody
}, out);

View File

@ -1,10 +1,10 @@
var widgetArgsHelper = module.exports = function widgetArgsHelper(
var componentArgsHelper = module.exports = function componentArgsHelper(
out,
widgetArgs) {
componentArgs) {
out.data.$w = widgetArgs;
out.data.$w = componentArgs;
};
widgetArgsHelper.cleanup = function(out) {
componentArgsHelper.cleanup = function(out) {
delete out.data.$w;
};

View File

@ -1,17 +1,17 @@
/**
* Helper method to return the WidgetDef for the current widget being rendered.
* This is, it returns the widget at the top of the widget stack.
* @param {AsyncWriter} out The current rendering context that holds info about rendered widgets.
* @return {WidgetDef} The WidgetDef instance
* Helper method to return the ComponentDef for the current component being rendered.
* This is, it returns the component at the top of the component stack.
* @param {AsyncWriter} out The current rendering context that holds info about rendered components.
* @return {ComponentDef} The ComponentDef instance
*/
module.exports = function getCurrentWidget(out) {
var widgetsContext = out.global.widgets;
var widgetStack;
module.exports = function getCurrentComponent(out) {
var componentsContext = out.global.components;
var componentStack;
var len;
if (!widgetsContext || (len = (widgetStack = widgetsContext.$__widgetStack).length) < 2) {
throw Error('No widget found');
if (!componentsContext || (len = (componentStack = componentsContext.$__componentStack).length) < 2) {
throw Error('No component found');
}
return widgetStack[len - 1];
return componentStack[len - 1];
};

View File

@ -1,5 +1,5 @@
{
"browser": {
"./getDynamicClientWidgetPath.js": "./getDynamicClientWidgetPath-browser.js"
"./getDynamicClientComponentPath.js": "./getDynamicClientComponentPath-browser.js"
}
}

View File

@ -1,5 +1,5 @@
var normalInclude = require('../../taglibs/core/include-tag');
var WidgetsContext = require('../WidgetsContext');
var ComponentsContext = require('../ComponentsContext');
var getElementById = require('../util').$__getElementById;
module.exports = function include(input, out) {
@ -14,8 +14,8 @@ module.exports = function include(input, out) {
// the existing body content in the DOM
var existingEl = getElementById(out.$__document, elId);
if (existingEl) {
var widgetsContext = WidgetsContext.$__getWidgetsContext(out);
widgetsContext.$__preserveDOMNode(elId, true /* body only */);
var componentsContext = ComponentsContext.$__getComponentsContext(out);
componentsContext.$__preserveDOMNode(elId, true /* body only */);
}
}
};

View File

@ -1,7 +1,7 @@
const INIT_WIDGET_KEY = Symbol();
var writeInitWidgetsCode = require('../').writeInitWidgetsCode;
var WidgetsContext = require('../WidgetsContext');
var writeInitComponentsCode = require('../').writeInitComponentsCode;
var ComponentsContext = require('../ComponentsContext');
module.exports = function render(input, out) {
var global = out.global;
@ -11,27 +11,27 @@ module.exports = function render(input, out) {
out.on('await:beforeRender', function(eventArgs) {
if (eventArgs.clientReorder) {
var asyncFragmentOut = eventArgs.out;
asyncFragmentOut.data.widgets = new WidgetsContext(asyncFragmentOut);
asyncFragmentOut.data.components = new ComponentsContext(asyncFragmentOut);
}
});
out.on('await:finish', function(eventArgs) {
var asyncFragmentOut = eventArgs.out;
var widgetsContext = asyncFragmentOut.data.widgets || asyncFragmentOut.global.widgets;
if (widgetsContext) {
writeInitWidgetsCode(widgetsContext, asyncFragmentOut);
var componentsContext = asyncFragmentOut.data.components || asyncFragmentOut.global.components;
if (componentsContext) {
writeInitComponentsCode(componentsContext, asyncFragmentOut);
}
});
if (out.isSync()) {
var widgetsContext = WidgetsContext.$__getWidgetsContext(out);
writeInitWidgetsCode(widgetsContext, out);
var componentsContext = ComponentsContext.$__getComponentsContext(out);
writeInitComponentsCode(componentsContext, out);
} else {
var asyncOut = out.beginAsync({ last: true, timeout: -1 });
out.onLast(function(next) {
var widgetsContext = WidgetsContext.$__getWidgetsContext(out);
writeInitWidgetsCode(widgetsContext, asyncOut);
var componentsContext = ComponentsContext.$__getComponentsContext(out);
writeInitComponentsCode(componentsContext, asyncOut);
asyncOut.end();
next();
});

View File

@ -32,10 +32,10 @@
{
"displayText": "key=\"<method>\"",
"snippet": "key=\"${1:method}\"",
"descriptionMoreURL": "http://markojs.com/docs/marko-widgets/get-started/#referencing-nested-widgets"
"descriptionMoreURL": "http://markojs.com/docs/marko-components/get-started/#referencing-nested-components"
},
{
"descriptionMoreURL": "http://markojs.com/docs/marko-widgets/get-started/#referencing-nested-widgets"
"descriptionMoreURL": "http://markojs.com/docs/marko-components/get-started/#referencing-nested-components"
}
]
},
@ -68,12 +68,12 @@
"type": "statement",
"allow-expressions": true,
"preserve-name": true,
"set-flag": "hasWidgetEvents",
"set-flag": "hasComponentEvents",
"autocomplete": [
{
"displayText": "on<event>(\"<method>\")",
"snippet": "on${1:Click}(\"handle${2:Button}${1:Click}\")",
"descriptionMoreURL": "http://markojs.com/docs/marko-widgets/get-started/#adding-dom-event-listeners"
"descriptionMoreURL": "http://markojs.com/docs/marko-components/get-started/#adding-dom-event-listeners"
}
]
},
@ -82,7 +82,7 @@
"type": "string",
"allow-expressions": true,
"preserve-name": true,
"set-flag": "hasWidgetEvents",
"set-flag": "hasComponentEvents",
"autocomplete": [],
"deprecated": true
},
@ -117,7 +117,7 @@
"preserve-name": true,
"autocomplete": [
{
"descriptionMoreURL": "http://markojs.com/docs/marko-widgets/#preserving-dom-nodes-during-re-render"
"descriptionMoreURL": "http://markojs.com/docs/marko-components/#preserving-dom-nodes-during-re-render"
}
]
},
@ -126,7 +126,7 @@
"preserve-name": true,
"autocomplete": [
{
"descriptionMoreURL": "http://markojs.com/docs/marko-widgets/#preserving-dom-nodes-during-re-render"
"descriptionMoreURL": "http://markojs.com/docs/marko-components/#preserving-dom-nodes-during-re-render"
}
]
},
@ -135,7 +135,7 @@
"autocomplete": [
{
"snippet": "no-update-if(${1:condition})",
"descriptionMoreURL": "http://markojs.com/docs/marko-widgets/#preserving-dom-nodes-during-re-render"
"descriptionMoreURL": "http://markojs.com/docs/marko-components/#preserving-dom-nodes-during-re-render"
}
]
},
@ -144,7 +144,7 @@
"autocomplete": [
{
"snippet": "no-update-body-if(${1:condition})",
"descriptionMoreURL": "http://markojs.com/docs/marko-widgets/#preserving-dom-nodes-during-re-render"
"descriptionMoreURL": "http://markojs.com/docs/marko-components/#preserving-dom-nodes-during-re-render"
}
]
},
@ -154,14 +154,14 @@
"autocomplete": [],
"deprecated": true
},
"transformer": "./widgets-transformer.js"
"transformer": "./components-transformer.js"
},
"<_widget>": {
"code-generator": "./widget-tag.js",
"<_component>": {
"code-generator": "./component-tag.js",
"autocomplete": []
},
"<init-widgets>": {
"renderer": "./init-widgets-tag.js",
"<init-components>": {
"renderer": "./init-components-tag.js",
"@immediate": "boolean"
},
"<w-preserve>": {
@ -179,8 +179,8 @@
"@body-only": "expression",
"autocomplete": []
},
"<widget-types>": {
"code-generator": "./widget-types-tag.js",
"<component-types>": {
"code-generator": "./component-types-tag.js",
"@*": "string",
"autocomplete": [],
"deprecated": true
@ -188,5 +188,5 @@
"<body>": {
"transformer": "./body-transformer.js"
},
"transformer": "./widgets-transformer.js"
"transformer": "./components-transformer.js"
}

View File

@ -1,4 +1,4 @@
var WidgetsContext = require('../WidgetsContext');
var ComponentsContext = require('../ComponentsContext');
var getElementById = require('../util').$__getElementById;
module.exports = function render(input, out) {
@ -16,7 +16,7 @@ module.exports = function render(input, out) {
if (condition !== false) {
var existingEl = getElementById(out.$__document, id);
if (existingEl) {
var widgetsContext = WidgetsContext.$__getWidgetsContext(out);
var componentsContext = ComponentsContext.$__getComponentsContext(out);
var bodyOnly = input.bodyOnly === true;
// Don't actually render anything since the element is already in the DOM,
// but keep track that the node is being preserved so that we can ignore
@ -31,7 +31,7 @@ module.exports = function render(input, out) {
out.element(tagName, { id: id });
}
widgetsContext.$__preserveDOMNode(id, bodyOnly);
componentsContext.$__preserveDOMNode(id, bodyOnly);
return;
}
}

View File

@ -4,7 +4,7 @@ var resolveFrom = tryRequire('resolve-from', require);
var nodePath = require('path');
var ok = require('assert').ok;
module.exports = function buildWidgetTypeNode(path, from, def, transformHelper) {
module.exports = function buildComponentTypeNode(path, from, def, transformHelper) {
ok(typeof path === 'string', '"path" should be a string');
ok(typeof from === 'string', '"from" should be a string');
@ -12,15 +12,15 @@ module.exports = function buildWidgetTypeNode(path, from, def, transformHelper)
var builder = context.builder;
var registerWidget = context.addStaticVar('marko_registerWidget',
builder.memberExpression(transformHelper.markoWidgetsVar, builder.identifier('rw')));
var registerComponent = context.addStaticVar('marko_registerComponent',
builder.memberExpression(transformHelper.markoComponentsVar, builder.identifier('rw')));
var typeName;
if (lassoModulesClientTransport) {
var targetPath = resolveFrom(from, path);
if (!targetPath) {
throw new Error('Widget module not found: ' + path + ' (from ' + from + ')');
throw new Error('Component module not found: ' + path + ' (from ' + from + ')');
}
typeName = lassoModulesClientTransport.getClientPath(targetPath);
} else {
@ -30,11 +30,11 @@ module.exports = function buildWidgetTypeNode(path, from, def, transformHelper)
if (!def) {
var returnValue = builder.require(builder.literal(path));
if (transformHelper.isLegacyWidget) {
var defineWidget = context.addStaticVar('marko_defineWidget',
builder.memberExpression(transformHelper.markoWidgetsVar, builder.identifier('w')));
if (transformHelper.isLegacyComponent) {
var defineComponent = context.addStaticVar('marko_defineComponent',
builder.memberExpression(transformHelper.markoComponentsVar, builder.identifier('w')));
returnValue = builder.functionCall(defineWidget, [returnValue]);
returnValue = builder.functionCall(defineComponent, [returnValue]);
}
def = builder.functionDeclaration(null, [] /* params */, [
@ -42,7 +42,7 @@ module.exports = function buildWidgetTypeNode(path, from, def, transformHelper)
]);
}
return builder.functionCall(registerWidget, [
return builder.functionCall(registerComponent, [
builder.literal(typeName),
def
]);

View File

@ -33,12 +33,12 @@ if (!setImmediate) {
/**
* This function is called when we schedule the update of "unbatched"
* updates to widgets.
* updates to components.
*/
function updateUnbatchedWidgets() {
function updateUnbatchedComponents() {
if (unbatchedQueue.length) {
try {
updateWidgets(unbatchedQueue);
updateComponents(unbatchedQueue);
} finally {
// Reset the flag now that this scheduled batch update
// is complete so that we can later schedule another
@ -57,16 +57,16 @@ function scheduleUpdates() {
updatesScheduled = true;
setImmediate(updateUnbatchedWidgets);
setImmediate(updateUnbatchedComponents);
}
function updateWidgets(queue) {
// Loop over the widgets in the queue and update them.
function updateComponents(queue) {
// Loop over the components in the queue and update them.
// NOTE: It is okay if the queue grows during the iteration
// since we will still get to them at the end
for (var i=0; i<queue.length; i++) {
var widget = queue[i];
widget.update(); // Do the actual widget update
var component = queue[i];
component.update(); // Do the actual component update
}
// Clear out the queue by setting the length to zero
@ -88,45 +88,45 @@ function batchUpdate(func) {
func();
} finally {
try {
// Update all of the widgets that where queued up
// Update all of the components that where queued up
// in this batch (if any)
if (batch.$__queue) {
updateWidgets(batch.$__queue);
updateComponents(batch.$__queue);
}
} finally {
// Now that we have completed the update of all the widgets
// Now that we have completed the update of all the components
// in this batch we need to remove it off the top of the stack
batchStack.length--;
}
}
}
function queueWidgetUpdate(widget) {
function queueComponentUpdate(component) {
var batchStackLen = batchStack.length;
if (batchStackLen) {
// When a batch update is started we push a new batch on to a stack.
// If the stack has a non-zero length then we know that a batch has
// been started so we can just queue the widget on the top batch. When
// the batch is ended this widget will be updated.
// been started so we can just queue the component on the top batch. When
// the batch is ended this component will be updated.
var batch = batchStack[batchStackLen-1];
// We default the batch queue to null to avoid creating an Array instance
// unnecessarily. If it is null then we create a new Array, otherwise
// we push it onto the existing Array queue
if (batch.$__queue) {
batch.$__queue.push(widget);
batch.$__queue.push(component);
} else {
batch.$__queue = [widget];
batch.$__queue = [component];
}
} else {
// We are not within a batched update. We need to schedule a batch update
// for the process.nextTick (if that hasn't been done already) and we will
// add the widget to the unbatched queued
// add the component to the unbatched queued
scheduleUpdates();
unbatchedQueue.push(widget);
unbatchedQueue.push(component);
}
}
exports.$__queueWidgetUpdate = queueWidgetUpdate;
exports.$__queueComponentUpdate = queueComponentUpdate;
exports.$__batchUpdate = batchUpdate;

View File

@ -1,23 +1,23 @@
var widgetLookup = {};
var componentLookup = {};
var defaultDocument = document;
function getWidgetForEl(el, doc) {
function getComponentForEl(el, doc) {
if (el) {
var node = typeof el === 'string' ? (doc || defaultDocument).getElementById(el) : el;
if (node) {
var widget = node._w;
var component = node._w;
while(widget) {
var rootFor = widget.$__rootFor;
while(component) {
var rootFor = component.$__rootFor;
if (rootFor) {
widget = rootFor;
component = rootFor;
} else {
break;
}
}
return widget;
return component;
}
}
}
@ -35,7 +35,7 @@ var lifecycleEventMethods = {};
});
/**
* This method handles invoking a widget's event handler method
* This method handles invoking a component's event handler method
* (if present) while also emitting the event through
* the standard EventEmitter.prototype.emit method.
*
@ -48,25 +48,25 @@ var lifecycleEventMethods = {};
* update --> onUpdate
* render --> onRender
*/
function emitLifecycleEvent(widget, eventType, eventArg1, eventArg2) {
var listenerMethod = widget[lifecycleEventMethods[eventType]];
function emitLifecycleEvent(component, eventType, eventArg1, eventArg2) {
var listenerMethod = component[lifecycleEventMethods[eventType]];
if (listenerMethod) {
listenerMethod.call(widget, eventArg1, eventArg2);
listenerMethod.call(component, eventArg1, eventArg2);
}
widget.emit(eventType, eventArg1, eventArg2);
component.emit(eventType, eventArg1, eventArg2);
}
function destroyWidgetForEl(el) {
var widgetToDestroy = el._w;
if (widgetToDestroy) {
widgetToDestroy.$__destroyShallow();
function destroyComponentForEl(el) {
var componentToDestroy = el._w;
if (componentToDestroy) {
componentToDestroy.$__destroyShallow();
el._w = null;
while ((widgetToDestroy = widgetToDestroy.$__rootFor)) {
widgetToDestroy.$__rootFor = null;
widgetToDestroy.$__destroyShallow();
while ((componentToDestroy = componentToDestroy.$__rootFor)) {
componentToDestroy.$__rootFor = null;
componentToDestroy.$__destroyShallow();
}
}
}
@ -74,7 +74,7 @@ function destroyElRecursive(el) {
var curChild = el.firstChild;
while(curChild) {
if (curChild.nodeType == 1) {
destroyWidgetForEl(curChild);
destroyComponentForEl(curChild);
destroyElRecursive(curChild);
}
curChild = curChild.nextSibling;
@ -83,7 +83,7 @@ function destroyElRecursive(el) {
var nextUniqueId = 0;
function nextWidgetId() {
function nextComponentId() {
return 'wc' + (nextUniqueId++);
}
@ -91,19 +91,19 @@ function getElementById(doc, id) {
return doc.getElementById(id);
}
function attachBubblingEvent(widgetDef, handlerMethodName, extraArgs) {
function attachBubblingEvent(componentDef, handlerMethodName, extraArgs) {
if (handlerMethodName) {
return extraArgs ?
[handlerMethodName, widgetDef.id, extraArgs] :
[handlerMethodName, widgetDef.id];
[handlerMethodName, componentDef.id, extraArgs] :
[handlerMethodName, componentDef.id];
}
}
exports.$__widgetLookup = widgetLookup;
exports.$__getWidgetForEl = getWidgetForEl;
exports.$__componentLookup = componentLookup;
exports.$__getComponentForEl = getComponentForEl;
exports.$__emitLifecycleEvent = emitLifecycleEvent;
exports.$__destroyWidgetForEl = destroyWidgetForEl;
exports.$__destroyComponentForEl = destroyComponentForEl;
exports.$__destroyElRecursive = destroyElRecursive;
exports.$__nextWidgetId = nextWidgetId;
exports.$__nextComponentId = nextComponentId;
exports.$__getElementById = getElementById;
exports.$__attachBubblingEvent = attachBubblingEvent;

View File

@ -2,11 +2,11 @@ var KEY = Symbol();
var isArray = Array.isArray;
function UniqueId(out) {
this.prefix = out.global.widgetIdPrefix || 'w';
this.prefix = out.global.componentIdPrefix || 'w';
this.nextId = 0;
}
function nextWidgetId(out) {
function nextComponentId(out) {
var global = out.global;
var idProvider = global[KEY] ||
@ -15,11 +15,11 @@ function nextWidgetId(out) {
return idProvider.prefix + (idProvider.nextId++);
}
function attachBubblingEvent(widgetDef, handlerMethodName, extraArgs) {
function attachBubblingEvent(componentDef, handlerMethodName, extraArgs) {
if (handlerMethodName) {
if (extraArgs) {
var bubblingDomEvents = widgetDef.$__bubblingDomEvents ||
( widgetDef.$__bubblingDomEvents = [] );
var bubblingDomEvents = componentDef.$__bubblingDomEvents ||
( componentDef.$__bubblingDomEvents = [] );
var eventIndex = bubblingDomEvents.length;
if (extraArgs.length === 1) {
@ -33,13 +33,13 @@ function attachBubblingEvent(widgetDef, handlerMethodName, extraArgs) {
bubblingDomEvents.push(extraArgs);
}
return handlerMethodName + ' ' + widgetDef.id + ' ' + eventIndex;
return handlerMethodName + ' ' + componentDef.id + ' ' + eventIndex;
} else {
return handlerMethodName + ' ' + widgetDef.id;
return handlerMethodName + ' ' + componentDef.id;
}
}
}
exports.$__nextWidgetId = nextWidgetId;
exports.$__nextComponentId = nextComponentId;
exports.$__server = true;
exports.$__attachBubblingEvent = attachBubblingEvent;

View File

@ -20,7 +20,7 @@ function defineRenderer(def) {
if (!renderer) {
// Create a renderer function that takes care of translating
// the input properties to a view state. Also, this renderer
// takes care of re-using existing widgets.
// takes care of re-using existing components.
renderer = function renderer(input, out) {
var newProps = input;

View File

@ -163,9 +163,9 @@ module.exports = {
> **Note**: When using a plain object, use the `onCreate` [lifecycle method]() instead of `contructor`.
### Split renderer & widget
### Split renderer & component
With this alternative technique to define a component, you don't have access to stateful re-rendering, but the template rendering logic will not be sent down to the browser.
Marko automatically discovers widget files in the same directory as a template. For example if you have a template named `button.marko`, it will automatically look for `button.widget.js`. If your template is named `index.marko`, it will look for `widget.js` in addition to `index.widget.js`.
Marko automatically discovers component files in the same directory as a template. For example if you have a template named `button.marko`, it will automatically look for `button.component.js`. If your template is named `index.marko`, it will look for `component.js` in addition to `index.component.js`.

View File

@ -7,7 +7,7 @@ const nodeRequire = require('../node-require');
var compiler;
var marko;
var runtime;
var widgets;
var components;
var modifiedId = 1;
var HOT_RELOAD_KEY = Symbol('HOT_RELOAD');
@ -188,4 +188,4 @@ exports.handleFileModified = function(path, options) {
compiler = require('../compiler');
marko = require('../');
runtime = require('../runtime/html');
widgets = require('../widgets');
components = require('../components');

12
jquery.js vendored
View File

@ -2,7 +2,7 @@ var ready = require('./ready');
var idRegExp = /^\#(\S+)( .*)?/;
exports.patchWidget = function(jQuery) {
exports.patchComponent = function(jQuery) {
/* globals window */
if (!jQuery) {
@ -12,7 +12,7 @@ exports.patchWidget = function(jQuery) {
}
}
require('./widgets/Widget').prototype.$ = function jqueryProxy(arg) {
require('./components/Component').prototype.$ = function jqueryProxy(arg) {
var args = arguments;
var self = this;
@ -26,16 +26,16 @@ exports.patchWidget = function(jQuery) {
var match = idRegExp.exec(arg);
//Reset the search to 0 so the next call to exec will start from the beginning for the new string
if (match != null) {
var widgetElId = match[1];
var componentElId = match[1];
if (match[2] == null) {
return jQuery(self.getEl(widgetElId));
return jQuery(self.getEl(componentElId));
} else {
return jQuery('#' + self.getElId(widgetElId) + match[2]);
return jQuery('#' + self.getElId(componentElId) + match[2]);
}
} else {
var rootEl = self.getEl();
if (!rootEl) {
throw new Error('Root element is not defined for widget');
throw new Error('Root element is not defined for component');
}
if (rootEl) {
return jQuery(arg, rootEl);

View File

@ -6,7 +6,7 @@
"template",
"async",
"streaming",
"widgets",
"components",
"components",
"ui",
"vdom",
@ -20,7 +20,7 @@
"url": "https://github.com/marko-js/marko.git"
},
"scripts": {
"test": "npm run jshint -s && npm run mocha -s && npm run test-widgets -s && npm run test-widgets-deprecated -s",
"test": "npm run jshint -s && npm run mocha -s && npm run test-components -s && npm run test-components-deprecated -s",
"mocha": "mocha --ui bdd --reporter spec ./test/",
"test-coverage": "npm run test-generate-coverage && nyc report --reporter=html && open ./coverage/index.html",
"test-generate-coverage": "nyc -asc npm run test",
@ -28,16 +28,16 @@
"test-async": "mocha --ui bdd --reporter spec ./test/async-render-test",
"test-taglib-loader": "mocha --ui bdd --reporter spec ./test/taglib-loader-test",
"test-express": "mocha --ui bdd --reporter spec ./test/express-test",
"test-widgets": "npm run test-widgets-browser -s && npm run test-widgets-pages -s",
"test-widgets-deprecated": "npm run test-widgets-browser-deprecated -s && npm run test-widgets-pages-deprecated -s",
"test-widgets-browser": "node test/browser-tests-runner/cli.js test/widgets-browser-tests.js --automated",
"test-widgets-browser-deprecated": "node test/browser-tests-runner/cli.js test/deprecated-widgets-browser-tests.js --automated && npm run test-widgets-pages-deprecated -s",
"test-widgets-pages": "node test/browser-tests-runner/cli.js --pages --automated",
"test-widgets-pages-deprecated": "node test/browser-tests-runner/cli.js --pagesDeprecated --automated",
"test-widgets-browser-dev": "browser-refresh test/browser-tests-runner/cli.js test/widgets-browser-tests.js --server",
"test-page": "node test/browser-tests-runner/cli.js test/widgets-browser-tests.js --automated --page",
"test-pages": "npm run test-widgets-pages",
"jshint": "jshint compiler/ runtime/ taglibs/ widgets/",
"test-components": "npm run test-components-browser -s && npm run test-components-pages -s",
"test-components-deprecated": "npm run test-components-browser-deprecated -s && npm run test-components-pages-deprecated -s",
"test-components-browser": "node test/browser-tests-runner/cli.js test/components-browser-tests.js --automated",
"test-components-browser-deprecated": "node test/browser-tests-runner/cli.js test/deprecated-components-browser-tests.js --automated && npm run test-components-pages-deprecated -s",
"test-components-pages": "node test/browser-tests-runner/cli.js --pages --automated",
"test-components-pages-deprecated": "node test/browser-tests-runner/cli.js --pagesDeprecated --automated",
"test-components-browser-dev": "browser-refresh test/browser-tests-runner/cli.js test/components-browser-tests.js --server",
"test-page": "node test/browser-tests-runner/cli.js test/components-browser-tests.js --automated --page",
"test-pages": "npm run test-components-pages",
"jshint": "jshint compiler/ runtime/ taglibs/ components/",
"coveralls": "nyc report --reporter=text-lcov | coveralls"
},
"author": "Patrick Steele-Idem <pnidem@gmail.com>",

View File

@ -134,8 +134,8 @@ function ready(callback, thisObj, doc) {
module.exports = ready;
module.exports.patchWidget = function() {
require('./widgets/Widget').prototype.ready = function (callback) {
module.exports.patchComponent = function() {
require('./components/Component').prototype.ready = function (callback) {
var document = this.el.ownerDocument;
ready(callback, this, document);
};

View File

@ -1,63 +1,63 @@
var domInsert = require('./dom-insert');
function checkAddedToDOM(result, method) {
if (!result.$__widgets) {
if (!result.$__components) {
throw Error('Not added to DOM');
}
}
function getWidgetDefs(result) {
var widgetDefs = result.$__widgets;
function getComponentDefs(result) {
var componentDefs = result.$__components;
if (widgetDefs.length === 0) {
throw Error('No widget');
if (componentDefs.length === 0) {
throw Error('No component');
}
return widgetDefs;
return componentDefs;
}
function RenderResult(out) {
this.out = this.$__out = out;
this.$__widgets = null;
this.$__components = null;
}
module.exports = RenderResult;
var proto = RenderResult.prototype = {
getWidget: function() {
checkAddedToDOM(this, 'getWidget');
getComponent: function() {
checkAddedToDOM(this, 'getComponent');
var rerenderWidgetInfo = this.$__out.global.$w;
var rerenderWidget = rerenderWidgetInfo && rerenderWidgetInfo[0];
if (rerenderWidget) {
return rerenderWidget;
var rerenderComponentInfo = this.$__out.global.$w;
var rerenderComponent = rerenderComponentInfo && rerenderComponentInfo[0];
if (rerenderComponent) {
return rerenderComponent;
}
return getWidgetDefs(this)[0].$__widget;
return getComponentDefs(this)[0].$__component;
},
getWidgets: function(selector) {
checkAddedToDOM(this, 'getWidgets');
getComponents: function(selector) {
checkAddedToDOM(this, 'getComponents');
var widgetDefs = getWidgetDefs(this);
var componentDefs = getComponentDefs(this);
var widgets = [];
var components = [];
var i;
for (i = 0; i < widgetDefs.length; i++) {
var widget = widgetDefs[i].$__widget;
if (!selector || selector(widget)) {
widgets.push(widget);
for (i = 0; i < componentDefs.length; i++) {
var component = componentDefs[i].$__component;
if (!selector || selector(component)) {
components.push(component);
}
}
return widgets;
return components;
},
afterInsert: function(doc) {
var out = this.$__out;
var widgetsContext = out.global.widgets;
if (widgetsContext) {
this.$__widgets = widgetsContext.$__widgets;
widgetsContext.$__initWidgets(doc);
var componentsContext = out.global.components;
if (componentsContext) {
this.$__components = componentsContext.$__components;
componentsContext.$__initComponents(doc);
}
return this;
@ -77,7 +77,7 @@ var proto = RenderResult.prototype = {
document: typeof document !== 'undefined' && document
};
// Add all of the following DOM methods to Widget.prototype:
// Add all of the following DOM methods to Component.prototype:
// - appendTo(referenceEl)
// - replace(referenceEl)
// - replaceChildrenOf(referenceEl)

View File

@ -1,7 +1,7 @@
var extend = require('raptor-util/extend');
var widgetsUtil = require('../widgets/util');
var destroyWidgetForEl = widgetsUtil.$__destroyWidgetForEl;
var destroyElRecursive = widgetsUtil.$__destroyElRecursive;
var componentsUtil = require('../components/util');
var destroyComponentForEl = componentsUtil.$__destroyComponentForEl;
var destroyElRecursive = componentsUtil.$__destroyElRecursive;
function resolveEl(el) {
if (typeof el === 'string') {
@ -16,7 +16,7 @@ function resolveEl(el) {
function beforeRemove(referenceEl) {
destroyElRecursive(referenceEl);
destroyWidgetForEl(referenceEl);
destroyComponentForEl(referenceEl);
}
module.exports = function(target, getEl, afterInsert) {

View File

@ -1,8 +1,8 @@
var expect = require('chai').expect;
module.exports = function(helpers) {
var widget = helpers.mount(require('./index'), {
var component = helpers.mount(require('./index'), {
name: 'Frank'
});
expect(widget.el.innerHTML).to.contain('Hello FRANK!');
expect(component.el.innerHTML).to.contain('Hello FRANK!');
};

View File

@ -1,3 +1,3 @@
<div class="bar" w-bind="./widget">
<div class="bar" w-bind="./component">
${data.label}
</div>

View File

@ -1,4 +1,4 @@
module.exports = require('marko/widgets/legacy').defineComponent({
module.exports = require('marko/components/legacy').defineComponent({
template: require.resolve('./template.marko'),
getInitialState: function(input) {
return {
@ -52,7 +52,7 @@ module.exports = require('marko/widgets/legacy').defineComponent({
},
handleClick: function(event) {
// Every Widget instance is also an EventEmitter instance.
// Every Component instance is also an EventEmitter instance.
// We will emit a custom "click" event when a DOM click event
// is triggered
this.emit('click', {

View File

@ -1,7 +1,7 @@
var expect = require('chai').expect;
module.exports = function(helpers) {
var widget = helpers.mount(require('./index'), { });
var component = helpers.mount(require('./index'), { });
expect(widget.sayHello('Frank')).to.equal('Hello Frank!');
expect(component.sayHello('Frank')).to.equal('Hello Frank!');
};

View File

@ -17,7 +17,7 @@ var items = [
];
module.exports = function(helpers) {
var widget = helpers.mount(require('./index'), {
var component = helpers.mount(require('./index'), {
items: items
});
@ -26,7 +26,7 @@ module.exports = function(helpers) {
expect(lookup.componentsById[0].id).to.not.equal(lookup.componentsById[1].id);
lookup.componentsById[0].emitPurchase();
expect(widget.purchaseEvents).to.deep.equal([
expect(component.purchaseEvents).to.deep.equal([
{
id: 0,
title: 'Item 1'
@ -34,7 +34,7 @@ module.exports = function(helpers) {
]);
lookup.componentsById[1].emitPurchase();
expect(widget.purchaseEvents).to.deep.equal([
expect(component.purchaseEvents).to.deep.equal([
{
id: 0,
title: 'Item 1'

View File

@ -6,7 +6,7 @@
<app-bar key="barArray[]" label="2"/>
<app-custom-events onTestEvent("handleTestEvent1") key="customEvents" />
<app-custom-events onTestEvent("handleTestEvent2") channel="customEvents-${widget.id}" />
<app-custom-events onTestEvent("handleTestEvent2") channel="customEvents-${component.id}" />
<ul>
<li for(color in ['red', 'green', 'blue']) key="colorListItems[]">${color}</li>

View File

@ -1,17 +1,17 @@
var expect = require('chai').expect;
module.exports = function(helpers) {
var widget = helpers.mount(require('./index'), {});
var component = helpers.mount(require('./index'), {});
var testEventFired = false;
widget.getWidget('bar').on('testEvent', function(a, b) {
component.getComponent('bar').on('testEvent', function(a, b) {
expect(a).to.equal('a');
expect(b).to.equal('b');
testEventFired = true;
});
widget.getWidget('bar').emitTestEvent();
component.getComponent('bar').emitTestEvent();
expect(testEventFired).to.equal(true);
};

View File

@ -1,6 +1,6 @@
module.exports = {
onMount: function() {
this.name = 'app-foo';
this.getWidget('bar').appendHtml('FOO');
this.getComponent('bar').appendHtml('FOO');
}
};

View File

@ -2,18 +2,18 @@ var expect = require('chai').expect;
module.exports = function(helpers) {
var widget = helpers.mount(require('./index'), { name: 'Frank', age: 30 });
var component = helpers.mount(require('./index'), { name: 'Frank', age: 30 });
var nameEl = widget.getEl('name');
var ageEl = widget.getEl('age');
var linkEl = widget.els[2];
var nameEl = component.getEl('name');
var ageEl = component.getEl('age');
var linkEl = component.els[2];
expect(nameEl.parentNode != null).to.equal(true);
expect(ageEl.parentNode != null).to.equal(true);
expect(linkEl.parentNode != null).to.equal(true);
widget.destroy();
component.destroy();
expect(nameEl.parentNode == null).to.equal(true);
expect(ageEl.parentNode == null).to.equal(true);

View File

@ -1,11 +1,11 @@
var expect = require('chai').expect;
module.exports = function(helpers) {
var widget = helpers.mount(require('./index'), {
var component = helpers.mount(require('./index'), {
showSimple: true
});
var simple = widget.getWidget('simple');
var simple = component.getComponent('simple');
var simpleDestroyed = false;
simple.onDestroy = function() {
@ -14,14 +14,14 @@ module.exports = function(helpers) {
expect(simple != null).to.equal(true);
widget.input = {
component.input = {
showSimple: false
};
widget.update();
component.update();
expect(simpleDestroyed).to.equal(true);
expect(simple.isDestroyed()).to.equal(true);
expect(widget.getWidget('simple') == null).to.equal(true);
expect(component.getComponent('simple') == null).to.equal(true);
};

View File

@ -1,18 +1,18 @@
var expect = require('chai').expect;
module.exports = function(helpers) {
var widget = helpers.mount(require('./index'), {
var component = helpers.mount(require('./index'), {
colors: [ 'red', 'green', 'blue' ]
});
var liEls = widget.el.querySelectorAll('li');
var liEls = component.el.querySelectorAll('li');
helpers.triggerMouseEvent(liEls[0], 'click');
expect(widget.color).to.equal('red');
expect(component.color).to.equal('red');
helpers.triggerMouseEvent(liEls[1], 'click');
expect(widget.color).to.equal('green');
expect(component.color).to.equal('green');
helpers.triggerMouseEvent(liEls[2], 'click');
expect(widget.color).to.equal('blue');
expect(component.color).to.equal('blue');
};

View File

@ -1,29 +1,29 @@
var expect = require('chai').expect;
module.exports = function(helpers) {
var widget = helpers.mount(require('./index'), {
var component = helpers.mount(require('./index'), {
colors: [ 'red', 'green', 'blue' ]
});
var liEls = widget.el.querySelectorAll('ul.primary li');
var liEls = component.el.querySelectorAll('ul.primary li');
helpers.triggerMouseEvent(liEls[0], 'click');
expect(widget.color).to.deep.equal({color: 'red', type: 'primary'});
expect(component.color).to.deep.equal({color: 'red', type: 'primary'});
helpers.triggerMouseEvent(liEls[1], 'click');
expect(widget.color).to.deep.equal({color: 'green', type: 'primary'});
expect(component.color).to.deep.equal({color: 'green', type: 'primary'});
helpers.triggerMouseEvent(liEls[2], 'click');
expect(widget.color).to.deep.equal({color: 'blue', type: 'primary'});
expect(component.color).to.deep.equal({color: 'blue', type: 'primary'});
liEls = widget.el.querySelectorAll('ul.secondary li');
liEls = component.el.querySelectorAll('ul.secondary li');
helpers.triggerMouseEvent(liEls[0], 'click');
expect(widget.color).to.deep.equal({color: 'red', type: 'secondary'});
expect(component.color).to.deep.equal({color: 'red', type: 'secondary'});
helpers.triggerMouseEvent(liEls[1], 'click');
expect(widget.color).to.deep.equal({color: 'green', type: 'secondary'});
expect(component.color).to.deep.equal({color: 'green', type: 'secondary'});
helpers.triggerMouseEvent(liEls[2], 'click');
expect(widget.color).to.deep.equal({color: 'blue', type: 'secondary'});
expect(component.color).to.deep.equal({color: 'blue', type: 'secondary'});
};

View File

@ -1,9 +1,9 @@
var expect = require('chai').expect;
module.exports = function(helpers) {
var widget = helpers.mount(require('./index'), {});
var component = helpers.mount(require('./index'), {});
expect(widget.clicked).to.equal(false);
helpers.triggerMouseEvent(widget.getEl('button'), 'click');
expect(widget.clicked).to.equal(true);
expect(component.clicked).to.equal(false);
helpers.triggerMouseEvent(component.getEl('button'), 'click');
expect(component.clicked).to.equal(true);
};

View File

@ -1,27 +1,27 @@
var expect = require('chai').expect;
module.exports = function(helpers) {
var widget = helpers.mount(require('./index'), {
var component = helpers.mount(require('./index'), {
colors: [ 'red', 'green', 'blue' ]
});
var liEls = widget.el.querySelectorAll('li');
var liEls = component.el.querySelectorAll('li');
helpers.triggerMouseEvent(liEls[0], 'mouseover');
expect(widget.mouseOverColor).to.equal('red');
expect(component.mouseOverColor).to.equal('red');
helpers.triggerMouseEvent(liEls[1], 'mouseover');
expect(widget.mouseOverColor).to.equal('green');
expect(component.mouseOverColor).to.equal('green');
helpers.triggerMouseEvent(liEls[2], 'mouseover');
expect(widget.mouseOverColor).to.equal('blue');
expect(component.mouseOverColor).to.equal('blue');
helpers.triggerMouseEvent(liEls[0], 'mouseout');
expect(widget.mouseOutColor).to.equal('red');
expect(component.mouseOutColor).to.equal('red');
helpers.triggerMouseEvent(liEls[1], 'mouseout');
expect(widget.mouseOutColor).to.equal('green');
expect(component.mouseOutColor).to.equal('green');
helpers.triggerMouseEvent(liEls[2], 'mouseout');
expect(widget.mouseOutColor).to.equal('blue');
expect(component.mouseOutColor).to.equal('blue');
};

View File

@ -1,18 +1,18 @@
var expect = require('chai').expect;
module.exports = function(helpers) {
var widget = helpers.mount(require('./index'), {
var component = helpers.mount(require('./index'), {
colors: [ 'red', 'green', 'blue' ]
});
var liEls = widget.el.querySelectorAll('li');
var liEls = component.el.querySelectorAll('li');
helpers.triggerMouseEvent(liEls[0], 'mouseover');
expect(widget.color).to.equal('red');
expect(component.color).to.equal('red');
helpers.triggerMouseEvent(liEls[1], 'mouseover');
expect(widget.color).to.equal('green');
expect(component.color).to.equal('green');
helpers.triggerMouseEvent(liEls[2], 'mouseover');
expect(widget.color).to.equal('blue');
expect(component.color).to.equal('blue');
};

View File

@ -1,30 +1,30 @@
var expect = require('chai').expect;
module.exports = function(helpers) {
var widget = helpers.mount(require('./index'), {
var component = helpers.mount(require('./index'), {
colors: ['red']
});
expect(widget.events.length).to.equal(0);
expect(component.events.length).to.equal(0);
widget.input = {
component.input = {
colors: ['red', 'blue']
};
widget.update();
component.update();
expect(widget.events.length).to.equal(1);
expect(widget.events[0].color).to.equal('blue');
expect(widget.events[0].node).to.equal(widget.el.querySelectorAll('li')[1]);
expect(component.events.length).to.equal(1);
expect(component.events[0].color).to.equal('blue');
expect(component.events[0].node).to.equal(component.el.querySelectorAll('li')[1]);
widget.input = {
component.input = {
colors: ['red', 'green', 'blue']
};
widget.update();
component.update();
expect(widget.events.length).to.equal(2);
expect(widget.events[1].color).to.equal('green');
expect(widget.events[1].node).to.equal(widget.el.querySelectorAll('li')[1]);
expect(component.events.length).to.equal(2);
expect(component.events[1].color).to.equal('green');
expect(component.events[1].node).to.equal(component.el.querySelectorAll('li')[1]);
};

View File

@ -1,32 +1,32 @@
var expect = require('chai').expect;
module.exports = function(helpers) {
var widget = helpers.mount(require('./index'), {
var component = helpers.mount(require('./index'), {
colors: ['red', 'green', 'blue']
});
expect(widget.events.length).to.equal(0);
expect(component.events.length).to.equal(0);
var finishDetach;
widget.handleDetach = function(color, event) {
component.handleDetach = function(color, event) {
expect(color).to.equal('green');
finishDetach = event.detach;
event.preventDefault();
};
widget.input = {
component.input = {
colors: ['red', 'blue']
};
widget.update();
component.update();
expect(widget.el.querySelectorAll('li').length).to.equal(3);
expect(widget.el.querySelectorAll('li')[1].innerHTML).to.contain('green');
expect(component.el.querySelectorAll('li').length).to.equal(3);
expect(component.el.querySelectorAll('li')[1].innerHTML).to.contain('green');
finishDetach();
expect(widget.el.querySelectorAll('li').length).to.equal(2);
expect(widget.el.querySelectorAll('li')[1].innerHTML).to.contain('blue');
expect(component.el.querySelectorAll('li').length).to.equal(2);
expect(component.el.querySelectorAll('li')[1].innerHTML).to.contain('blue');
};

View File

@ -1,30 +1,30 @@
var expect = require('chai').expect;
module.exports = function(helpers) {
var widget = helpers.mount(require('./index'), {
var component = helpers.mount(require('./index'), {
colors: ['red', 'green', 'blue']
});
expect(widget.events.length).to.equal(0);
expect(component.events.length).to.equal(0);
widget.input = {
component.input = {
colors: ['red', 'blue']
};
widget.update();
component.update();
expect(widget.events.length).to.equal(1);
expect(widget.events[0].color).to.equal('green');
expect(widget.events[0].node.innerHTML).to.contain('green');
expect(component.events.length).to.equal(1);
expect(component.events[0].color).to.equal('green');
expect(component.events[0].node.innerHTML).to.contain('green');
widget.input = {
component.input = {
colors: ['red']
};
widget.update();
component.update();
expect(widget.events.length).to.equal(2);
expect(widget.events[1].color).to.equal('blue');
expect(widget.events[1].node.innerHTML).to.contain('blue');
expect(component.events.length).to.equal(2);
expect(component.events[1].color).to.equal('blue');
expect(component.events[1].node.innerHTML).to.contain('blue');
};

View File

@ -6,6 +6,6 @@ module.exports = {
},
emitPressEvent: function() {
this.emit('press', { widget: this });
this.emit('press', { component: this });
}
};

View File

@ -1,15 +1,15 @@
var expect = require('chai').expect;
module.exports = function(helpers) {
var widget = helpers.mount(require('./index'), {});
var component = helpers.mount(require('./index'), {});
widget.getWidget('ok').emitPressEvent();
component.getComponent('ok').emitPressEvent();
expect(widget.pressEvent[0].type).to.equal('ok');
expect(widget.pressEvent[1].widget).to.equal(widget.getWidget('ok'));
expect(component.pressEvent[0].type).to.equal('ok');
expect(component.pressEvent[1].component).to.equal(component.getComponent('ok'));
widget.getWidget('cancel').emitPressEvent();
component.getComponent('cancel').emitPressEvent();
expect(widget.pressEvent[0].type).to.equal('cancel');
expect(widget.pressEvent[1].widget).to.equal(widget.getWidget('cancel'));
expect(component.pressEvent[0].type).to.equal('cancel');
expect(component.pressEvent[1].component).to.equal(component.getComponent('cancel'));
};

View File

@ -1,23 +1,23 @@
var expect = require('chai').expect;
module.exports = function(helpers) {
var widget = helpers.mount(require('./index'), {});
var component = helpers.mount(require('./index'), {});
expect(widget.buttonClickCalls.length).to.equal(0);
expect(component.buttonClickCalls.length).to.equal(0);
helpers.triggerClick(widget.getEl('ok'));
helpers.triggerClick(component.getEl('ok'));
expect(widget.buttonClickCalls.length).to.equal(1);
expect(component.buttonClickCalls.length).to.equal(1);
expect(widget.buttonClickCalls[0][0]).to.equal('ok');
expect(widget.buttonClickCalls[0][1].stopPropagation).to.be.a('function');
expect(widget.buttonClickCalls[0][2].innerHTML).to.equal('OK');
expect(component.buttonClickCalls[0][0]).to.equal('ok');
expect(component.buttonClickCalls[0][1].stopPropagation).to.be.a('function');
expect(component.buttonClickCalls[0][2].innerHTML).to.equal('OK');
helpers.triggerClick(widget.getEl('cancel'));
helpers.triggerClick(component.getEl('cancel'));
expect(widget.buttonClickCalls.length).to.equal(2);
expect(component.buttonClickCalls.length).to.equal(2);
expect(widget.buttonClickCalls[1][0]).to.equal('cancel');
expect(widget.buttonClickCalls[1][1].stopPropagation).to.be.a('function');
expect(widget.buttonClickCalls[1][2].innerHTML).to.equal('Cancel');
expect(component.buttonClickCalls[1][0]).to.equal('cancel');
expect(component.buttonClickCalls[1][1].stopPropagation).to.be.a('function');
expect(component.buttonClickCalls[1][2].innerHTML).to.equal('Cancel');
};

View File

@ -1,23 +1,23 @@
var expect = require('chai').expect;
module.exports = function(helpers) {
var widget = helpers.mount(require('./index'), {});
var component = helpers.mount(require('./index'), {});
expect(widget.buttonClickCalls.length).to.equal(0);
expect(component.buttonClickCalls.length).to.equal(0);
helpers.triggerClick(widget.getEl('ok'));
helpers.triggerClick(component.getEl('ok'));
expect(widget.buttonClickCalls.length).to.equal(1);
expect(component.buttonClickCalls.length).to.equal(1);
expect(widget.buttonClickCalls[0][0]).to.equal('ok');
expect(widget.buttonClickCalls[0][1].stopPropagation).to.be.a('function');
expect(widget.buttonClickCalls[0][2].innerHTML).to.equal('OK');
expect(component.buttonClickCalls[0][0]).to.equal('ok');
expect(component.buttonClickCalls[0][1].stopPropagation).to.be.a('function');
expect(component.buttonClickCalls[0][2].innerHTML).to.equal('OK');
helpers.triggerClick(widget.getEl('cancel'));
helpers.triggerClick(component.getEl('cancel'));
expect(widget.buttonClickCalls.length).to.equal(2);
expect(component.buttonClickCalls.length).to.equal(2);
expect(widget.buttonClickCalls[1][0]).to.equal('cancel');
expect(widget.buttonClickCalls[1][1].stopPropagation).to.be.a('function');
expect(widget.buttonClickCalls[1][2].innerHTML).to.equal('Cancel');
expect(component.buttonClickCalls[1][0]).to.equal('cancel');
expect(component.buttonClickCalls[1][1].stopPropagation).to.be.a('function');
expect(component.buttonClickCalls[1][2].innerHTML).to.equal('Cancel');
};

View File

@ -1,19 +1,19 @@
var expect = require('chai').expect;
module.exports = function(helpers) {
var widget = helpers.mount(require('./index'), {});
var component = helpers.mount(require('./index'), {});
expect(widget.mouseMoveEvent).to.equal(undefined);
expect(component.mouseMoveEvent).to.equal(undefined);
helpers.triggerMouseMove(widget.getEl('ok'));
helpers.triggerMouseMove(component.getEl('ok'));
expect(widget.mouseMoveEvent[0]).to.equal('ok');
expect(widget.mouseMoveEvent[1].stopPropagation).to.be.a('function');
expect(widget.mouseMoveEvent[2].innerHTML).to.equal('OK');
expect(component.mouseMoveEvent[0]).to.equal('ok');
expect(component.mouseMoveEvent[1].stopPropagation).to.be.a('function');
expect(component.mouseMoveEvent[2].innerHTML).to.equal('OK');
helpers.triggerMouseMove(widget.getEl('cancel'));
helpers.triggerMouseMove(component.getEl('cancel'));
expect(widget.mouseMoveEvent[0]).to.equal('cancel');
expect(widget.mouseMoveEvent[1].stopPropagation).to.be.a('function');
expect(widget.mouseMoveEvent[2].innerHTML).to.equal('Cancel');
expect(component.mouseMoveEvent[0]).to.equal('cancel');
expect(component.mouseMoveEvent[1].stopPropagation).to.be.a('function');
expect(component.mouseMoveEvent[2].innerHTML).to.equal('Cancel');
};

View File

@ -9,7 +9,7 @@ module.exports = {
},
handleClick: function(event) {
// Every Widget instance is also an EventEmitter instance.
// Every Component instance is also an EventEmitter instance.
// We will emit a custom "click" event when a DOM click event
// is triggered
this.emit('click', {

View File

@ -1,8 +1,8 @@
var expect = require('chai').expect;
var markoWidgets = require('marko/widgets');
var markoComponents = require('marko/components');
module.exports = function(helpers) {
var checkboxWidget = helpers.mount(require('./components/app-checkbox'), {
var checkboxComponent = helpers.mount(require('./components/app-checkbox'), {
checked: true,
'class': 'my-checkbox',
data: 123
@ -11,7 +11,7 @@ module.exports = function(helpers) {
var el = helpers.targetEl.querySelector('.my-checkbox');
expect(el != null).to.equal(true);
var widgetForEl = markoWidgets.getWidgetForEl(el);
var componentForEl = markoComponents.getComponentForEl(el);
expect(widgetForEl).to.equal(checkboxWidget);
expect(componentForEl).to.equal(checkboxComponent);
};

View File

@ -1,4 +1,4 @@
module.exports = function(helpers, done) {
var widget = helpers.mount(require('./index.marko'), {});
widget.test(done);
var component = helpers.mount(require('./index.marko'), {});
component.test(done);
};

View File

@ -1,20 +1,20 @@
var expect = require('chai').expect;
module.exports = function(helpers) {
var widget = helpers.mount(require('./index'), {
var component = helpers.mount(require('./index'), {
name: 'Frank',
index: 0
});
var fooWidget = widget.getWidget('foo');
var fooComponent = component.getComponent('foo');
expect(fooWidget.el.querySelector('.body').innerHTML).to.equal('Current index: 0');
expect(fooWidget.el.querySelector('span').innerHTML).to.equal('Hello Frank!');
expect(fooComponent.el.querySelector('.body').innerHTML).to.equal('Current index: 0');
expect(fooComponent.el.querySelector('span').innerHTML).to.equal('Hello Frank!');
fooWidget.state.name = 'Jane';
fooComponent.state.name = 'Jane';
fooWidget.update();
fooComponent.update();
expect(fooWidget.el.querySelector('.body').innerHTML).to.equal('Current index: 0');
expect(fooWidget.el.querySelector('span').innerHTML).to.equal('Hello Jane!');
expect(fooComponent.el.querySelector('.body').innerHTML).to.equal('Current index: 0');
expect(fooComponent.el.querySelector('span').innerHTML).to.equal('Hello Jane!');
};

View File

@ -1,10 +1,10 @@
var expect = require('chai').expect;
module.exports = function(helpers) {
var widget = helpers.mount(require('./index.marko'));
var component = helpers.mount(require('./index.marko'));
var firstCheckbox = widget.getEl('first');
var secondCheckbox = widget.getEl('second');
var firstCheckbox = component.getEl('first');
var secondCheckbox = component.getEl('second');
expect(firstCheckbox.checked).to.equal(true);
expect(secondCheckbox.checked).to.equal(false);

View File

@ -1,31 +1,31 @@
var expect = require('chai').expect;
module.exports = function(helpers) {
var widget = helpers.mount(require('./index.marko'), {
var component = helpers.mount(require('./index.marko'), {
name: 'Frank'
});
expect(widget.el.querySelector('.render-count').innerHTML).to.equal('0');
expect(widget.el.querySelector('.name').innerHTML).to.equal('Frank');
expect(component.el.querySelector('.render-count').innerHTML).to.equal('0');
expect(component.el.querySelector('.name').innerHTML).to.equal('Frank');
// Rerender with a new props object that has the shallow properties
widget.input = {
component.input = {
name: 'Frank'
};
widget.update();
component.update();
expect(widget.el.querySelector('.render-count').innerHTML).to.equal('0');
expect(widget.el.querySelector('.name').innerHTML).to.equal('Frank');
expect(component.el.querySelector('.render-count').innerHTML).to.equal('0');
expect(component.el.querySelector('.name').innerHTML).to.equal('Frank');
// Rerender with a new props object that has the shallow properties
widget.input = {
component.input = {
name: 'John'
};
widget.update();
component.update();
expect(widget.el.querySelector('.render-count').innerHTML).to.equal('1');
expect(widget.el.querySelector('.name').innerHTML).to.equal('John');
expect(component.el.querySelector('.render-count').innerHTML).to.equal('1');
expect(component.el.querySelector('.name').innerHTML).to.equal('John');
};

View File

@ -1,31 +1,31 @@
var expect = require('chai').expect;
module.exports = function(helpers) {
var widget = helpers.mount(require('./index.marko'), {
var component = helpers.mount(require('./index.marko'), {
name: 'Frank'
});
expect(widget.getWidget('foo').el.querySelector('.render-count').innerHTML).to.equal('0');
expect(widget.getWidget('foo').el.querySelector('.name').innerHTML).to.equal('Frank');
expect(component.getComponent('foo').el.querySelector('.render-count').innerHTML).to.equal('0');
expect(component.getComponent('foo').el.querySelector('.name').innerHTML).to.equal('Frank');
// Rerender with a new props object that has the shallow properties
widget.input = {
component.input = {
name: 'Frank'
};
widget.update();
component.update();
expect(widget.getWidget('foo').el.querySelector('.render-count').innerHTML).to.equal('0');
expect(widget.getWidget('foo').el.querySelector('.name').innerHTML).to.equal('Frank');
expect(component.getComponent('foo').el.querySelector('.render-count').innerHTML).to.equal('0');
expect(component.getComponent('foo').el.querySelector('.name').innerHTML).to.equal('Frank');
// Rerender with a new props object that has the shallow properties
widget.input = {
component.input = {
name: 'John'
};
widget.update();
component.update();
expect(widget.getWidget('foo').el.querySelector('.render-count').innerHTML).to.equal('1');
expect(widget.getWidget('foo').el.querySelector('.name').innerHTML).to.equal('John');
expect(component.getComponent('foo').el.querySelector('.render-count').innerHTML).to.equal('1');
expect(component.getComponent('foo').el.querySelector('.name').innerHTML).to.equal('John');
};

View File

@ -1,31 +1,31 @@
var expect = require('chai').expect;
module.exports = function(helpers) {
var widget = helpers.mount(require('./index.marko'), {
var component = helpers.mount(require('./index.marko'), {
name: 'Frank'
});
expect(widget.el.querySelector('.render-count').innerHTML).to.equal('0');
expect(widget.el.querySelector('.name').innerHTML).to.equal('Frank');
expect(component.el.querySelector('.render-count').innerHTML).to.equal('0');
expect(component.el.querySelector('.name').innerHTML).to.equal('Frank');
// Rerender with a new props object that has the shallow properties
widget.input = {
component.input = {
name: 'Frank'
};
widget.update();
component.update();
expect(widget.el.querySelector('.render-count').innerHTML).to.equal('0');
expect(widget.el.querySelector('.name').innerHTML).to.equal('Frank');
expect(component.el.querySelector('.render-count').innerHTML).to.equal('0');
expect(component.el.querySelector('.name').innerHTML).to.equal('Frank');
// Rerender with a new props object that has the shallow properties
widget.input = {
component.input = {
name: 'John'
};
widget.update();
component.update();
expect(widget.el.querySelector('.render-count').innerHTML).to.equal('1');
expect(widget.el.querySelector('.name').innerHTML).to.equal('John');
expect(component.el.querySelector('.render-count').innerHTML).to.equal('1');
expect(component.el.querySelector('.name').innerHTML).to.equal('John');
};

View File

@ -1,12 +1,12 @@
var expect = require('chai').expect;
module.exports = function(helpers) {
var widget = helpers.mount(require('./index.marko'));
var component = helpers.mount(require('./index.marko'));
expect(widget.getEl('searchInput').value).to.equal('');
expect(component.getEl('searchInput').value).to.equal('');
widget.increment();
widget.update();
component.increment();
component.update();
expect(widget.getEl('searchInput').value).to.equal('');
expect(component.getEl('searchInput').value).to.equal('');
};

View File

@ -1,31 +1,31 @@
var expect = require('chai').expect;
module.exports = function(helpers) {
var widget = helpers.mount(require('./index.marko'), {
var component = helpers.mount(require('./index.marko'), {
color:'red'
});
expect(widget.el.getAttribute('style')).to.equal('color:red;');
expect(widget.getWidget('counter').el.getAttribute('style')).to.equal('color:red;');
expect(widget.getWidget('counter').el.querySelector('.count').innerHTML).to.equal('0');
expect(component.el.getAttribute('style')).to.equal('color:red;');
expect(component.getComponent('counter').el.getAttribute('style')).to.equal('color:red;');
expect(component.getComponent('counter').el.querySelector('.count').innerHTML).to.equal('0');
widget.getWidget('counter').increment();
widget.getWidget('counter').update();
component.getComponent('counter').increment();
component.getComponent('counter').update();
expect(widget.el.getAttribute('style')).to.equal('color:red;');
expect(widget.getWidget('counter').el.getAttribute('style')).to.equal('color:red;');
expect(widget.getWidget('counter').el.querySelector('.count').innerHTML).to.equal('1');
expect(component.el.getAttribute('style')).to.equal('color:red;');
expect(component.getComponent('counter').el.getAttribute('style')).to.equal('color:red;');
expect(component.getComponent('counter').el.querySelector('.count').innerHTML).to.equal('1');
widget.updateColor('green');
widget.update();
component.updateColor('green');
component.update();
expect(widget.el.getAttribute('style')).to.equal('color:green;');
expect(widget.getWidget('counter').el.getAttribute('style')).to.equal('color:green;');
expect(widget.getWidget('counter').el.querySelector('.count').innerHTML).to.equal('1');
expect(component.el.getAttribute('style')).to.equal('color:green;');
expect(component.getComponent('counter').el.getAttribute('style')).to.equal('color:green;');
expect(component.getComponent('counter').el.querySelector('.count').innerHTML).to.equal('1');
//
// expect(widget.el.style.color).to.equal('#09c;');
// expect(widget.getWidget('counter').el.style.color).to.equal('#09c;');
// expect(component.el.style.color).to.equal('#09c;');
// expect(component.getComponent('counter').el.style.color).to.equal('#09c;');
//
// expect(widget.getEl('current').getAttribute('style')).to.equal('color:#09c;');
// expect(component.getEl('current').getAttribute('style')).to.equal('color:#09c;');
};

View File

@ -1,14 +1,14 @@
var expect = require('chai').expect;
module.exports = function(helpers) {
var widget = helpers.mount(require('./index.marko'), {
var component = helpers.mount(require('./index.marko'), {
color:'#09c'
});
expect(widget.getEl('current').getAttribute('style')).to.equal('color:#09c;');
expect(component.getEl('current').getAttribute('style')).to.equal('color:#09c;');
widget.increment();
widget.update();
component.increment();
component.update();
expect(widget.getEl('current').getAttribute('style')).to.equal('color:#09c;');
expect(component.getEl('current').getAttribute('style')).to.equal('color:#09c;');
};

View File

@ -1,14 +1,14 @@
var expect = require('chai').expect;
module.exports = function(helpers) {
var widget = helpers.mount(require('./index.marko'), {
var component = helpers.mount(require('./index.marko'), {
value: 1
});
expect(widget.getEl('input').value).to.equal('1');
expect(component.getEl('input').value).to.equal('1');
widget.state.value = 0;
widget.update();
component.state.value = 0;
component.update();
expect(widget.getEl('input').value).to.equal('0');
expect(component.getEl('input').value).to.equal('0');
};

View File

@ -1,19 +1,19 @@
var expect = require('chai').expect;
module.exports = function(helpers) {
var widget = helpers.mount(require('./index'), { name: 'Frank' });
expect(widget.el.querySelector('.name').innerHTML).to.equal('Frank');
expect(widget.onInputCalls).to.deep.equal([
var component = helpers.mount(require('./index'), { name: 'Frank' });
expect(component.el.querySelector('.name').innerHTML).to.equal('Frank');
expect(component.onInputCalls).to.deep.equal([
{
name: 'INITIAL'
}
]);
expect(widget.name).to.equal('Frank');
expect(component.name).to.equal('Frank');
widget.input = { name: 'John' };
widget.update();
component.input = { name: 'John' };
component.update();
expect(widget.onInputCalls).to.deep.equal([
expect(component.onInputCalls).to.deep.equal([
{
name: 'INITIAL'
},
@ -22,6 +22,6 @@ module.exports = function(helpers) {
}
]);
expect(widget.el.querySelector('.name').innerHTML).to.equal('John');
expect(widget.name).to.equal('John');
expect(component.el.querySelector('.name').innerHTML).to.equal('John');
expect(component.name).to.equal('John');
};

View File

@ -2,9 +2,9 @@ var expect = require('chai').expect;
var hooks = require('./hooks');
module.exports = function(helpers) {
var widget = helpers.mount(require('./index'), { name: 'Frank' });
var component = helpers.mount(require('./index'), { name: 'Frank' });
widget.destroy();
component.destroy();
expect(hooks.getHookNames()).deep.equal(['root:destroy', 'foo:destroy']);
};

Some files were not shown because too many files have changed in this diff Show More