mirror of
https://github.com/marko-js/marko.git
synced 2025-12-08 19:26:05 +00:00
128 lines
3.7 KiB
JavaScript
128 lines
3.7 KiB
JavaScript
var events = require('./events');
|
|
var dom = require('./dom');
|
|
|
|
function checkAddedToDOM(asyncStream, method) {
|
|
if (!asyncStream.data._added) {
|
|
throw new Error('Cannot call ' + method + '() until after HTML fragment is added to DOM.');
|
|
}
|
|
}
|
|
|
|
function getWidgetDefs(asyncStream) {
|
|
var widgetDefs = asyncStream.data.widgets;
|
|
|
|
if (!widgetDefs || widgetDefs.length === 0) {
|
|
throw new Error('No widget rendered');
|
|
}
|
|
return widgetDefs;
|
|
}
|
|
|
|
module.exports = {
|
|
getWidget: function() {
|
|
checkAddedToDOM(this, 'getWidget');
|
|
|
|
var rerenderWidget = this.global.__rerenderWidget;
|
|
if (rerenderWidget) {
|
|
return rerenderWidget;
|
|
}
|
|
|
|
return getWidgetDefs(this)[0].widget;
|
|
},
|
|
getWidgets: function(selector) {
|
|
checkAddedToDOM(this, 'getWidgets');
|
|
|
|
var widgetDefs = getWidgetDefs(this);
|
|
|
|
var widgets;
|
|
var i;
|
|
if (selector) {
|
|
// use the selector to find the widgets that the caller wants
|
|
widgets = [];
|
|
for (i = 0; i < widgetDefs.length; i++) {
|
|
var widget = widgetDefs[i].widget;
|
|
if (selector(widget)) {
|
|
widgets.push(widget);
|
|
}
|
|
}
|
|
} else {
|
|
// return all widgets
|
|
widgets = new Array(widgetDefs.length);
|
|
for (i = 0; i < widgetDefs.length; i++) {
|
|
widgets[i] = widgetDefs[i].widget;
|
|
}
|
|
}
|
|
return widgets;
|
|
},
|
|
|
|
afterInsert: function(node) {
|
|
var data = this.data;
|
|
data._added = true;
|
|
|
|
var widgetsContext = this.global.widgets;
|
|
var widgetDefs = widgetsContext ? widgetsContext.widgets : null;
|
|
|
|
data.widgets = widgetDefs;
|
|
|
|
events.emit('mountNode', {
|
|
node: node,
|
|
out: this,
|
|
document: node.ownerDocument
|
|
}); // NOTE: This will trigger widgets to be initialized if there were any
|
|
|
|
return this;
|
|
},
|
|
|
|
then: function(fn, fnErr) {
|
|
var self = this;
|
|
var promise = new Promise(function(resolve, reject) {
|
|
self.on('error', reject);
|
|
self.on('finish', function(data) {
|
|
try {
|
|
resolve(fn(data));
|
|
} catch(err) {
|
|
reject(err);
|
|
}
|
|
});
|
|
});
|
|
|
|
if (fnErr) {
|
|
promise = promise.catch(fnErr);
|
|
}
|
|
return promise;
|
|
},
|
|
|
|
catch: function(fnErr) {
|
|
return this.then(undefined, fnErr);
|
|
},
|
|
|
|
appendTo: function(referenceEl) {
|
|
var newNode = this.getNode(referenceEl.ownerDocument);
|
|
dom.appendTo(newNode, referenceEl);
|
|
return this.afterInsert(newNode);
|
|
},
|
|
replace: function(referenceEl) {
|
|
var newNode = this.getNode(referenceEl.ownerDocument);
|
|
dom.replace(newNode, referenceEl);
|
|
return this.afterInsert(newNode);
|
|
},
|
|
replaceChildrenOf: function(referenceEl) {
|
|
var newNode = this.getNode(referenceEl.ownerDocument);
|
|
dom.replaceChildrenOf(newNode, referenceEl);
|
|
return this.afterInsert(newNode);
|
|
},
|
|
insertBefore: function(referenceEl) {
|
|
var newNode = this.getNode(referenceEl.ownerDocument);
|
|
dom.insertBefore(newNode, referenceEl);
|
|
return this.afterInsert(newNode);
|
|
},
|
|
insertAfter: function(referenceEl) {
|
|
var newNode = this.getNode(referenceEl.ownerDocument);
|
|
dom.insertAfter(newNode, referenceEl);
|
|
return this.afterInsert(newNode);
|
|
},
|
|
prependTo: function(referenceEl) {
|
|
var newNode = this.getNode(referenceEl.ownerDocument);
|
|
dom.prependTo(newNode, referenceEl);
|
|
return this.afterInsert(newNode);
|
|
},
|
|
document: typeof document !== 'undefined' && document
|
|
}; |