mirror of
https://github.com/Mibew/mibew.git
synced 2025-04-25 15:56:07 +03:00
parent
120abce028
commit
7fde2eb9cd
@ -72,6 +72,14 @@ chat_user_mail_send:
|
|||||||
token: \d{1,10}
|
token: \d{1,10}
|
||||||
methods: [POST]
|
methods: [POST]
|
||||||
|
|
||||||
|
chat_user_popup_style:
|
||||||
|
path: /chat/style/popup/{style}
|
||||||
|
defaults:
|
||||||
|
_controller: Mibew\Controller\Chat\StyleController::loadPopupStyleAction
|
||||||
|
style: ""
|
||||||
|
requirements:
|
||||||
|
style: "[0-9A-Za-z_]*"
|
||||||
|
|
||||||
chat_user_start:
|
chat_user_start:
|
||||||
path: /chat
|
path: /chat
|
||||||
defaults:
|
defaults:
|
||||||
|
@ -59,7 +59,7 @@
|
|||||||
}],
|
}],
|
||||||
function(args){
|
function(args){
|
||||||
if (args.closed) {
|
if (args.closed) {
|
||||||
window.close();
|
Mibew.Utils.closeChatPopup();
|
||||||
} else {
|
} else {
|
||||||
// Something went wrong. Display error message
|
// Something went wrong. Display error message
|
||||||
Mibew.Objects.Models.Status.message.setMessage(
|
Mibew.Objects.Models.Status.message.setMessage(
|
||||||
|
@ -188,6 +188,15 @@
|
|||||||
|
|
||||||
models.soundManager = new Mibew.Models.ChatSoundManager();
|
models.soundManager = new Mibew.Models.ChatSoundManager();
|
||||||
|
|
||||||
|
// If the chat is ran inside an iframe we need to tell the parent page
|
||||||
|
// that the chat is started. This is needed to reopen chat when the user
|
||||||
|
// navigates to another page.
|
||||||
|
if (!models.user.get('isAgent') && options.links.chat) {
|
||||||
|
if (window.parent && window.parent.postMessage && (window.parent !== window)) {
|
||||||
|
window.parent.postMessage('mibew-chat-started:' + window.name + ':' + options.links.chat, '*');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: May be move it somewhere else
|
// TODO: May be move it somewhere else
|
||||||
// Periodically call update function at the server side
|
// Periodically call update function at the server side
|
||||||
periodicallyCalled.push(
|
periodicallyCalled.push(
|
||||||
|
43
src/mibew/js/source/chat/utils.js
Normal file
43
src/mibew/js/source/chat/utils.js
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/*!
|
||||||
|
* This file is a part of Mibew Messenger.
|
||||||
|
*
|
||||||
|
* Copyright 2005-2014 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function(Mibew){
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @namespace Holds utility functions
|
||||||
|
*/
|
||||||
|
Mibew.Utils = Mibew.Utils || {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes chat window.
|
||||||
|
*
|
||||||
|
* The method helps to close chat popup no mater how it's implemented
|
||||||
|
* (iframe or window).
|
||||||
|
*/
|
||||||
|
Mibew.Utils.closeChatPopup = function() {
|
||||||
|
if (window.parent && (window.parent !== window) && window.parent.postMessage) {
|
||||||
|
// It seems that the chat is working in an iframe. Tell the parent
|
||||||
|
// window that the chat is stoped so it could close the iframe.
|
||||||
|
window.parent.postMessage('mibew-chat-closed:' + window.name, '*');
|
||||||
|
} else {
|
||||||
|
// Just close the window.
|
||||||
|
window.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
})(Mibew);
|
460
src/mibew/js/source/chat_popup.js
Normal file
460
src/mibew/js/source/chat_popup.js
Normal file
@ -0,0 +1,460 @@
|
|||||||
|
/*!
|
||||||
|
* This file is a part of Mibew Messenger.
|
||||||
|
*
|
||||||
|
* Copyright 2005-2014 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @namespace Holds all Mibew functionality
|
||||||
|
*/
|
||||||
|
var Mibew = Mibew || {};
|
||||||
|
|
||||||
|
(function(Mibew) {
|
||||||
|
if (Mibew.ChatPopup) {
|
||||||
|
// It seems that this file was already loaded. We do not need to do the
|
||||||
|
// job twice.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @namespace Holds all functionality related with chat popups
|
||||||
|
*/
|
||||||
|
Mibew.ChatPopup = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @namespace Holds objects instances
|
||||||
|
*/
|
||||||
|
Mibew.Objects = Mibew.Objects || {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @namespace Holds all popups instances.
|
||||||
|
*/
|
||||||
|
Mibew.Objects.ChatPopups = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @namespace Holds utility functions
|
||||||
|
*/
|
||||||
|
Mibew.Utils = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a cookie for the second level domain with path equals to '/'.
|
||||||
|
*
|
||||||
|
* @param {String} name Cookie name
|
||||||
|
* @param {String} value Cookie value
|
||||||
|
* @param {Date} expires Indicates when the cookie expires. If the value is
|
||||||
|
* omitted a session cookie will be created.
|
||||||
|
*/
|
||||||
|
Mibew.Utils.createCookie = function(name, value, expires) {
|
||||||
|
var domain = /([^\.]+\.[^\.]+)$/.exec(document.location.hostname);
|
||||||
|
document.cookie = "" + name + "=" + value + "; "
|
||||||
|
+ "path=/; "
|
||||||
|
+ (domain ? ("domain=" + domain[1] + "; ") : '')
|
||||||
|
+ (expires ? ('expires=' + expires.toUTCString() + '; ') : '');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try to read cookie.
|
||||||
|
*
|
||||||
|
* @param {String} name Cookie name
|
||||||
|
* @returns {String|Boolean} Cookie value or boolean false if cookie with
|
||||||
|
* specified name does not exist
|
||||||
|
*/
|
||||||
|
Mibew.Utils.readCookie = function(name) {
|
||||||
|
var cookies = document.cookie.split('; ');
|
||||||
|
var nameForSearch = name + '=';
|
||||||
|
var value = false;
|
||||||
|
for (var i = 0; i < cookies.length; i++) {
|
||||||
|
if (cookies[i].indexOf(nameForSearch) != -1) {
|
||||||
|
value = cookies[i].substr(nameForSearch.length);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes cookie.
|
||||||
|
*
|
||||||
|
* @param {String} name Name of the cookie that should be deleted.
|
||||||
|
*/
|
||||||
|
Mibew.Utils.deleteCookie = function(name) {
|
||||||
|
Mibew.Utils.createCookie(name, '', (new Date(0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets correct prototypes chain.
|
||||||
|
*
|
||||||
|
* This function is based on the logic used in Object.create method.
|
||||||
|
* Unfortunately not all target browsers support this function thus it
|
||||||
|
* should be implemented here.
|
||||||
|
*
|
||||||
|
* Warning: this methods completely rewrites prototype of "ctor" argument.
|
||||||
|
*
|
||||||
|
* @type {Function}
|
||||||
|
* @param {Function} ctor An object constructor which prototype should be
|
||||||
|
* updated.
|
||||||
|
* @param {Function} superCtor An object constructor which prototype should
|
||||||
|
* be used.
|
||||||
|
*/
|
||||||
|
Mibew.Utils.inherits = (function() {
|
||||||
|
// Tmp function is defined in closure because in such case only one
|
||||||
|
// temporary function will be kept in memory regardless of inherits
|
||||||
|
// function calls number.
|
||||||
|
var Tmp = function() {};
|
||||||
|
|
||||||
|
return function(ctor, superCtor) {
|
||||||
|
Tmp.prototype = superCtor.prototype;
|
||||||
|
ctor.prototype = new Tmp();
|
||||||
|
Tmp.prototype = null;
|
||||||
|
ctor.prototype.constructor = ctor;
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attaches an event listener to the target object's event.
|
||||||
|
*
|
||||||
|
* This method uses native "addEventListener" in modern browsers and a
|
||||||
|
* workaround for IE < 9.
|
||||||
|
*
|
||||||
|
* @param {Object} target The object which fires the event.
|
||||||
|
* @param {String} eventName Name of the event.
|
||||||
|
* @param {Function} listener The function that should be triggered.
|
||||||
|
*/
|
||||||
|
Mibew.Utils.addEventListener = function(target, eventName, listener) {
|
||||||
|
if (target.addEventListener) {
|
||||||
|
// A regular browser is used
|
||||||
|
target.addEventListener(eventName, listener, false);
|
||||||
|
} else {
|
||||||
|
if (target.attachEvent) {
|
||||||
|
// This is needed for IE < 9
|
||||||
|
target.attachEvent(
|
||||||
|
'on' + eventName,
|
||||||
|
// The closure is used to use valid this reference in the
|
||||||
|
// listener.
|
||||||
|
function (event) {
|
||||||
|
listener.call(target, event);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads CSS file and attach it to DOM.
|
||||||
|
*
|
||||||
|
* @param {String} url URL of the CSS that should be loaded.
|
||||||
|
* @param {String} [id] ID of the DOM element that will be created. Can be
|
||||||
|
* omitted.
|
||||||
|
* @returns {Element} Appended DOM item.
|
||||||
|
*/
|
||||||
|
Mibew.Utils.loadStyleSheet = function(url, id) {
|
||||||
|
var styleSheet = document.createElement('link');
|
||||||
|
styleSheet.setAttribute('rel', 'stylesheet');
|
||||||
|
styleSheet.setAttribute('type', 'text/css');
|
||||||
|
styleSheet.setAttribute('href', url);
|
||||||
|
if (id) {
|
||||||
|
styleSheet.setAttribute('id', id);
|
||||||
|
}
|
||||||
|
document.getElementsByTagName('head')[0].appendChild(styleSheet);
|
||||||
|
|
||||||
|
return styleSheet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads JavaScript file and attach it to DOM.
|
||||||
|
*
|
||||||
|
* @param {String} url URL of the JavaScript file that should be loaded.
|
||||||
|
* @param {String} [id] ID of the DOM element that will be created. Can be
|
||||||
|
* omitted.
|
||||||
|
* @returns {Element} Appended DOM item.
|
||||||
|
*/
|
||||||
|
Mibew.Utils.loadScript = function(url, id) {
|
||||||
|
var script = document.createElement('script');
|
||||||
|
script.setAttribute('type', 'text/javascript');
|
||||||
|
script.setAttribute('src', url);
|
||||||
|
if (id) {
|
||||||
|
script.setAttribute('id', id);
|
||||||
|
}
|
||||||
|
document.getElementsByTagName('head')[0].appendChild(script);
|
||||||
|
|
||||||
|
return script;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a proper chat popup.
|
||||||
|
*
|
||||||
|
* This is a helper function which choose which popup (iframe or window)
|
||||||
|
* should be created, create it and store into Mibew.Objects.ChatPopups
|
||||||
|
* hash.
|
||||||
|
*
|
||||||
|
* @param {Object} options List of popup options.
|
||||||
|
*/
|
||||||
|
Mibew.ChatPopup.init = function(options) {
|
||||||
|
var canUseIFrame = (window.postMessage && options.preferIFrame),
|
||||||
|
Popup = canUseIFrame ? Mibew.ChatPopup.IFrame : Mibew.ChatPopup.Window;
|
||||||
|
|
||||||
|
Mibew.Objects.ChatPopups[options.id] = new Popup(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A constructor for base (abstract) popup object.
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
* @param {Object} options A list of popup options.
|
||||||
|
*/
|
||||||
|
var BasePopup = function(options) {
|
||||||
|
/**
|
||||||
|
* Unique ID of the popup.
|
||||||
|
* @type {String}
|
||||||
|
*/
|
||||||
|
this.id = options.id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chat initialization URL.
|
||||||
|
* @type {String}
|
||||||
|
*/
|
||||||
|
this.url = options.url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Width of the popup in pixels.
|
||||||
|
* @type {Number}
|
||||||
|
*/
|
||||||
|
this.width = options.width;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Height of the popup in pixels.
|
||||||
|
* @type {Number}
|
||||||
|
*/
|
||||||
|
this.height = options.height;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicats if the popup should be resizable.
|
||||||
|
*
|
||||||
|
* It can be appliedonly for window popup.
|
||||||
|
*
|
||||||
|
* @type {Boolean}
|
||||||
|
*/
|
||||||
|
this.resizable = options.resizable || false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains URL of JavaScript file that loads css file for IFrame popup.
|
||||||
|
*
|
||||||
|
* @type {String}
|
||||||
|
*/
|
||||||
|
this.styleLoader = options.styleLoader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if special actions should be done to fix problems with
|
||||||
|
* mod_security.
|
||||||
|
* @type {Boolean}
|
||||||
|
*/
|
||||||
|
this.modSecurity = options.modSecurity || false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if the popup is opened.
|
||||||
|
* @type {Boolean}
|
||||||
|
*/
|
||||||
|
this.isOpened = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds an URL that initializes a chat.
|
||||||
|
*
|
||||||
|
* @returns {String} Chat URL.
|
||||||
|
*/
|
||||||
|
BasePopup.prototype.buildChatUrl = function() {
|
||||||
|
var href = document.location.href,
|
||||||
|
referrer = document.referrer;
|
||||||
|
|
||||||
|
if (this.modSecurity) {
|
||||||
|
href = href.replace('http://','').replace('https://','');
|
||||||
|
referrer = referrer.replace('http://','').replace('https://','');
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.url
|
||||||
|
+ ((this.url.indexOf('?') === false) ? '?' : '&') + 'url=' + escape(href)
|
||||||
|
+ '&referrer=' + escape(referrer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs IFrame popup.
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
* @extends BasePopup
|
||||||
|
* @param {Object} options List of popup options.
|
||||||
|
*/
|
||||||
|
Mibew.ChatPopup.IFrame = function(options) {
|
||||||
|
// Call parent constructor.
|
||||||
|
BasePopup.call(this, options);
|
||||||
|
|
||||||
|
this.iframe = null;
|
||||||
|
|
||||||
|
// Load extra style sheets.
|
||||||
|
Mibew.Utils.loadScript(this.styleLoader);
|
||||||
|
var openedChatUrl = Mibew.Utils.readCookie('mibew-chat-frame-' + this.id);
|
||||||
|
if (openedChatUrl) {
|
||||||
|
// The chat was not closed so the popup should be reopened when a
|
||||||
|
// new page is visited.
|
||||||
|
this.open(openedChatUrl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set correct prototype chain for IFrame popup.
|
||||||
|
Mibew.Utils.inherits(Mibew.ChatPopup.IFrame, BasePopup);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens the popup.
|
||||||
|
*
|
||||||
|
* @param {String} [url] The URL that should be opened in the popup. If the
|
||||||
|
* value is omitted, the chat initialization URL will be loaded.
|
||||||
|
*/
|
||||||
|
Mibew.ChatPopup.IFrame.prototype.open = function(url) {
|
||||||
|
if (this.isOpened) {
|
||||||
|
// Do not open the popup twice.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.iframe) {
|
||||||
|
// Create new iframe.
|
||||||
|
// There is a bug in IE <= 7 that make "name" attribute unchangeble
|
||||||
|
// for elements that already exist. Thus a temporary div is used
|
||||||
|
// here as a workaround.
|
||||||
|
var tmpDiv = document.createElement('div');
|
||||||
|
tmpDiv.innerHTML = '<iframe name="mibewChat' + this.id + '"></iframe>';
|
||||||
|
|
||||||
|
this.iframe = tmpDiv.getElementsByTagName('iframe')[0];
|
||||||
|
this.iframe.setAttribute('id', 'mibew-chat-frame-' + this.id);
|
||||||
|
this.iframe.className = 'mibew-chat-frame';
|
||||||
|
this.iframe.setAttribute('frameBorder', 0);
|
||||||
|
this.iframe.style.display = 'none';
|
||||||
|
document.getElementsByTagName('body')[0].appendChild(this.iframe);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.iframe.style.display = 'block';
|
||||||
|
this.iframe.src = url || this.buildChatUrl();
|
||||||
|
this.isOpened = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes the popup.
|
||||||
|
*/
|
||||||
|
Mibew.ChatPopup.IFrame.prototype.close = function() {
|
||||||
|
if (!this.isOpened) {
|
||||||
|
// A popup that was not opened thus it cannot be closed.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.iframe.style.display = 'none';
|
||||||
|
this.iframe.src = '';
|
||||||
|
this.isOpened = false;
|
||||||
|
Mibew.Utils.deleteCookie('mibew-chat-frame-' + this.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs Window popup.
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
* @extends BasePopup
|
||||||
|
* @param {Object} options List of popup options.
|
||||||
|
*/
|
||||||
|
Mibew.ChatPopup.Window = function(options) {
|
||||||
|
BasePopup.call(this, options);
|
||||||
|
|
||||||
|
this.window = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set correct prototype chain for Window popup.
|
||||||
|
Mibew.Utils.inherits(Mibew.ChatPopup.Window, BasePopup);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens the popup.
|
||||||
|
*
|
||||||
|
* @param {String} [url] The URL that should be opened in the popup. If the
|
||||||
|
* value is omitted, the chat initialization URL will be loaded.
|
||||||
|
*/
|
||||||
|
Mibew.ChatPopup.Window.prototype.open = function(url) {
|
||||||
|
if (this.isOpened) {
|
||||||
|
// Do not open the popup twice.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.window = window.open(
|
||||||
|
url || this.buildChatUrl(),
|
||||||
|
'mibewChat' + this.id,
|
||||||
|
this.getWindowParams()
|
||||||
|
);
|
||||||
|
this.window.focus();
|
||||||
|
this.window.opener = window;
|
||||||
|
|
||||||
|
this.isOpened = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes the popup.
|
||||||
|
*/
|
||||||
|
Mibew.ChatPopup.Window.prototype.close = function() {
|
||||||
|
if (!this.isOpened) {
|
||||||
|
// The window was not opened thus it should not be closed.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.window.close();
|
||||||
|
this.window = null;
|
||||||
|
this.isOpened = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds window params string.
|
||||||
|
*
|
||||||
|
* Generated params string can be used in window.open method as the third
|
||||||
|
* argument.
|
||||||
|
*
|
||||||
|
* @protected
|
||||||
|
* @returns {String}
|
||||||
|
*/
|
||||||
|
Mibew.ChatPopup.Window.prototype.getWindowParams = function() {
|
||||||
|
return [
|
||||||
|
'toolbar=0',
|
||||||
|
'scrollbars=0',
|
||||||
|
'location=0',
|
||||||
|
'status=1',
|
||||||
|
'menubar=0',
|
||||||
|
'width=' + this.width.toString(),
|
||||||
|
'height=' + this.height.toString(),
|
||||||
|
'resizable=' + (this.resizable ? '1' : '0')
|
||||||
|
].join(',');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attach a listener to window's "message" event to get the url of the chat
|
||||||
|
// which is opened in iframe popup.
|
||||||
|
Mibew.Utils.addEventListener(window, 'message', function(event) {
|
||||||
|
var matches = /^mibew-chat-started\:mibewChat([0-9A-Za-z]+)\:(.*)$/.exec(event.data);
|
||||||
|
|
||||||
|
if (matches) {
|
||||||
|
Mibew.Utils.createCookie('mibew-chat-frame-' + matches[1], matches[2]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Attach a listener to window's "message" event to close the iframe when
|
||||||
|
// the chat is closed.
|
||||||
|
Mibew.Utils.addEventListener(window, 'message', function(event) {
|
||||||
|
var popups = Mibew.Objects.ChatPopups,
|
||||||
|
matches = /^mibew-chat-closed\:mibewChat([0-9A-Za-z]+)$/.exec(event.data);
|
||||||
|
|
||||||
|
if (matches && popups[matches[1]]) {
|
||||||
|
popups[matches[1]].close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
})(Mibew);
|
@ -19,14 +19,14 @@
|
|||||||
/**
|
/**
|
||||||
* @namespace Holds all Mibew functionality
|
* @namespace Holds all Mibew functionality
|
||||||
*/
|
*/
|
||||||
var Mibew = {};
|
var Mibew = Mibew || {};
|
||||||
|
|
||||||
(function(Mibew){
|
(function(Mibew){
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @namespace Holds objects instances
|
* @namespace Holds objects instances
|
||||||
*/
|
*/
|
||||||
Mibew.Objects = {};
|
Mibew.Objects = Mibew.Objects || {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create new widget
|
* Create new widget
|
||||||
@ -93,11 +93,7 @@ var Mibew = {};
|
|||||||
this.dataToSend = {};
|
this.dataToSend = {};
|
||||||
|
|
||||||
// Load additional styles
|
// Load additional styles
|
||||||
var styleSheet = document.createElement('link');
|
Mibew.Utils.loadStyleSheet(options.inviteStyle);
|
||||||
styleSheet.setAttribute('rel', 'stylesheet');
|
|
||||||
styleSheet.setAttribute('type', 'text/css');
|
|
||||||
styleSheet.setAttribute('href', options.inviteStyle);
|
|
||||||
document.getElementsByTagName('head')[0].appendChild(styleSheet);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -121,7 +117,7 @@ var Mibew = {};
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.doLoadScript(
|
Mibew.Utils.loadScript(
|
||||||
this.requestURL
|
this.requestURL
|
||||||
+ '?' + this.getQuery(),
|
+ '?' + this.getQuery(),
|
||||||
'mibew-response-script'
|
'mibew-response-script'
|
||||||
@ -260,7 +256,7 @@ var Mibew = {};
|
|||||||
// Store context
|
// Store context
|
||||||
var context = this;
|
var context = this;
|
||||||
// Load script by adding script tag to DOM
|
// Load script by adding script tag to DOM
|
||||||
var script = this.doLoadScript(this.requestedScripts[id].url, id);
|
var script = Mibew.Utils.loadScript(this.requestedScripts[id].url, id);
|
||||||
|
|
||||||
// Check if script loaded
|
// Check if script loaded
|
||||||
script.onload = function(){
|
script.onload = function(){
|
||||||
@ -274,21 +270,6 @@ var Mibew = {};
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Dynamically add script tag to DOM
|
|
||||||
* @param {String} url URL of the script to load
|
|
||||||
* @param {String} id Identifier of the script to load
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
Mibew.Widget.prototype.doLoadScript = function(url, id) {
|
|
||||||
var script = document.createElement('script');
|
|
||||||
script.setAttribute('type', 'text/javascript');
|
|
||||||
script.setAttribute('src', url);
|
|
||||||
script.setAttribute('id', id);
|
|
||||||
document.getElementsByTagName('head')[0].appendChild(script);
|
|
||||||
return script;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Event listener for script onLoad event. Run handlers which have no
|
* Event listener for script onLoad event. Run handlers which have no
|
||||||
* unload dependencies.
|
* unload dependencies.
|
||||||
@ -330,57 +311,6 @@ var Mibew = {};
|
|||||||
Mibew.Objects.widget.makeRequest();
|
Mibew.Objects.widget.makeRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @namespace Holds utility functions
|
|
||||||
*/
|
|
||||||
Mibew.Utils = {};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a cookie for the second level domain with path equals to '/'.
|
|
||||||
*
|
|
||||||
* @param {String} name Cookie name
|
|
||||||
* @param {String} value Cookie value
|
|
||||||
* @param {Date} expires Indicates when the cookie expires. If the value is
|
|
||||||
* omitted a session cookie will be created.
|
|
||||||
*/
|
|
||||||
Mibew.Utils.createCookie = function(name, value, expires) {
|
|
||||||
var domain = /([^\.]+\.[^\.]+)$/.exec(document.location.hostname);
|
|
||||||
document.cookie = "" + name + "=" + value + "; "
|
|
||||||
+ "path=/; "
|
|
||||||
+ (domain ? ("domain=" + domain[1] + "; ") : '')
|
|
||||||
+ (expires ? ('expires=' + expires.toUTCString() + '; ') : '');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Try to read cookie.
|
|
||||||
*
|
|
||||||
* @param {String} name Cookie name
|
|
||||||
* @returns {String|Boolean} Cookie value or boolean false if cookie with
|
|
||||||
* specified name does not exist
|
|
||||||
*/
|
|
||||||
Mibew.Utils.readCookie = function(name) {
|
|
||||||
var cookies = document.cookie.split('; ');
|
|
||||||
var nameForSearch = name + '=';
|
|
||||||
var value = false;
|
|
||||||
for (var i = 0; i < cookies.length; i++) {
|
|
||||||
if (cookies[i].indexOf(nameForSearch) != -1) {
|
|
||||||
value = cookies[i].substr(nameForSearch.length);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Deletes cookie.
|
|
||||||
*
|
|
||||||
* @param {String} name Name of the cookie that should be deleted.
|
|
||||||
*/
|
|
||||||
Mibew.Utils.deleteCookie = function(name) {
|
|
||||||
Mibew.Utils.createCookie(name, '', (new Date(0)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @namespace Holds invitation stuff
|
* @namespace Holds invitation stuff
|
||||||
*/
|
*/
|
||||||
|
@ -416,6 +416,16 @@ function setup_chatview_for_user(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set chat link
|
||||||
|
$data['chat']['links']['chat'] = $url_generator->generate(
|
||||||
|
'chat_user',
|
||||||
|
array(
|
||||||
|
'thread_id' => $thread->id,
|
||||||
|
'token' => $thread->lastToken,
|
||||||
|
),
|
||||||
|
UrlGeneratorInterface::ABSOLUTE_URL
|
||||||
|
);
|
||||||
|
|
||||||
// Set default operator's avatar
|
// Set default operator's avatar
|
||||||
$operator = operator_by_id($thread->agentId);
|
$operator = operator_by_id($thread->agentId);
|
||||||
$data['chat']['avatar'] = ($operator['vcavatar'] ? $operator['vcavatar'] : '');
|
$data['chat']['avatar'] = ($operator['vcavatar'] ? $operator['vcavatar'] : '');
|
||||||
@ -465,6 +475,16 @@ function setup_chatview_for_operator(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set chat link
|
||||||
|
$data['chat']['links']['chat'] = $url_generator->generate(
|
||||||
|
'chat_operator',
|
||||||
|
array(
|
||||||
|
'thread_id' => $thread->id,
|
||||||
|
'token' => $thread->lastToken,
|
||||||
|
),
|
||||||
|
UrlGeneratorInterface::ABSOLUTE_URL
|
||||||
|
);
|
||||||
|
|
||||||
// Set history window params
|
// Set history window params
|
||||||
$data['chat']['links']['history'] = $url_generator->generate(
|
$data['chat']['links']['history'] = $url_generator->generate(
|
||||||
'history_user',
|
'history_user',
|
||||||
|
@ -19,6 +19,8 @@
|
|||||||
|
|
||||||
namespace Mibew\Button\Generator;
|
namespace Mibew\Button\Generator;
|
||||||
|
|
||||||
|
use Canteen\HTML5;
|
||||||
|
use Mibew\Asset\Generator\UrlGeneratorInterface as AssetUrlGeneratorInterface;
|
||||||
use Mibew\EventDispatcher\EventDispatcher;
|
use Mibew\EventDispatcher\EventDispatcher;
|
||||||
use Mibew\EventDispatcher\Events;
|
use Mibew\EventDispatcher\Events;
|
||||||
use Mibew\Routing\Generator\SecureUrlGeneratorInterface as RouteUrlGeneratorInterface;
|
use Mibew\Routing\Generator\SecureUrlGeneratorInterface as RouteUrlGeneratorInterface;
|
||||||
@ -36,6 +38,13 @@ abstract class AbstractGenerator implements GeneratorInterface
|
|||||||
*/
|
*/
|
||||||
protected $routeUrlGenerator = null;
|
protected $routeUrlGenerator = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An assets URL generator.
|
||||||
|
*
|
||||||
|
* @var AssetUrlGeneratorInterface|null
|
||||||
|
*/
|
||||||
|
protected $assetUrlGenerator = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of the generator's options.
|
* List of the generator's options.
|
||||||
*
|
*
|
||||||
@ -53,10 +62,14 @@ abstract class AbstractGenerator implements GeneratorInterface
|
|||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
RouteUrlGeneratorInterface $routeUrlGenerator,
|
RouteUrlGeneratorInterface $routeUrlGenerator,
|
||||||
|
AssetUrlGeneratorInterface $assetUrlGenerator,
|
||||||
$options = array()
|
$options = array()
|
||||||
) {
|
) {
|
||||||
$this->routeUrlGenerator = $routeUrlGenerator;
|
$this->routeUrlGenerator = $routeUrlGenerator;
|
||||||
$this->options = $options;
|
$this->assetUrlGenerator = $assetUrlGenerator;
|
||||||
|
$this->options = $options + array(
|
||||||
|
'unique_id' => uniqid() . dechex(rand(0, pow(2, 12))),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -117,6 +130,25 @@ abstract class AbstractGenerator implements GeneratorInterface
|
|||||||
: $generator->generate($route, $parameters, RouteUrlGeneratorInterface::ABSOLUTE_URL);
|
: $generator->generate($route, $parameters, RouteUrlGeneratorInterface::ABSOLUTE_URL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates URL for the specified asset.
|
||||||
|
*
|
||||||
|
* @param stirng $asset The relative path of the asset.
|
||||||
|
* @return string The URL for the specified asset.
|
||||||
|
*/
|
||||||
|
protected function generateAssetUrl($asset)
|
||||||
|
{
|
||||||
|
$generator = $this->assetUrlGenerator;
|
||||||
|
|
||||||
|
if (!$this->getOption('show_host')) {
|
||||||
|
return $generator->generate($asset);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->getOption('force_secure')
|
||||||
|
? $generator->generateSecure($asset, RouteUrlGeneratorInterface::ABSOLUTE_URL)
|
||||||
|
: $generator->generate($asset, RouteUrlGeneratorInterface::ABSOLUTE_URL);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the URL of the chat start point.
|
* Gets the URL of the chat start point.
|
||||||
*
|
*
|
||||||
@ -161,26 +193,76 @@ abstract class AbstractGenerator implements GeneratorInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the options string for the chat popup window.
|
* Gets the style options string for the chat popup.
|
||||||
*
|
*
|
||||||
* @return string
|
* @return array
|
||||||
*/
|
*/
|
||||||
protected function getPopupOptions()
|
protected function getPopupStyle()
|
||||||
{
|
{
|
||||||
$style_name = $this->getOption('chat_style');
|
$defaults = array(
|
||||||
|
'width' => 640,
|
||||||
|
'height' => 480,
|
||||||
|
'resizable' => true,
|
||||||
|
);
|
||||||
|
|
||||||
|
$style_name = $this->getOption('chat_style');
|
||||||
if (!$style_name) {
|
if (!$style_name) {
|
||||||
return "toolbar=0,scrollbars=0,location=0,status=1,menubar=0,width=640,height=480,resizable=1";
|
return $defaults + array(
|
||||||
|
'styleLoader' => $this->generateUrl('chat_user_popup_style'),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$chat_style = new ChatStyle($style_name);
|
$chat_style = new ChatStyle($style_name);
|
||||||
$chat_configurations = $chat_style->getConfigurations();
|
$chat_configs = $chat_style->getConfigurations();
|
||||||
|
|
||||||
return sprintf(
|
// Intersection is used to limit style options to keys from the defaults
|
||||||
"toolbar=0,scrollbars=0,location=0,status=1,menubar=0,width=%u,height=%u,resizable=%u",
|
// array.
|
||||||
$chat_configurations['chat']['window']['width'] ?: 640,
|
return array_intersect_key(
|
||||||
$chat_configurations['chat']['window']['height'] ?: 480,
|
$chat_configs['chat']['window'] + $defaults,
|
||||||
$chat_configurations['chat']['window']['resizable'] ? '1' : '0'
|
$defaults
|
||||||
|
) + array(
|
||||||
|
'styleLoader' => $this->generateUrl(
|
||||||
|
'chat_user_popup_style',
|
||||||
|
array('style' => $style_name)
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds options list for a chat popup.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function getPopupOptions()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
'id' => $this->getOption('unique_id'),
|
||||||
|
'url' => str_replace('&', '&', $this->getChatUrl()),
|
||||||
|
'preferIFrame' => $this->getOption('prefer_iframe'),
|
||||||
|
'modSecurity' => $this->getOption('mod_security'),
|
||||||
|
) + $this->getPopupStyle();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds markup with chat popup initialization code.
|
||||||
|
*
|
||||||
|
* @return \Canteen\HTML5\Fragment
|
||||||
|
*/
|
||||||
|
protected function getPopup()
|
||||||
|
{
|
||||||
|
$fragment = HTML5\html('fragment');
|
||||||
|
$fragment->addChild(
|
||||||
|
HTML5\html('script')->setAttributes(array(
|
||||||
|
'type' => 'text/javascript',
|
||||||
|
'src' => $this->generateAssetUrl('js/compiled/chat_popup.js'),
|
||||||
|
))
|
||||||
|
);
|
||||||
|
$fragment->addChild(
|
||||||
|
HTML5\html('script')
|
||||||
|
->setAttribute('type', 'text/javascript')
|
||||||
|
->addChild('Mibew.ChatPopup.init(' . json_encode($this->getPopupOptions()) . ');')
|
||||||
|
);
|
||||||
|
|
||||||
|
return $fragment;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,8 +20,6 @@
|
|||||||
namespace Mibew\Button\Generator;
|
namespace Mibew\Button\Generator;
|
||||||
|
|
||||||
use Canteen\HTML5;
|
use Canteen\HTML5;
|
||||||
use Mibew\Asset\Generator\UrlGeneratorInterface as AssetUrlGeneratorInterface;
|
|
||||||
use Mibew\Routing\Generator\SecureUrlGeneratorInterface as RouteUrlGeneratorInterface;
|
|
||||||
use Mibew\Settings;
|
use Mibew\Settings;
|
||||||
use Mibew\Style\InvitationStyle;
|
use Mibew\Style\InvitationStyle;
|
||||||
|
|
||||||
@ -30,32 +28,6 @@ use Mibew\Style\InvitationStyle;
|
|||||||
*/
|
*/
|
||||||
class ImageGenerator extends TextGenerator
|
class ImageGenerator extends TextGenerator
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* An assets URL generator.
|
|
||||||
*
|
|
||||||
* @var AssetUrlGeneratorInterface|null
|
|
||||||
*/
|
|
||||||
protected $assetUrlGenerator = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class contructor.
|
|
||||||
*
|
|
||||||
* @param RouteUrlGeneratorInterface $routeUrlGenerator A routes URL
|
|
||||||
* generator.
|
|
||||||
* @param AssetUrlGeneratorInterface $assetUrlGenerator An assets URL
|
|
||||||
* generator.
|
|
||||||
* @param array $options Associative array with generator's initial options.
|
|
||||||
* The set of options can vary for the child classes.
|
|
||||||
*/
|
|
||||||
public function __construct(
|
|
||||||
RouteUrlGeneratorInterface $routeUrlGenerator,
|
|
||||||
AssetUrlGeneratorInterface $assetUrlGenerator,
|
|
||||||
$options = array()
|
|
||||||
) {
|
|
||||||
parent::__construct($routeUrlGenerator, $options);
|
|
||||||
$this->assetUrlGenerator = $assetUrlGenerator;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
@ -84,7 +56,7 @@ class ImageGenerator extends TextGenerator
|
|||||||
|
|
||||||
$button = HTML5\html('fragment');
|
$button = HTML5\html('fragment');
|
||||||
$button->addChild(HTML5\html('comment', 'mibew button'));
|
$button->addChild(HTML5\html('comment', 'mibew button'));
|
||||||
$button->addChild($this->getPopup($image));
|
$button->addChild($this->getPopupLink($image));
|
||||||
if (Settings::get('enabletracking')) {
|
if (Settings::get('enabletracking')) {
|
||||||
$button->addChild($this->getWidgetCode());
|
$button->addChild($this->getWidgetCode());
|
||||||
}
|
}
|
||||||
@ -93,25 +65,6 @@ class ImageGenerator extends TextGenerator
|
|||||||
return $button;
|
return $button;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates URL for the specified asset.
|
|
||||||
*
|
|
||||||
* @param stirng $asset The relative path of the asset.
|
|
||||||
* @return string The URL for the specified asset.
|
|
||||||
*/
|
|
||||||
protected function generateAssetUrl($asset)
|
|
||||||
{
|
|
||||||
$generator = $this->assetUrlGenerator;
|
|
||||||
|
|
||||||
if (!$this->getOption('show_host')) {
|
|
||||||
return $generator->generate($asset);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->getOption('force_secure')
|
|
||||||
? $generator->generateSecure($asset, RouteUrlGeneratorInterface::ABSOLUTE_URL)
|
|
||||||
: $generator->generate($asset, RouteUrlGeneratorInterface::ABSOLUTE_URL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates HTML markup for Mibew widget.
|
* Generates HTML markup for Mibew widget.
|
||||||
*
|
*
|
||||||
|
@ -35,15 +35,12 @@ class OperatorCodeGenerator extends AbstractGenerator
|
|||||||
$form->setAttributes(array(
|
$form->setAttributes(array(
|
||||||
'action' => '',
|
'action' => '',
|
||||||
'onsubmit' => sprintf(
|
'onsubmit' => sprintf(
|
||||||
("if(navigator.userAgent.toLowerCase().indexOf('opera') != -1 "
|
("var popup = Mibew.Objects.ChatPopups['%s'];"
|
||||||
. "&& window.event.preventDefault) window.event.preventDefault();"
|
. "popup.open(popup.buildChatUrl() "
|
||||||
. "this.newWindow = window.open(%s + '&operator_code=' "
|
. "+ '&operator_code=' "
|
||||||
. "+ document.getElementById('mibew-operator-code-field').value, 'mibew', '%s');"
|
. "+ document.getElementById('mibew-operator-code-field').value);"
|
||||||
. "this.newWindow.focus();"
|
. "return false;"),
|
||||||
. "this.newWindow.opener=window;"
|
$this->getOption('unique_id')
|
||||||
. "return false;"),
|
|
||||||
$this->getChatUrlForJs(),
|
|
||||||
$this->getPopupOptions()
|
|
||||||
),
|
),
|
||||||
'id' => 'mibew-operator-code-form',
|
'id' => 'mibew-operator-code-form',
|
||||||
));
|
));
|
||||||
@ -58,6 +55,7 @@ class OperatorCodeGenerator extends AbstractGenerator
|
|||||||
$button = HTML5\html('fragment');
|
$button = HTML5\html('fragment');
|
||||||
$button->addChild(HTML5\html('comment', 'mibew operator code field'));
|
$button->addChild(HTML5\html('comment', 'mibew operator code field'));
|
||||||
$button->addChild($form);
|
$button->addChild($form);
|
||||||
|
$button->addChild($this->getPopup());
|
||||||
$button->addChild(HTML5\html('comment', '/ mibew operator code field'));
|
$button->addChild(HTML5\html('comment', '/ mibew operator code field'));
|
||||||
|
|
||||||
return $button;
|
return $button;
|
||||||
|
@ -33,35 +33,28 @@ class TextGenerator extends AbstractGenerator
|
|||||||
{
|
{
|
||||||
$button = HTML5\html('fragment');
|
$button = HTML5\html('fragment');
|
||||||
$button->addChild(HTML5\html('comment', 'mibew text link'));
|
$button->addChild(HTML5\html('comment', 'mibew text link'));
|
||||||
$button->addChild($this->getPopup($this->getOption('caption')));
|
$button->addChild($this->getPopupLink($this->getOption('caption')));
|
||||||
$button->addChild(HTML5\html('comment', '/ mibew text link'));
|
$button->addChild(HTML5\html('comment', '/ mibew text link'));
|
||||||
|
|
||||||
return $button;
|
return $button;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a markup for opening popup window with the chat.
|
* Generates a markup for link that opens chat popup.
|
||||||
*
|
*
|
||||||
|
* @param string|\Canteen\HTML5\Node $caption A string or an HTML node that
|
||||||
|
* is used as popup link caption.
|
||||||
* @return string HTML markup.
|
* @return string HTML markup.
|
||||||
*/
|
*/
|
||||||
protected function getPopup($message)
|
protected function getPopupLink($caption)
|
||||||
{
|
{
|
||||||
$link = HTML5\html('a', $message);
|
$link = HTML5\html('a', $caption);
|
||||||
|
|
||||||
$link->setAttributes(array(
|
$link->setAttributes(array(
|
||||||
'id' => 'mibew-agent-button',
|
'id' => 'mibew-agent-button',
|
||||||
'href' => str_replace('&', '&', $this->getChatUrl()),
|
'href' => str_replace('&', '&', $this->getChatUrl()),
|
||||||
'target' => '_blank',
|
'target' => '_blank',
|
||||||
'onclick' =>sprintf(
|
'onclick' => ("Mibew.Objects.ChatPopups['" . $this->getOption('unique_id') . "'].open();"
|
||||||
("if(navigator.userAgent.toLowerCase().indexOf('opera') != -1 "
|
. "return false;"),
|
||||||
. "&& window.event.preventDefault) window.event.preventDefault();"
|
|
||||||
. "this.newWindow = window.open(%s, 'mibew', '%s');"
|
|
||||||
. "this.newWindow.focus();"
|
|
||||||
. "this.newWindow.opener=window;"
|
|
||||||
. "return false;"),
|
|
||||||
$this->getChatUrlForJs(),
|
|
||||||
$this->getPopupOptions()
|
|
||||||
),
|
|
||||||
));
|
));
|
||||||
|
|
||||||
$title = $this->getOption('title');
|
$title = $this->getOption('title');
|
||||||
@ -69,6 +62,10 @@ class TextGenerator extends AbstractGenerator
|
|||||||
$link->setAttribute('title', $title);
|
$link->setAttribute('title', $title);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $link;
|
$fragment = HTML5\html('fragment');
|
||||||
|
$fragment->addChild($link);
|
||||||
|
$fragment->addChild($this->getPopup());
|
||||||
|
|
||||||
|
return $fragment;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,6 +82,7 @@ class ButtonCodeController extends AbstractController
|
|||||||
$show_host = $request->query->get('hostname') == 'on';
|
$show_host = $request->query->get('hostname') == 'on';
|
||||||
$force_secure = $request->query->get('secure') == 'on';
|
$force_secure = $request->query->get('secure') == 'on';
|
||||||
$mod_security = $request->query->get('modsecurity') == 'on';
|
$mod_security = $request->query->get('modsecurity') == 'on';
|
||||||
|
$force_windows = $request->query->get('forcewindows') == 'on';
|
||||||
|
|
||||||
$code_type = $request->query->get('codetype', 'button');
|
$code_type = $request->query->get('codetype', 'button');
|
||||||
if (!in_array($code_type, array('button', 'operator_code', 'text_link'))) {
|
if (!in_array($code_type, array('button', 'operator_code', 'text_link'))) {
|
||||||
@ -101,11 +102,13 @@ class ButtonCodeController extends AbstractController
|
|||||||
'show_host' => $show_host,
|
'show_host' => $show_host,
|
||||||
'force_secure' => $force_secure,
|
'force_secure' => $force_secure,
|
||||||
'mod_security' => $mod_security,
|
'mod_security' => $mod_security,
|
||||||
|
'prefer_iframe' => !$force_windows,
|
||||||
);
|
);
|
||||||
|
|
||||||
if ($operator_code) {
|
if ($operator_code) {
|
||||||
$button_generator = new OperatorCodeFieldGenerator(
|
$button_generator = new OperatorCodeFieldGenerator(
|
||||||
$this->getRouter(),
|
$this->getRouter(),
|
||||||
|
$this->getAssetManager()->getUrlGenerator(),
|
||||||
$button_generator_options
|
$button_generator_options
|
||||||
);
|
);
|
||||||
} elseif ($generate_button) {
|
} elseif ($generate_button) {
|
||||||
@ -134,6 +137,7 @@ class ButtonCodeController extends AbstractController
|
|||||||
|
|
||||||
$button_generator = new TextButtonGenerator(
|
$button_generator = new TextButtonGenerator(
|
||||||
$this->getRouter(),
|
$this->getRouter(),
|
||||||
|
$this->getAssetManager()->getUrlGenerator(),
|
||||||
$button_generator_options
|
$button_generator_options
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -166,6 +170,7 @@ class ButtonCodeController extends AbstractController
|
|||||||
$page['formsecure'] = $force_secure;
|
$page['formsecure'] = $force_secure;
|
||||||
$page['formmodsecurity'] = $mod_security;
|
$page['formmodsecurity'] = $mod_security;
|
||||||
$page['formcodetype'] = $code_type;
|
$page['formcodetype'] = $code_type;
|
||||||
|
$page['formforcewindows'] = $force_windows;
|
||||||
|
|
||||||
$page['enabletracking'] = Settings::get('enabletracking');
|
$page['enabletracking'] = Settings::get('enabletracking');
|
||||||
$page['operator_code'] = $operator_code;
|
$page['operator_code'] = $operator_code;
|
||||||
|
@ -0,0 +1,61 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is a part of Mibew Messenger.
|
||||||
|
*
|
||||||
|
* Copyright 2005-2014 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Mibew\Controller\Chat;
|
||||||
|
|
||||||
|
use Mibew\Asset\Generator\UrlGeneratorInterface;
|
||||||
|
use Mibew\Style\ChatStyle;
|
||||||
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains all actions which are related with dynamic styles loading.
|
||||||
|
*/
|
||||||
|
class StyleController extends AbstractController
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Generates a JavaScript file with popup CSS file loader.
|
||||||
|
*
|
||||||
|
* @param Request $request
|
||||||
|
* @return JsonResponse
|
||||||
|
*/
|
||||||
|
public function loadPopupStyleAction(Request $request)
|
||||||
|
{
|
||||||
|
$style_name = $request->attributes->get('style');
|
||||||
|
if (!$style_name) {
|
||||||
|
$style_name = ChatStyle::getDefaultStyle();
|
||||||
|
}
|
||||||
|
|
||||||
|
$style = new ChatStyle($style_name);
|
||||||
|
$configs = $style->getConfigurations();
|
||||||
|
|
||||||
|
$response = new JsonResponse();
|
||||||
|
if ($configs['chat']['iframe']['css']) {
|
||||||
|
$generator = $this->getAssetManager()->getUrlGenerator();
|
||||||
|
$css = $generator->generate(
|
||||||
|
$style->getFilesPath() . '/' . $configs['chat']['iframe']['css'],
|
||||||
|
UrlGeneratorInterface::ABSOLUTE_URL
|
||||||
|
);
|
||||||
|
$response->setData($css);
|
||||||
|
$response->setCallback('Mibew.Utils.loadStyleSheet');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
}
|
@ -142,6 +142,7 @@ class ChatStyle extends AbstractHandlebarsPoweredStyle implements StyleInterface
|
|||||||
return array(
|
return array(
|
||||||
'chat' => array(
|
'chat' => array(
|
||||||
'window' => array(),
|
'window' => array(),
|
||||||
|
'iframe' => array(),
|
||||||
),
|
),
|
||||||
'mail' => array(
|
'mail' => array(
|
||||||
'window' => array(),
|
'window' => array(),
|
||||||
|
@ -6,6 +6,9 @@ chat:
|
|||||||
height: 480
|
height: 480
|
||||||
width: 640
|
width: 640
|
||||||
resizable: true
|
resizable: true
|
||||||
|
# These params are used to customize chat popup.
|
||||||
|
iframe:
|
||||||
|
css: iframe.css
|
||||||
|
|
||||||
mail:
|
mail:
|
||||||
# These params are used for send mail windows opened via JavaScript's window.open.
|
# These params are used for send mail windows opened via JavaScript's window.open.
|
||||||
|
37
src/mibew/styles/chats/default/iframe.css
Normal file
37
src/mibew/styles/chats/default/iframe.css
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2005-2014 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
iframe.mibew-chat-frame {
|
||||||
|
background-color: #f1f2f2 !important;
|
||||||
|
margin: 0 !important;
|
||||||
|
padding: 0px !important;
|
||||||
|
border: 0 !important;
|
||||||
|
outline: 0 !important;
|
||||||
|
border: 1px solid #aaa !important;
|
||||||
|
position: fixed !important;
|
||||||
|
bottom: 5px !important;
|
||||||
|
right: 5px !important;
|
||||||
|
width: 510px !important;
|
||||||
|
height: 480px !important;
|
||||||
|
overflow: hidden !important;
|
||||||
|
z-index: 100 !important;
|
||||||
|
border-radius: 10px !important;
|
||||||
|
-webkit-border-radius: 10px !important;
|
||||||
|
-moz-border-radius: 10px !important;
|
||||||
|
box-shadow: 0 1px 1px 1px #ddd !important;
|
||||||
|
-moz-box-shadow: 0 1px 1px 1px #ddd !important;
|
||||||
|
-webkit-box-shadow: 0 1px 1px 1px #ddd !important;
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<a href="javascript:window.close();" title="{{l10n "Close"}}">
|
<a href="javascript:Mibew.Utils.closeChatPopup();" title="{{l10n "Close"}}">
|
||||||
<img class="tpl-image image-close-window" src="{{page.stylePath}}/images/free.gif" alt="{{l10n "Close"}}" />
|
<img class="tpl-image image-close-window" src="{{page.stylePath}}/images/free.gif" alt="{{l10n "Close"}}" />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<a href="javascript:window.close();" title="{{l10n "Close..."}}">
|
<a href="javascript:Mibew.Utils.closeChatPopup();" title="{{l10n "Close..."}}">
|
||||||
<img class="tpl-image image-close-window" src="{{page.stylePath}}/images/free.gif" alt="{{l10n "Close..."}}" />
|
<img class="tpl-image image-close-window" src="{{page.stylePath}}/images/free.gif" alt="{{l10n "Close..."}}" />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<div id="headers">
|
<div id="headers">
|
||||||
<div class="headers-inwards-wrapper-common"><div class="headers-inwards-wrapper-left"><div class="headers-inwards-wrapper-right"><div class="headers-inwards-wrapper-top"><div class="headers-inwards-wrapper-top-left"><div class="headers-inwards-wrapper-top-right"><div class="headers-inwards-wrapper-bottom-left"><div class="headers-inwards-wrapper-bottom-right">
|
<div class="headers-inwards-wrapper-common"><div class="headers-inwards-wrapper-left"><div class="headers-inwards-wrapper-right"><div class="headers-inwards-wrapper-top"><div class="headers-inwards-wrapper-top-left"><div class="headers-inwards-wrapper-top-right"><div class="headers-inwards-wrapper-bottom-left"><div class="headers-inwards-wrapper-bottom-right">
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<a href="javascript:window.close();" title="{{l10n "Close"}}"><img class="tpl-image image-close-window" src="{{page.stylePath}}/images/free.gif" alt="{{l10n "Close"}}" /></a>
|
<a href="javascript:Mibew.Utils.closeChatPopup();" title="{{l10n "Close"}}"><img class="tpl-image image-close-window" src="{{page.stylePath}}/images/free.gif" alt="{{l10n "Close"}}" /></a>
|
||||||
</div>
|
</div>
|
||||||
<div class="info-message">{{l10n "Thank you for contacting us. Please fill out the form below and click the Start Chat button."}}</div>
|
<div class="info-message">{{l10n "Thank you for contacting us. Please fill out the form below and click the Start Chat button."}}</div>
|
||||||
</div></div></div></div></div></div></div></div>
|
</div></div></div></div></div></div></div></div>
|
||||||
|
@ -50,6 +50,13 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="field-in-row">
|
||||||
|
<label for="force-windows" class="field-label">{{l10n "Use windows (even for modern browsers)"}}</label>
|
||||||
|
<div class="field-value-no-description">
|
||||||
|
<input id="force-windows" type="checkbox" name="forcewindows" value="on"{{#if formforcewindows}} checked="checked"{{/if}} onchange="this.form.submit();"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<br clear="all"/>
|
<br clear="all"/>
|
||||||
|
|
||||||
{{#if generateButton}}
|
{{#if generateButton}}
|
||||||
|
Loading…
Reference in New Issue
Block a user