A.HTMLScreen = A.Base.create('htmlScreen', A.Screen, [], {
/**
* Holds the IO request.
*
* @property _request
* @type {Object}
* @protected
*/
_request: null,
/**
* Aborts any outstanding request.
*
* @method abortRequest
*/
abortRequest: function() {
if (this._request) {
this._request.abort();
}
},
/**
* Returns content for given surface from the provided content.
*
* @method getSurfaceContent
* @param {String} surfaceId The ID of the surface, which content should be
* loaded.
* @contents {Node} The content container from which the surface content
* will be retrieved.
* @return {String|Node} String or Node instance which contains the content
* of the surface.
*/
getSurfaceContent: function(surfaceId, contents) {
var frag = contents.one('#' + surfaceId);
if (frag) {
return frag.getHTML();
}
},
/**
* Loads the content for all surfaces in one AJAX request from the server.
*
* @method load
* @return {CancellablePromise} Promise, which should be resolved with the
* returned content from the server.
*/
load: function(path) {
var cache = this.getCache(),
url;
if (A.Lang.isValue(cache)) {
return A.CancellablePromise.resolve(cache);
}
url = new A.Url(path);
url.addParameters(this.get('urlParams'));
return this.loadContent(url.toString());
},
/**
* Loads the content from server via single AJAX request.
*
* @method loadContent
* @protected
* @return {CancellablePromise} Promise, which should be resolved with the returned
* content from the server.
*/
loadContent: function(path) {
var instance = this,
promise;
instance.abortRequest();
promise = new A.CancellablePromise(
function(resolve) {
var params = {
headers: {
'X-PJAX': 'true'
},
method: instance.get('method'),
on: {
failure: function(id, response) {
promise.cancel(response.responseText);
},
success: function(id, response) {
var frag = A.Node.create('<div/>');
frag.append(response.responseText);
instance._setScreenTitleFromFragment(frag);
instance.addCache(frag);
resolve(frag);
}
},
timeout: instance.get('timeout')
};
// For Internet Explorer and MSIE don't rely on the caching mechanism
// http://www.greenvilleweb.us/how-to-web-design/problem-with-ie-9-caching-ajax-get-request/
if (A.UA.edge || A.UA.ie) {
params.cache = false;
}
instance._request = A.io(path, params);
},
function() {
instance.abortRequest();
}
);
return promise;
},
/**
* Setter for urlParams attribute.
*
* @method _setUrlParams
* @protected
* @return {String|Object} If the provided value was string, it will be
* converted to Object with one property - the provided string and "1"
* as value. Otherwise, the provided object will be passed directly to
* the attribute value.
*/
_setUrlParams: function(val) {
var params = val;
if (A.Lang.isString(val)) {
params = {};
params[val] = 1;
}
return params;
},
/**
* Retrieves the title from the provided content and sets it to title
* attribute of the class.
*
* @method _setScreenTitleFromFragment
* @param {Node} frag The container from which the title should be
* retrieve.
*/
_setScreenTitleFromFragment: function(frag) {
var title = frag.one(this.get('titleSelector'));
if (title) {
this.set('title', title.get('text'));
}
},
/**
* Validates the value of urlParams. The value could be String or Object
* with key and values. During URL construction, they will be added to the
* other parameters.
*
* @method _validateUrlParams
* @protected
* @return {Boolean} true if val is String or an Object.
*/
_validateUrlParams: function(val) {
return A.Lang.isString(val) || A.Lang.isObject(val);
}
}, {
ATTRS: {
/**
* @attribute cacheable
* @default true
* @type Boolean
*/
cacheable: {
value: true
},
/**
* Ajax request method.
*
* @attribute method
* @type {String}
* @default GET
**/
method: {
validator: A.Lang.isString,
value: 'GET'
},
/**
* CSS selector used to extract a page title from the content of a page
* loaded via Pjax.
*
* By default this is set to extract the title from the `<title>`
* element, but you could customize it to extract the title from an
* `<h1>`, or from any other element, if that's more appropriate for the
* content you're loading.
*
* @attribute titleSelector
* @type String
* @default "title"
**/
titleSelector: {
value: 'title'
},
/**
* Time in milliseconds after which an Ajax request should time out.
*
* @attribute timeout
* @type {Number}
* @default 30000
**/
timeout: {
value: 30000
},
/**
* Could be String or Object with multiple keys and values. If String,
* the defaule value will be "1". If an Object with multiple keys and
* values, they will be concatenated to the URL.
*
* @attribute urlParams
* @type {String|Object}
* @default pjax
*/
urlParams: {
setter: '_setUrlParams',
validator: '_validateUrlParams',
value: 'pjax'
}
}
});