Commit 6a2de75bcd39f596abd5cf618523f45b11f755b9

  • avatar
  • www-data <www-data @Debian-60-sq…-64-LAMP.(none)>
  • Wed Mar 28 12:51:36 IST 2012
Changed dev environment
  
4646 script_edit = root.makeelement('script')
4747 root.body.append(script_test)
4848 root.body.append(script_edit)
49 script_test.set("src", "http://dev.a11y.in/alipi/ui.js")
49 script_test.set("src", "http://dev.a11y.in/server/ui.js")
5050 script_test.set("type", "text/javascript")
51 script_edit.set("src", "http://dev.a11y.in/alipi/wsgi/page_edit.js")
51 script_edit.set("src", "http://dev.a11y.in/server/wsgi/page_edit.js")
5252 script_edit.set("type","text/javascript")
5353
5454 script_jq_mini = root.makeelement('script')
6060 root.body.append(style)
6161 style.set("rel","stylesheet")
6262 style.set("type", "text/css")
63 style.set("href", "http://dev.a11y.in/alipi/stylesheet.css")
63 style.set("href", "http://dev.a11y.in/server/stylesheet.css")
64
65 # if collection.find_one({"about" : request.args['foruri']}) is not None:
66 # overlay1 = root.makeelement('div')
67 # root.body.append(overlay1)
68 # overlay1.set("id", "overlay1")
69
70 # opt = root.makeelement('option')
71 # opt.text = "Choose a narration"
72
6473 script_jq_cust = root.makeelement('script')
6574 root.body.append(script_jq_cust)
6675 script_jq_cust.set("src", "https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js")
9696 script_jq_mini.set("src", "http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js")
9797 script_jq_mini.set("type", "text/javascript")
9898
99 script_test.set("src", "http://dev.a11y.in/alipi/ui.js")
99 script_test.set("src", "http://dev.a11y.in/server/ui.js")
100100 script_test.set("type", "text/javascript")
101 script_edit.set("src", "http://dev.a11y.in/alipi/wsgi/page_edit.js")
101 script_edit.set("src", "http://dev.a11y.in/server/wsgi/page_edit.js")
102102 script_edit.set("type","text/javascript")
103103 script_jqui = root.makeelement('script')
104104 script_jqui.set("type","text/javascript")
152152 root.body.append(style)
153153 style.set("rel","stylesheet")
154154 style.set("type", "text/css")
155 style.set("href", "http://dev.a11y.in/alipi/stylesheet.css")
155 style.set("href", "http://dev.a11y.in/server/stylesheet.css")
156
157 # overlay2 = root.makeelement('div')
158 # root.body.append(overlay2)
159 # overlay2.set("id", "overlay2")
160
161 # btn = root.makeelement('input')
162 # overlay2.append(btn)
163 # btn.set("id", "edit-button")
164 # btn.set("type", "submit")
165 # btn.set("onClick", "a11ypi.testContext();page_edit('4seiz', '4l85060vb9', '336e2nootv6nxjsvyjov', 'VISUAL', 'false', '');")
166 # btn.set("value", "EDIT")
156167 root.body.set("onload","a11ypi.ren();a11ypi.tweet(); a11ypi.facebook();a11ypi.loadOverlay();")
157168 return lxml.html.tostring(root)
158169
175175 d['lang'] = request.args['lang']
176176 script_test = root.makeelement('script')
177177 root.body.append(script_test)
178 script_test.set("src", "http://dev.a11y.in/alipi/ui.js")
178 script_test.set("src", "http://dev.a11y.in/server/ui.js")
179179 script_test.set("type", "text/javascript")
180180 root.body.set("onload","a11ypi.ren()");
181181 root.make_links_absolute(d['foruri'], resolve_base_href = True)
185185 script_jqui = root.makeelement('script')
186186
187187 script_test = root.makeelement('script')
188 script_test.set("src", "http://dev.a11y.in/alipi/ui.js")
188 script_test.set("src", "http://dev.a11y.in/server/ui.js")
189189 script_test.set("type", "text/javascript")
190190 root.body.append(script_test)
191191
195195 root.body.append(script_jq_mini)
196196
197197 script_edit = root.makeelement('script')
198 script_edit.set("src", "http://dev.a11y.in/alipi/wsgi/page_edit.js")
198 script_edit.set("src", "http://dev.a11y.in/server/wsgi/page_edit.js")
199199 script_edit.set("type","text/javascript")
200200 root.body.append(script_edit)
201201
249249 root.body.append(style)
250250 style.set("rel","stylesheet")
251251 style.set("type", "text/css")
252 style.set("href", "http://dev.a11y.in/alipi/stylesheet.css")
252 style.set("href", "http://dev.a11y.in/server/stylesheet.css")
253253
254254 overlay2 = root.makeelement('div')
255255 root.body.append(overlay2)
264264
265265 script_test = root.makeelement('script')
266266 root.body.append(script_test)
267 script_test.set("src", "http://dev.a11y.in/alipi/ui.js")
267 script_test.set("src", "http://dev.a11y.in/server/ui.js")
268268 script_test.set("type", "text/javascript")
269269 root.body.set("onload","a11ypi.filter(); a11ypi.tweet(); a11ypi.facebook();");
270270 root.make_links_absolute(d['foruri'], resolve_base_href = True)
273273 elif request.args.has_key('interactive') == False and request.args.has_key('blog') == True:
274274 script_test = root.makeelement('script')
275275 root.body.append(script_test)
276 script_test.set("src", "http://dev.a11y.in/alipi/ui.js")
276 script_test.set("src", "http://dev.a11y.in/server/ui.js")
277277 script_test.set("type", "text/javascript")
278278
279279 script_jq_mini = root.makeelement('script')
296296 root.body.append(style)
297297 style.set("rel","stylesheet")
298298 style.set("type", "text/css")
299 style.set("href", "http://dev.a11y.in/alipi/stylesheet.css")
299 style.set("href", "http://dev.a11y.in/server/stylesheet.css")
300300
301301 collection = g.db['post']
302302 if collection.find_one({"about" : request.args['foruri']}) is not None:
  
2020 {
2121 foruri = document.getElementById("inputurl").value;
2222 if(foruri.substring(0,7) == "http://") {
23 window.open("http://127.0.0.1:5000/?foruri=" + encodeURIComponent(foruri));
23 window.open("http://dev.a11y.in/web?foruri=" + encodeURIComponent(foruri));
2424 }
2525 else if (foruri.substring(0,8) == "https://") {
26 window.open("http://127.0.0.1:5000/?foruri=" + encodeURIComponent(foruri));
26 window.open("http://dev.a11y.in/web?foruri=" + encodeURIComponent(foruri));
2727 }
2828 else {
2929 alert("Please enter 'HTTP' protocoled URL");
test.html
(1 / 1)
  
88</stylesheet>
99</head>
1010<body style="margin: auto 10%;">
11 <img src="http://localhost/alipi-1/server/images/alipi.gif" style="position:relative; top:50px; left:25px; width:10%; height:20%;"></img>
11 <img src="http://dev.a11y.in/alipi.gif" style="position:relative; top:50px; left:25px; width:10%; height:20%;"></img>
1212<span style="position:relative; top:30px; left:20px; font-size:25px;"> Alipi.us</span>
1313<hr style="position:relative; top:30px;">
1414
  
1function page_edit( boltSlug, pageSlug, uploadSlug, editMode, hasEditPermission, successUrl)
2{
3
4 var console, PopupControl, M4ImageElement,locName='',langName = '',styleName='',authorValue;
5 var editAttributes, elementAttributes, fontTypeAttributes, normalFontAttributes, popupContainerAttributes, editButtonAttributes, editTextInputAttributes, editSubmitAttributes, editTitleAttributes, panelButtonAttributes, buttonPanelAttributes, actionPanelAttributes, closeButtonAttributes, actionButtonAttributes, redButtonAttributes, leftBorderStyle, rightBorderStyle, titleButtonImageAttributes, titleButtonDisplayTextAttributes, actionButtonImageAttributes, actionButtonDisplayTextAttributes,greyArrowAttributes, pageEditor, splashWindow, loadingTimerId, keepOriginal = false;
6
7 /**
8 * General utility class / functions.
9 */
10 var UTIL = UTIL || {};
11
12 (function(UTIL) {
13 UTIL.addEvent = function addEvent(node, event, callback) {
14 if (node.addEventListener) {
15 node.addEventListener(event, callback, false);
16 return true;
17 } else if (node.attachEvent) {
18 // Simulates W3C event model in IE
19 return node.attachEvent('on' + event, function() {
20 callback( {
21 target : window.event.srcElement,
22 pageX : window.event.clientX + (document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft),
23 pageY : window.event.clientY + (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop),
24 clientX : window.event.clientX,
25 clientY : window.event.clientY,
26 keyCode : window.event.keyCode,
27 ctrlKey : window.event.ctrlKey,
28 altKey : window.event.altKey,
29 shiftKey : window.event.shiftKey,
30 type : window.event.type,
31 preventDefault : function() {
32 window.event.returnValue = false;
33 },
34 stopPropagation : function() {
35 window.event.cancelBubble = true;
36 }
37 });
38 });
39 }
40 return false;
41 };
42
43 // String concatenation in <IE9 is really slow.
44 UTIL.StringBuffer = function StringBuffer() {
45 var buffer = [];
46 this.append = function append(string) {
47 buffer.push(string);
48 return this;
49 };
50
51 this.toString = function toString() {
52 return buffer.join('');
53 };
54 };
55
56 UTIL.forEach = function forEach(array, callback) {
57 var i = 0, length = array.length, value;
58
59 if (length) {
60 for (value = array[0]; i < length && callback.call(value, i, value) !== false; value = array[++i]) {
61 }
62 }
63 };
64
65 UTIL.animate = function animate(callback, steps, delay) {
66 var index = 1, timer;
67
68 timer = window.setInterval(function() {
69 if (index < steps) {
70 callback(index, false);
71 index += 1;
72 } else {
73 clearInterval(timer);
74 callback(index, true);
75 }
76 }, delay);
77 };
78
79 UTIL.hashToQueryString = function hashToQueryString(hash) {
80 var first = true, buffer = new UTIL.StringBuffer();
81
82 for (var key in hash) {
83 if (first) {
84 first = false;
85 } else {
86 buffer.append('&');
87 }
88 buffer.append(encodeURIComponent(key));
89 buffer.append('=');
90 buffer.append(encodeURIComponent(hash[key]));
91 }
92
93 return buffer.toString();
94 };
95 })(UTIL);
96 // //
97
98 /**
99 * DOM utility class / functions.
100 */
101 var DOM = DOM || {};
102
103 (function(DOM) {
104 // //
105
106 (function(__global__, undefined)
107 {
108
109 var modules = (typeof module !== 'undefined' && module.exports);
110
111 var document = (__global__.document || {
112 // Provide a dummy document object if we're not in a browser, to keep
113 // interpreters happy.
114 createElement: function(){},
115 createDocumentFragment: function(){},
116 createTextNode: function(){},
117 getElementById: function(){}
118 }),
119 toString = Object.prototype.toString,
120 slice = Array.prototype.slice,
121 // Functioms and objects involved in implementing cross-crowser workarounds
122 createElement,
123 eventAttrs,
124 addEvent,
125 setInnerHTML,
126 /** Tag names defined in the HTML 4.01 Strict and Frameset DTDs. */
127 tagNames = ("a abbr acronym address area b bdo big blockquote body br " +
128 "button caption cite code col colgroup dd del dfn div dl dt em fieldset " +
129 "form frame frameset h1 h2 h3 h4 h5 h6 hr head html i iframe img input " +
130 "ins kbd label legend li link map meta noscript " /* :) */ + "object ol " +
131 "optgroup option p param pre q samp script select small span strong style " +
132 "sub sup table tbody td textarea tfoot th thead title tr tt ul var").split(" "),
133 /** Lookup for known tag names. */
134 tagNameLookup = lookup(tagNames),
135 /** * Lookup for tags defined as EMPTY in the HTML 4.01 Strict and Frameset DTDs. */
136 emptyTags = lookup("area base br col frame hr input img link meta param".split(" "));
137
138 // Utility functions -----------------------------------------------------------
139
140 /**
141 * Naively copies from ``source`` to ``dest``, returning ``dest``.
142 */
143 function extend(dest, source)
144 {
145 for (var name in source)
146 {
147 dest[name] = source[name];
148 }
149 return dest;
150 }
151
152 /**
153 * Creates a lookup object from an array of strings.
154 */
155 function lookup(a)
156 {
157 var obj = {}, i = 0, l = a.length;
158 for (; i < l; i++)
159 {
160 obj[a[i]] = true;
161 }
162 return obj;
163 }
164
165 /**
166 * Uses a dummy constructor to make a ``child`` constructor inherit from a
167 * ``parent`` constructor.
168 */
169 function inheritFrom(child, parent)
170 {
171 function F() {};
172 F.prototype = parent.prototype;
173 child.prototype = new F();
174 child.prototype.constructor = child;
175 }
176
177 function isArray(o)
178 {
179 return (toString.call(o) === "[object Array]");
180 }
181
182 function isFunction(o)
183 {
184 return (toString.call(o) === "[object Function]");
185 }
186
187 /**
188 * We primarily want to distinguish between Objects and Nodes.
189 */
190 function isObject(o)
191 {
192 return (!!o && toString.call(o) === "[object Object]" &&
193 !o.nodeType &&
194 !(o instanceof SafeString))
195 }
196
197 /**
198 * Flattens an Array in-place, replacing any Arrays it contains with their
199 * contents, and flattening their contents in turn.
200 */
201 function flatten(a)
202 {
203 for (var i = 0, l = a.length; i < l; i++)
204 {
205 var c = a[i];
206 if (isArray(c))
207 {
208 // Make sure we loop to the Array's new length
209 l += c.length - 1;
210 // Replace the current item with its contents
211 Array.prototype.splice.apply(a, [i, 1].concat(c));
212 // Stay on the current index so we continue looping at the first
213 // element of the array we just spliced in or removed.
214 i--;
215 }
216 }
217 }
218
219 /**
220 * Escapes sensitive HTML characters.
221 */
222 function escapeHTML(s)
223 {
224 return s.split("&").join("&amp;")
225 .split("<").join("&lt;")
226 .split(">").join("&gt;")
227 .split('"').join("&quot;")
228 .split("'").join("&#39;");
229 }
230
231
232 eventAttrs = lookup(
233 ("blur focus focusin focusout load resize scroll unload click dblclick " +
234 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
235 "change select submit keydown keypress keyup error").split(" "));
236
237 if (!modules)
238 {
239 // jQuery is not available, implement the most essential workarounds
240 var supportsStyle = (function()
241 {
242 var div = document.createElement("div");
243 div.style.display = "none";
244 div.innerHTML = '<span style="color:silver;">s<span>';
245 return /silver/.test(div.getElementsByTagName("span")[0].getAttribute("style"));
246 })(),
247 specialRE = /^(?:href|src|style)$/,
248 attributeTranslations = {
249 cellspacing: "cellSpacing",
250 "class": "className",
251 colspan: "colSpan",
252 "for": "htmlFor",
253 frameborder: "frameBorder",
254 maxlength: "maxLength",
255 readonly: "readOnly",
256 rowspan: "rowSpan",
257 tabindex: "tabIndex",
258 usemap: "useMap"
259 };
260
261 createElement = function(tagName, attributes)
262 {
263 var el = document.createElement(tagName); // Damn you, IE
264
265 for (var name in attributes)
266 {
267 var value = attributes[name],
268 name = attributeTranslations[name] || name;
269
270 if (name in eventAttrs)
271 {
272 el["on" + name] = value;
273 continue;
274 }
275
276 var special = specialRE.test(name);
277 //if ((name in el || el[name] !== undefined) && !special)
278 //el[name] = value;
279 if (!supportsStyle && name == "style")
280 el.style.cssText = ""+value;
281 else
282 el.setAttribute(name, ""+value);
283 }
284
285 return el;
286 };
287
288 addEvent = function(id, event, handler)
289 {
290 document.getElementById(id)["on" + event] = handler;
291 };
292
293 setInnerHTML = function(el, html)
294 {
295 try
296 {
297 el.innerHTML = html;
298 }
299 catch (e)
300 {
301 var div = document.createElement("div");
302 div.innerHTML = html;
303 while (el.firstChild)
304 el.removeChild(el.firstChild);
305 while (div.firstChild)
306 el.appendChild(div.firstChild);
307 }
308 };
309 }
310
311
312 // HTML Escaping ---------------------------------------------------------------
313
314 /**
315 * If the given input is a ``SafeString``, returns its value; otherwise, coerces
316 * to ``String`` and escapes.
317 */
318 function conditionalEscape(html)
319 {
320 if (html instanceof SafeString)
321 {
322 return html.value;
323 }
324 return escapeHTML(""+html);
325 }
326
327 /**
328 * ``String`` subclass which marks the given string as safe for inclusion
329 * without escaping.
330 */
331 function SafeString(value)
332 {
333 this.value = value;
334 }
335
336 inheritFrom(SafeString, String);
337
338 SafeString.prototype.toString = SafeString.prototype.valueOf = function()
339 {
340 return this.value;
341 };
342
343 // Mock DOM Elements -----------------------------------------------------------
344
345 /**
346 * Partially emulates a DOM ``Node`` for HTML generation.
347 */
348 function HTMLNode(childNodes)
349 {
350 this.childNodes = childNodes || [];
351
352 // Ensure HTMLFragment contents are inlined, as if this object's child
353 // nodes were appended one-by-one.
354 this._inlineFragments();
355 }
356
357 inheritFrom(HTMLNode, Object);
358
359 /**
360 * Replaces any ``HTMLFragment`` objects in child nodes with their own
361 * child nodes and empties the fragment.
362 */
363 HTMLNode.prototype._inlineFragments = function()
364 {
365 for (var i = 0, l = this.childNodes.length; i < l; i++)
366 {
367 var child = this.childNodes[i];
368 if (child instanceof HTMLFragment)
369 {
370 this.childNodes.splice.apply(this.childNodes,
371 [i, 1].concat(child.childNodes));
372 // Clear the fragment on append, as per DocumentFragment
373 child.childNodes = [];
374 }
375 }
376 };
377
378 /**
379 * Emulates ``appendChild``, inserting fragment child node contents and
380 * emptying the fragment if one is given.
381 */
382 HTMLNode.prototype.appendChild = function(node)
383 {
384 if (node instanceof HTMLFragment)
385 {
386 this.childNodes = this.childNodes.concat(node.childNodes);
387 // Clear the fragment on append, as per DocumentFragment
388 node.childNodes = [];
389 }
390 else
391 {
392 this.childNodes.push(node);
393 }
394 };
395
396 /**
397 * Emulates ``cloneNode`` so cloning of ``HTMLFragment`` objects works
398 * as expected.
399 */
400 HTMLNode.prototype.cloneNode = function(deep)
401 {
402 var clone = this._clone();
403 if (deep === true)
404 {
405 for (var i = 0, l = this.childNodes.length; i < l; i++)
406 {
407 var node = this.childNodes[i];
408 if (node instanceof HTMLElement)
409 {
410 clone.childNodes.push(node.cloneNode(deep));
411 }
412 else
413 {
414 clone.childNodes.push(node);
415 }
416 }
417 }
418 return clone;
419 };
420
421 /**
422 * Creates the object to be used for deep cloning.
423 */
424 HTMLNode.prototype._clone = function()
425 {
426 return new Node();
427 };
428
429 /**
430 * Partially emulates a DOM ``Element ``for HTML generation.
431 */
432 function HTMLElement(tagName, attributes, childNodes)
433 {
434 HTMLNode.call(this, childNodes);
435
436 this.tagName = this.nodeName = tagName.toLowerCase();
437 this.attributes = attributes || {};
438
439 // Keep a record of whether or not closing slashes are needed, as the
440 // mode could change before this object is coerced to a String.
441 this.xhtml = (DOMBuilder.mode == "XHTML");
442 }
443
444 inheritFrom(HTMLElement, HTMLNode);
445
446 HTMLElement.eventTrackerId = 1;
447
448 HTMLElement.prototype.nodeType = 1;
449
450 HTMLElement.prototype._clone = function()
451 {
452 var clone = new HTMLElement(this.tagName, extend({}, this.attributes));
453 clone.xhtml = this.xhtml;
454 return clone;
455 };
456
457 /**
458 * Creates an HTML/XHTML representation of an HTMLElement.
459 *
460 * If ``true`` is passed as an argument and any event attributes are found, this
461 * method will ensure the resulting element has an id so the handlers for the
462 * event attributes can be registered after the element has been inserted into
463 * the document via ``innerHTML``.
464 *
465 * If necessary, a unique id will be generated.
466 */
467 HTMLElement.prototype.toString = function()
468 {
469 var trackEvents = arguments[0] || false,
470 tagName = (tagNameLookup[this.tagName]
471 ? this.tagName
472 : conditionalEscape(this.tagName));
473
474 // Opening tag
475 var parts = ["<" + tagName];
476 for (var attr in this.attributes)
477 {
478 // innerHTML is a special case, as we can use it to (perhaps
479 // inadvisedly) to specify entire contents as a string.
480 if (attr === "innerHTML")
481 {
482 continue;
483 }
484 // Don't create attributes which wouldn't make sense in HTML mode -
485 // they can be dealt with afet insertion using addEvents().
486 if (attr in eventAttrs)
487 {
488 if (trackEvents === true && !this.eventsFound)
489 {
490 this.eventsFound = true;
491 }
492 continue;
493 }
494 parts.push(" " + conditionalEscape(attr.toLowerCase()) + "=\"" +
495 conditionalEscape(this.attributes[attr]) + "\"");
496 }
497 if (this.eventsFound && !("id" in this.attributes))
498 {
499 // Ensure an id is present so we can grab this element later
500 this.id = "__DB" + HTMLElement.eventTrackerId++ + "__";
501 parts.push(' id="' + this.id + '"');
502 }
503 parts.push(">");
504
505 if (emptyTags[tagName])
506 {
507 if (this.xhtml)
508 {
509 parts.splice(parts.length - 1, 1, " />");
510 }
511 return parts.join("");
512 }
513
514 // If innerHTML was given, use it exclusively for the contents
515 if ("innerHTML" in this.attributes)
516 {
517 parts.push(this.attributes.innerHTML);
518 }
519 else
520 {
521 for (var i = 0, l = this.childNodes.length; i < l; i++)
522 {
523 var node = this.childNodes[i];
524 if (node instanceof HTMLElement || node instanceof SafeString)
525 {
526 parts.push(node.toString(trackEvents));
527 }
528 else if (node === "\u00A0")
529 {
530 // Special case to convert these back to entities,
531 parts.push("&nbsp;");
532 }
533 else
534 {
535 // Coerce to string and escape
536 parts.push(escapeHTML(""+node));
537 }
538 }
539 }
540
541 // Closing tag
542 parts.push("</" + tagName + ">");
543 return parts.join("");
544 };
545
546 /**
547 * If event attributes were found when ``toString(true)`` was called, this
548 * method will retrieve the resulting DOM Element by id, attach event handlers
549 * to it and call ``addEvents`` on any HTMLElement children.
550 */
551 HTMLElement.prototype.addEvents = function()
552 {
553 if (this.eventsFound)
554 {
555 var id = ("id" in this.attributes
556 ? conditionalEscape(this.attributes.id)
557 : this.id);
558 for (var attr in this.attributes)
559 {
560 if (attr in eventAttrs)
561 {
562 addEvent(id, attr, this.attributes[attr]);
563 }
564 }
565
566 delete this.eventsFound;
567 delete this.id;
568 }
569
570 for (var i = 0, l = this.childNodes.length; i < l; i++)
571 {
572 var node = this.childNodes[i];
573 if (node instanceof HTMLElement)
574 {
575 node.addEvents();
576 }
577 }
578 };
579
580 HTMLElement.prototype.insertWithEvents = function(el)
581 {
582 setInnerHTML(el, this.toString(true));
583 this.addEvents();
584 };
585
586 /**
587 * Partially emulates a DOM ``DocumentFragment`` for HTML generation.
588 */
589 function HTMLFragment(childNodes)
590 {
591 HTMLNode.call(this, childNodes);
592 }
593 inheritFrom(HTMLFragment, HTMLNode);
594
595 HTMLFragment.prototype._clone = function()
596 {
597 return new HTMLFragment();
598 };
599
600 HTMLFragment.prototype.nodeType = 11;
601 HTMLFragment.prototype.nodeName = "#document-fragment";
602
603 /**
604 * Creates an HTML/XHTML representation of an HTMLFragment.
605 *
606 * If ``true``is passed as an argument, it will be passed on to
607 * any child HTMLElements when their ``toString()`` is called.
608 */
609 HTMLFragment.prototype.toString = function()
610 {
611 var trackEvents = arguments[0] || false,
612 parts = [];
613
614 // Contents
615 for (var i = 0, l = this.childNodes.length; i < l; i++)
616 {
617 var node = this.childNodes[i];
618 if (node instanceof HTMLElement || node instanceof SafeString)
619 {
620 parts.push(node.toString(trackEvents));
621 }
622 else if (node === "\u00A0")
623 {
624 // Special case to convert these back to entities,
625 parts.push("&nbsp;");
626 }
627 else
628 {
629 // Coerce to string and escape
630 parts.push(escapeHTML(""+node));
631 }
632 }
633
634 return parts.join("");
635 };
636
637 /**
638 * Calls ``addEvents()`` on any HTMLElement children.
639 */
640 HTMLFragment.prototype.addEvents = function()
641 {
642 for (var i = 0, l = this.childNodes.length; i < l; i++)
643 {
644 var node = this.childNodes[i];
645 if (node instanceof HTMLElement)
646 {
647 node.addEvents();
648 }
649 }
650 };
651
652 HTMLFragment.prototype.insertWithEvents = function(el)
653 {
654 setInnerHTML(el, this.toString(true));
655 this.addEvents();
656 };
657
658 /**
659 * Creates a function which, when called, uses DOMBuilder to create an element
660 * with the given ``tagName``.
661 *
662 * The resulting function will also have a ``map`` function which calls
663 * ``DOMBuilder.map`` with the given ``tagName``.
664 */
665 function createElementFunction(tagName)
666 {
667 var elementFunction = function()
668 {
669 if (arguments.length === 0)
670 {
671 // Short circuit if there are no arguments, to avoid further
672 // argument inspection.
673 if (DOMBuilder.mode == "DOM")
674 {
675 return document.createElement(tagName);
676 }
677 else
678 {
679 return new HTMLElement(tagName);
680 }
681 }
682 else
683 {
684 return createElementFromArguments(tagName, slice.call(arguments));
685 }
686 };
687
688 // Add a ``map`` function which will call ``DOMBuilder.map`` with the
689 // appropriate ``tagName``.
690 elementFunction.map = function()
691 {
692 var mapArgs = slice.call(arguments);
693 mapArgs.unshift(tagName);
694 return DOMBuilder.map.apply(DOMBuilder, mapArgs);
695 };
696
697 return elementFunction;
698 }
699
700 /**
701 * Normalises a list of arguments in order to create a new DOM element
702 * using ``DOMBuilder.createElement``. Supported argument formats are:
703 *
704 * ``(attributes, child1, ...)``
705 * an attributes object followed by an arbitrary number of children.
706 * ``(attributes, [child1, ...])``
707 * an attributes object and an ``Array`` of children.
708 * ``(child1, ...)``
709 * an arbitrary number of children.
710 * ``([child1, ...])``
711 * an ``Array`` of children.
712 *
713 * At least one argument *must* be provided.
714 */
715 function createElementFromArguments(tagName, args)
716 {
717 var attributes, children,
718 // The short circuit in ``createElementFunction`` ensures we will
719 // always have at least one argument when called via element creation
720 // functions.
721 argsLength = args.length, firstArg = args[0];
722
723 if (argsLength === 1 &&
724 isArray(firstArg))
725 {
726 children = firstArg; // ([child1, ...])
727 }
728 else if (isObject(firstArg))
729 {
730 attributes = firstArg;
731 children = (argsLength == 2 && isArray(args[1])
732 ? args[1] // (attributes, [child1, ...])
733 : slice.call(args, 1)); // (attributes, child1, ...)
734 }
735 else
736 {
737 children = slice.call(args); // (child1, ...)
738 }
739
740 return DOMBuilder.createElement(tagName, attributes, children);
741 }
742
743 // DOMBuilder API --------------------------------------------------------------
744
745 var DOMBuilder = {
746 version: "1.4.3",
747
748 /**
749 * Determines which mode the ``createElement`` function will operate in.
750 * Supported values are:
751 *
752 * ``"DOM"``
753 * create DOM Elements.
754 * ``"HTML"``
755 * create HTML Strings.
756 * ``"XHTML"``
757 * create XHTML Strings.
758 *
759 * The value depends on the environment we're running in - if modules are
760 * available, we default to HTML mode, otherwise we assume we'te in a
761 * browser and default to DOM mode.
762 */
763 mode: (modules ? "HTML" : "DOM"),
764
765 /**
766 * Calls a function using DOMBuilder temporarily in the given mode and
767 * returns its output.
768 *
769 * This is primarily intended for using DOMBuilder to generate HTML
770 * strings when running in the browser without having to manage the
771 * mode flag yourself.
772 */
773 withMode: function(mode, func)
774 {
775 var originalMode = this.mode;
776 this.mode = mode;
777 try
778 {
779 return func();
780 }
781 finally
782 {
783 this.mode = originalMode;
784 }
785 },
786
787 /**
788 * An ``Object`` containing element creation functions.
789 */
790 elementFunctions: (function(obj)
791 {
792 for (var i = 0, tagName; tagName = tagNames[i]; i++)
793 {
794 obj[tagName.toUpperCase()] = createElementFunction(tagName);
795 }
796 return obj;
797 })({}),
798
799 /**
800 * Adds element creation functions to a given context ``Object``, or to
801 * a new object if none was given. Returns the object the functions were
802 * added to, either way.
803 *
804 * An ``NBSP`` property corresponding to the Unicode character for a
805 * non-breaking space is also added to the context object, for
806 * convenience.
807 */
808 apply: function(context)
809 {
810 context = context || {};
811 extend(context, this.elementFunctions);
812 context.NBSP = "\u00A0"; // Add NBSP for backwards-compatibility
813 return context;
814 },
815
816 /**
817 * Creates a DOM element with the given tag name and, optionally,
818 * the given attributes and children.
819 */
820 createElement: function(tagName, attributes, children)
821 {
822 attributes = attributes || {};
823 children = children || [];
824 flatten(children);
825
826 if (this.mode != "DOM")
827 {
828 return new HTMLElement(tagName, attributes, children);
829 }
830
831 // Create the element and set its attributes and event listeners
832 var el = createElement(tagName, attributes);
833
834 // If content was set via innerHTML, we're done...
835 if (!("innerHTML" in attributes))
836 {
837 // ...otherwise, append children
838 for (var i = 0, l = children.length; i < l; i++)
839 {
840 var child = children[i];
841 if (child && child.nodeType)
842 {
843 el.appendChild(child);
844 }
845 else
846 {
847 el.appendChild(document.createTextNode(""+child));
848 }
849 }
850 }
851 return el;
852 },
853
854 /**
855 * Creates an element for (potentially) every item in a list. Supported
856 * argument formats are:
857 *
858 * 1. ``(tagName, defaultAttributes, [item1, ...], mappingFunction)``
859 * 2. ``(tagName, [item1, ...], mappingFunction)``
860 *
861 * Arguments are as follows:
862 *
863 * ``tagName``
864 * the name of the element to create.
865 * ``defaultAttributes`` (optional)
866 * default attributes for the element.
867 * ``items``
868 * the list of items to use as the basis for creating elements.
869 * ``mappingFunction`` (optional)
870 * a function to be called with each item in the list to provide
871 * contents for the element which will be created for that item.
872 *
873 * Contents can consist of a single value or a mixed ``Array``.
874 *
875 * If provided, the function will be called with the following
876 * arguments::
877 *
878 * func(item, attributes, itemIndex)
879 *
880 * Attributes on the element which will be created can be altered by
881 * modifying the ``attributes argument, which will initially contain
882 * the contents of ``defaultAttributes``, if it was provided.
883 *
884 * The function can prevent an element being generated for a given
885 * item by returning ``null``.
886 *
887 * If not provided, each item will result in the creation of a new
888 * element and the item itself will be used as the only contents.
889 */
890 map: function(tagName)
891 {
892 // Determine how the function was called
893 if (isArray(arguments[1]))
894 {
895 // (tagName, items, func)
896 var defaultAttrs = {},
897 items = arguments[1],
898 func = (isFunction(arguments[2]) ? arguments[2] : null);
899 }
900 else
901 {
902 // (tagName, attrs, items, func)
903 var defaultAttrs = arguments[1],
904 items = arguments[2],
905 func = (isFunction(arguments[3]) ? arguments[3] : null);
906 }
907
908 var results = [];
909 for (var i = 0, l = items.length; i < l; i++)
910 {
911 var attrs = extend({}, defaultAttrs);
912 // If we were given a mapping function, call it and use the
913 // return value as the contents, unless the function specifies
914 // that the item shouldn't generate an element by explicity
915 // returning null.
916 if (func !== null)
917 {
918 var children = func(items[i], attrs, i);
919 if (children === null)
920 {
921 continue;
922 }
923 }
924 else
925 {
926 // If we weren't given a mapping function, use the item as the
927 // contents.
928 var children = items[i];
929 }
930
931 // Ensure children are in an Array, as required by createElement
932 if (!isArray(children))
933 {
934 children = [children];
935 }
936
937 results.push(this.createElement(tagName, attrs, children));
938 }
939 return results;
940 },
941
942 /**
943 * Creates a ``DocumentFragment`` with the given children. Supported
944 * argument formats are:
945 *
946 * ``(child1, ...)``
947 * an arbitrary number of children.
948 * ``([child1, ...])``
949 * an ``Array`` of children.
950 *
951 * A ``DocumentFragment`` conveniently allows you to append its contents
952 * with a single call. If you're thinking of adding a wrapper ``<div>``
953 * solely to be able to insert a number of sibling elements at the same
954 * time, a ``DocumentFragment`` will do the same job without the need for
955 * a redundant wrapper element.
956 *
957 * See http://ejohn.org/blog/dom-documentfragments/ for more information
958 * about ``DocumentFragment`` objects.
959 */
960 fragment: function()
961 {
962 if (arguments.length === 1 &&
963 isArray(arguments[0]))
964 {
965 var children = arguments[0]; // ([child1, ...])
966 }
967 else
968 {
969 var children = slice.call(arguments) // (child1, ...)
970 }
971
972 // Inline the contents of any child Arrays
973 flatten(children);
974
975 if (this.mode != "DOM")
976 {
977 return new HTMLFragment(children);
978 }
979
980 var fragment = document.createDocumentFragment();
981 for (var i = 0, l = children.length; i < l; i++)
982 {
983 var child = children[i];
984 if (child.nodeType)
985 {
986 fragment.appendChild(child);
987 }
988 else
989 {
990 fragment.appendChild(document.createTextNode(""+child));
991 }
992 }
993
994 return fragment;
995 },
996
997 /**
998 * Marks a string as safe
999 */
1000 markSafe: function(value)
1001 {
1002 return new SafeString(value);
1003 },
1004
1005 /**
1006 * Determines if a string is safe.
1007 */
1008 isSafe: function(value)
1009 {
1010 return (value instanceof SafeString);
1011 },
1012
1013 HTMLElement: HTMLElement,
1014 HTMLFragment: HTMLFragment,
1015 HTMLNode: HTMLNode,
1016 SafeString: SafeString
1017 };
1018
1019 /**
1020 * Creates a fragment wrapping content created for every item in a
1021 * list.
1022 *
1023 * Arguments are as follows:
1024 *
1025 * ``items``
1026 * the list of items to use as the basis for creating fragment
1027 * contents.
1028 * ``mappingFunction``
1029 * a function to be called with each item in the list, to provide
1030 * contents for the fragment.
1031 *
1032 * Contents can consist of a single value or a mixed ``Array``.
1033 *
1034 * The function will be called with the following arguments::
1035 *
1036 * func(item, itemIndex)
1037 *
1038 * The function can indicate that the given item shouldn't generate
1039 * any content for the fragment by returning ``null``.
1040 */
1041 DOMBuilder.fragment.map = function(items, func)
1042 {
1043 // If we weren't given a mapping function, the user may as well just
1044 // have created a fragment directly, as we're just wrapping content
1045 // here, not creating it.
1046 if (!isFunction(func))
1047 {
1048 return DOMBuilder.fragment(items);
1049 }
1050
1051 var results = [];
1052 for (var i = 0, l = items.length; i < l; i++)
1053 {
1054 // Call the mapping function and add the return value to the
1055 // fragment contents, unless the function specifies that the item
1056 // shouldn't generate content by explicity returning null.
1057 var children = func(items[i], i);
1058 if (children === null)
1059 {
1060 continue;
1061 }
1062 results = results.concat(children);
1063 }
1064 return DOMBuilder.fragment(results);
1065 };
1066
1067 // Export DOMBuilder or expose it to the global object
1068 if (modules)
1069 {
1070 module.exports = DOMBuilder;
1071 }
1072 else
1073 {
1074 __global__.DOMBuilder = DOMBuilder;
1075 }
1076
1077 })(this);
1078
1079
1080 DOM.BUILDER = DOMBuilder.apply();
1081
1082 DOM.getIndex = function getIndex (currentNode)
1083 {
1084 var kids = currentNode.parentNode.childNodes;
1085 var j = 0;
1086 for(var i=0; i< kids.length; i++)
1087 {
1088 if (currentNode.nodeName == kids[i].nodeName)
1089 j++;
1090 if (currentNode == kids[i])
1091 {
1092 return j;
1093 }
1094 else
1095 continue;
1096 }
1097 return -1;
1098 };
1099
1100 DOM.getElementIdx = function getElementIdx(elt)
1101 {
1102 var count = 1;
1103 for (var sib = elt.previousSibling; sib ; sib = sib.previousSibling)
1104 {
1105 if(sib.nodeType == 1 && sib.tagName == elt.tagName)count++
1106 }
1107
1108 return count;
1109 };
1110
1111 DOM.makePath = function makePath(elt){
1112 var path = '';
1113 for (; elt && elt.nodeType == 1; elt = elt.parentNode)
1114 {
1115 if (elt.attributes['m4pageedittype'] === undefined || elt.attributes['m4pageedittype'].nodeValue != 'text')
1116 {
1117 idx = DOM.getElementIdx(elt);
1118 xname = elt.tagName;
1119 if (idx > 1) xname += "[" + idx + "]";
1120 path = "/" + xname + path;
1121 }
1122 }
1123 return path;
1124 };
1125
1126 DOM.evaluate = function evaluate(path,newcontent){
1127 var nodes = document.evaluate(path, document, null, XPathResult.ANY_TYPE,null);
1128 try{
1129 var result = nodes.iterateNext();
1130 while (result)
1131 {
1132 if (result.tagName == "img" || result.tagName =='IMG'){
1133 url=newcontent.split(',')[1];
1134 size = newcontent.split(',')[0].split('x');
1135 width = size[0];
1136 height = size[1];
1137 result.setAttribute('src',url)
1138 result.setAttribute('width',width);
1139 result.setAttribute('height',height);
1140
1141 }
1142 else{
1143 result.textContent = newcontent;
1144 }
1145 result=nodes.iterateNext();
1146 }
1147 }
1148 catch (e)
1149 {
1150 dump( 'error: Document tree modified during iteration ' + e );
1151 }
1152
1153 }
1154
1155 DOM.getXPATH = function getXPath(element)
1156 {
1157 var doc = document;
1158 //we get the selections
1159 var selection = window.getSelection();
1160 var str = '';
1161 //var currentNode = selection.getRangeAt(i).commonAncestorContainer;
1162 var currentNode = element;
1163 var path = '';
1164 var index = -1;
1165 if ( currentNode == undefined) {
1166 currentNode = document.getElementById("alipiSelectedElement");
1167 }
1168
1169 if (currentNode.nodeName != "#text")
1170 {
1171 path = DOM.makePath(currentNode);
1172 }
1173 else
1174 {
1175 path = DOM.makePath(currentNode.parentNode);
1176 }
1177
1178
1179 return path;
1180 };
1181
1182 DOM.findPosition = function findPosition(element) {
1183 var currentLeft = 0, currentTop = 0;
1184
1185 if (element.offsetParent) {
1186 do {
1187 currentLeft += element.offsetLeft;
1188 currentTop += element.offsetTop;
1189 } while (element = element.offsetParent);
1190 }
1191
1192 return { x : currentLeft, y : currentTop };
1193 };
1194
1195 DOM.findSize = function findSize(element) {
1196 return { width : element.clientWidth, height: element.clientHeight };
1197 };
1198
1199 DOM.clickBlocker = function clickBlocker(element) {
1200 var size = DOM.findSize(element), position;
1201
1202 if (size.width > 0 && size.height > 0) {
1203 position = DOM.findPosition(element);
1204
1205 document.body.appendChild(DOM.BUILDER.DIV( { style : 'background: transparent; z-index: 2147483644; width:'
1206 + (size.width + 'px') + '; height:' + (size.height + 'px')
1207 + '; position: absolute; left:' + (position.x + 'px') + '; top:' + (position.y + 'px') + ';' }));
1208 }
1209 };
1210
1211 DOM.overrideStyleProperty = function overrideStyleProperty(object, property, value) {
1212 var savedName = 'm4p' + property.toUpperCase();
1213
1214 object.style[savedName] = object.style[property];
1215 object.style[property] = value;
1216 };
1217
1218 DOM.restoreStyleProperty = function restoreStyleProperty(object, property, fallback) {
1219 var savedName = 'm4p' + property.toUpperCase();
1220
1221 if (object.style[savedName] !== undefined) {
1222 object.style[property] = object.style[savedName];
1223 } else {
1224 object.style[property] = fallback;
1225 }
1226
1227 object.style[savedName] = undefined;
1228 };
1229
1230 DOM.deleteStyleProperty = (function() {
1231 if (typeof document.createElement('div').style.removeAttribute !== 'undefined') {
1232 // IE specific
1233 return function deleteStyleProperty(object, property) {
1234 object.style.removeAttribute(property);
1235 };
1236 } else {
1237 // W3C standard
1238 return function deleteStyleProperty(object, property) {
1239 object.style.removeProperty(property);
1240 };
1241 }
1242 })();
1243
1244 // Not to be used for Style attributes. For style attributes use overrideStyleProperty instead
1245 DOM.overrideAttribute = function overrideAttribute (object, attributeName, value) {
1246 var savedName = 'm4p' + attributeName.toUpperCase();
1247 if (object[attributeName]) {
1248 var attributeValue = object.getAttribute(attributeName);
1249 if (attributeValue) {
1250 object.setAttribute(savedName, attributeValue);
1251 }
1252 }
1253 object.setAttribute(attributeName, value);
1254 };
1255
1256 // Not to be used for Style attributes. For style attributes use restoreStyleProperty instead
1257 DOM.restoreAttribute = function restoreAttribute (object, attributeName) {
1258 var savedName = 'm4p' + attributeName.toUpperCase();
1259 if (object[attributeName]) {
1260 var originalValue = object.getAttribute(savedName);
1261 if (originalValue != null) {
1262 object.setAttribute(attributeName, originalValue);
1263 object.removeAttribute(savedName);
1264 } else {
1265 object.removeAttribute(attributeName);
1266 }
1267 }
1268 };
1269
1270 DOM.addListener = (function() {
1271 if (document.attachEvent) {
1272 // Simulates W3C event model in IE
1273 return function addListener(type, callback, capture) {
1274 document.attachEvent('on' + type, function() {
1275 callback( {
1276 target : window.event.srcElement,
1277 pageX : window.event.clientX + (document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft),
1278 pageY : window.event.clientY + (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop),
1279 clientX : window.event.clientX,
1280 clientY : window.event.clientY,
1281 keyCode : window.event.keyCode,
1282 ctrlKey : window.event.ctrlKey,
1283 preventDefault : function() {
1284 window.event.returnValue = false;
1285 },
1286 stopPropagation : function() {
1287 window.event.cancelBubble = true;
1288 }
1289 });
1290 });
1291 }
1292 } else {
1293 return function addListener(type, callback, capture) {
1294 document.addEventListener(type, callback, capture);
1295 };
1296 }
1297 })();
1298
1299 DOM.textContent = (function() {
1300 if (document.all) {
1301 // IE specific
1302 return function textContent(element, content) {
1303 if (content) {
1304 element.innerText = content;
1305 }
1306 return element.innerText;
1307 }
1308 } else {
1309 return function textContent(element, content) {
1310 if (element == undefined) {
1311 element = document.getElementById("alipiSelectedElement");
1312 content = document.getElementById("alipiSelectedElement").textContent;
1313 element.textContent = content;
1314 } else if (content) {
1315 element.textContent = content;
1316 }
1317 return element.textContent;
1318 }
1319 }
1320 })();
1321
1322 DOM.viewDimension = function viewDimension() {
1323 var width, height;
1324 if (window.innerWidth) {
1325 width = window.innerWidth;
1326 } else if (document.documentElement && document.documentElement.clientWidth) {
1327 width = document.documentElement.clientWidth;
1328 } else if (document.body) {
1329 width = document.body.clientWidth;
1330 }
1331
1332 if (window.innerHeight) {
1333 height = window.innerHeight;
1334 } else if (document.documentElement && document.documentElement.clientHeight) {
1335 height = document.documentElement.clientHeight;
1336 } else if (document.body) {
1337 height = document.body.clientHeight;
1338 }
1339
1340 return [ width, height ];
1341 };
1342
1343 DOM.isElementOfType = function isElementOfType(element, tagName) {
1344 return (element && element.nodeName && tagName && element.tagName.toLowerCase() == tagName.toLowerCase()) ;
1345 };
1346
1347 DOM.isQuirksMode = function isQuirksMode() {
1348
1349 return ( (document.documentMode && document.documentMode == 5)
1350 || (document.compatMode && document.compatMode == 'BackCompat')) ;
1351 }
1352
1353 /*
1354 * Use this with caution..
1355 */
1356 DOM.isIEBrowser = function isIEBrowser() {
1357 return (window.navigator.appName == 'Microsoft Internet Explorer');
1358 }
1359
1360 // Immutable set of DOM Element Attributes
1361 DOM.Attributes = function(initialAttributes, additionalAttributes) {
1362 var self = this, attributes = {}, attribute;
1363
1364 var set = function(moreAttributes) {
1365 if (moreAttributes instanceof DOM.Attributes) {
1366 moreAttributes = moreAttributes.values();
1367 }
1368
1369 for (attribute in moreAttributes) {
1370 attributes[attribute] = moreAttributes[attribute];
1371 }
1372 };
1373
1374 set(initialAttributes);
1375 if (additionalAttributes) {
1376 set(additionalAttributes)
1377 }
1378
1379 this.addStyle = function(value) {
1380 var style;
1381
1382 if (attributes['style']) {
1383 // later inline styles override
1384 style = attributes['style'] + ' ' + value;
1385 } else {
1386 style = value;
1387 }
1388
1389 return new DOM.Attributes(attributes, { 'style': style });
1390 };
1391
1392 this.put = function(moreAttributes) {
1393 return new DOM.Attributes(attributes, moreAttributes)
1394 };
1395
1396 this.values = function() {
1397 var result = {};
1398 for (attribute in attributes) {
1399 result[attribute] = attributes[attribute];
1400 }
1401 return result;
1402 }
1403 };
1404 })(DOM);
1405 // //
1406
1407 /**
1408 * AJAX utility class / functions.
1409 */
1410 var AJAX = AJAX || {};
1411
1412 (function(AJAX) {
1413 AJAX.createXmlHttpRequest = function createXmlHttpRequest() {
1414 if (window.ActiveXObject) {
1415 return new ActiveXObject("Microsoft.XMLHTTP");
1416 } else {
1417 return new XMLHttpRequest();
1418 }
1419 };
1420
1421 AJAX.get = function get(url, callback) {
1422 return AJAX.ajax('GET', url, null, callback);
1423 };
1424
1425 AJAX.post = function post(url, data, callback, contentType) {
1426 return AJAX.ajax('POST', url, data, callback, contentType);
1427 };
1428
1429 // @param contentType, defaults to 'application/x-www-form-urlencoded; charset=UTF-8', optional
1430 AJAX.ajax = function ajax(method, url, data, callback, contentType) {
1431 var http = AJAX.createXmlHttpRequest();
1432 var defaultContentType = 'application/x-www-form-urlencoded; charset=UTF-8';
1433 if (!contentType) {
1434 contentType = defaultContentType;
1435 }
1436 if (callback) {
1437 // async
1438 http.open(method, url, true);
1439 if (method === 'POST') {
1440 // must be set after open()
1441 http.setRequestHeader('Content-type', contentType);
1442 }
1443 http.onreadystatechange = function ajaxOnReadyStateChangeHandler() {
1444 if (http.readyState === 4) {
1445 callback(http);
1446 }
1447 };
1448 http.send(data);
1449 } else {
1450 // sync
1451 http.open(method, url, false);
1452 if (method === 'POST') {
1453 // must be set after open()
1454 http.setRequestHeader('Content-type', contentType);
1455 }
1456 http.send(data);
1457 return http;
1458 }
1459 };
1460 })(AJAX);
1461
1462 if (typeof window.console == 'undefined') {
1463 console = {
1464 log : function() {
1465 },
1466 error : function() {
1467 },
1468 warn : function() {
1469 },
1470 info : function() {
1471 },
1472 dir : function() {
1473 }
1474 }
1475 } else {
1476 console = window.console;
1477 }
1478
1479 editAttributes = new DOM.Attributes({ 'm4pageeditcontrol': true });
1480 elementAttributes = editAttributes.addStyle('margin:0; padding:0; border:none; text-indent: 0px; background: none;');
1481 fontTypeAttributes = elementAttributes.addStyle("font-family: Helvetica Neue, Helvetica, Arial, Sans-serif;");
1482 normalFontAttributes = fontTypeAttributes.addStyle("font-weight:bold; font-size:12px; line-height: 10px;");
1483
1484 leftBorderStyle = 'border-top-left-radius:3px; border-bottom-left-radius:3px; -moz-border-radius-topleft:3px; -moz-border-radius-bottomleft:3px; -webkit-border-top-left-radius:3px; -webkit-border-bottom-left-radius:3px;';
1485 rightBorderStyle = 'border-top-right-radius:3px; border-bottom-right-radius:3px; -moz-border-radius-topright:3px; -moz-border-radius-bottomright:3px; -webkit-border-top-right-radius:3px; -webkit-border-bottom-right-radius:3px;';
1486
1487 editTextInputAttributes = normalFontAttributes.put({ type : 'text' }).addStyle('width: 70%; float:left; font-weight:normal;color: #747474; border:1px solid #747474; outline-style:none; outline-width:0px; margin:0; padding:2px; margin-left: 0px;').addStyle(leftBorderStyle + rightBorderStyle);
1488 editTitleAttributes = normalFontAttributes.addStyle("color:#fff; background-color:#333; float:left; padding:3px; border-top-left-radius:3px; border-bottom-left-radius:3px; -moz-border-radius-topleft:3px; -moz-border-radius-bottomleft:3px; -webkit-border-top-left-radius:3px; -webkit-border-bottom-left-radius:3px;");
1489
1490 panelButtonAttributes = fontTypeAttributes.addStyle('height:auto; cursor:pointer; float:right; font-weight:normal; font-size:14px; background-image:none; border-radius:5px; -moz-border-radius:5px; -webkit-border-radius:5px; margin: 16px 16px 0 0; padding: 0 0 4px 0;-khtml-box-sizing: none;-webkit-box-sizing: none;-moz-box-sizing: none;box-sizing: none;text-shadow:none;');
1491 editButtonAttributes = normalFontAttributes.addStyle(" height:45px;float:left; position:relative; cursor:pointer;border-top:1px solid #BDBDBD;border-left:1px solid #BDBDBD;border-right:1px solid #BDBDBD;border-bottom:1px solid #BDBDBD;color:#000;background-color:#FFF;margin: 0px;padding: 0px;");
1492
1493 var closeButtonIconPath = 'http://dev.a11y.in/alipi/images/close_button.png';
1494 closeButtonAttributes = editButtonAttributes.addStyle('top: -8px; left: -8px; position: absolute; border:none; background: url("' + closeButtonIconPath +'") no-repeat; width: 15px; height: 15px; z-index: 2;');
1495
1496 var redArrowIconPath = './images/caret_red.png';
1497 redArrowAttributes = elementAttributes.addStyle('width: 8px; height: 11px;position: relative;background: url(' + redArrowIconPath + ') no-repeat; float: left;margin-top: 10px;z-index:2;left: -1px;');
1498
1499 var greyArrowIconPath = './images/caret_grey.png';
1500 greyArrowAttributes = elementAttributes.addStyle('z-index: 2; position: relative; width:11px; height: 7px; background: url(' + greyArrowIconPath + ') no-repeat; float: left; margin-top: 3px; margin-left: 10px; display:none;');
1501
1502 popupContainerAttributes = normalFontAttributes.addStyle('position:absolute; top:0; left:0; display:none; max-height:160px; width:auto; background:transparent; z-index:2147483645;');
1503
1504 buttonPanelAttributes = normalFontAttributes.addStyle('width: auto; height: 53px; float: left; position: relative;');
1505 actionPanelAttributes = normalFontAttributes.addStyle(leftBorderStyle + rightBorderStyle).addStyle('position: relative; top: -1px; float: left; display: none; max-height:140px; background:#BDBDBD; border: 1px solid #BDBDBD; width: auto; height: auto; color: #747474; background-color: #DBDBDB; background: -webkit-gradient(linear, 0% 100%, 0% 0%, from(#D9D9D9), to(#F6F6F6));background: -moz-linear-gradient(bottom, #D9D9D9, #F6F6F6); text-shadow: 0px 1px 0px #FFF; -moz-text-shadow: 0px 1px 0px #FFF; -webkit-text-shadow: 0px 1px 0px #FFF;');
1506
1507 actionButtonAttributes = editButtonAttributes.addStyle('font-size:11px; height: 50px; margin: 0; padding-left: 5px; padding-right: 5px; left: -6px; color: #747474; background-color: #DBDBDB; background: -webkit-gradient(linear, 0% 100%, 0% 0%, from(#D9D9D9), to(#F6F6F6));background: -moz-linear-gradient(bottom, #D9D9D9, #F6F6F6); text-shadow: 0px 1px 0px #FFF; -moz-text-shadow: 0px 1px 0px #FFF; -webkit-text-shadow: 0px 1px 0px #FFF;');
1508
1509 redButtonAttributes = editButtonAttributes.addStyle('font-size:11px; height: 50px; margin: 0; border:1px solid #777; -moz-border-radius-topright:3px;-moz-border-radius-bottomright:3px;-moz-border-radius-topleft:3px; -moz-border-radius-bottomleft:3px;-webkit-border-top-right-radius:3px; -webkit-border-bottom-right-radius:3px;-webkit-border-top-left-radius:3px; -webkit-border-bottom-left-radius:3px;text-shadow: 2px 1px 1px #777;-moz-text-shadow: 2px 1px 0px #777;-webkit-text-shadow: 2px 1px 0px #777;background-color: #AAA;background: -webkit-gradient(linear, 0% 100%, 0% 5%, from(#777), to(#fff));background: -moz-linear-gradient(bottom, #777, #fff);');
1510
1511 editSubmitAttributes = redButtonAttributes.put({ type: 'submit', value : 'OK' }).addStyle('height:20px; width: 32px; padding-left: 5px; padding-right: 5px; margin-left: 5px;');
1512
1513 undoSubmitButton = redButtonAttributes.put({ type: 'submit', value : 'undo' }).addStyle('height:20px; width: 32px; padding-left: 5px; padding-right: 5px; margin-left: 5px;');
1514
1515 titleButtonImageAttributes = elementAttributes.put({src: 'https://bo.lt/app/asset/page-edit/bo_icon_28x17.png?p=622fd096a39f5c36a6e06e41a9963dafaad61079'}).addStyle('display:block; width: 28px; height: 17px; margin-left: auto;margin-right: auto; margin-top: 2px; margin-bottom: 0px;');
1516 titleButtonDisplayTextAttributes = fontTypeAttributes.addStyle('text-align: center; height: auto; color: #FFF; display:block; margin-left: auto;margin-right: auto; margin-top: 5px; margin-bottom: 5px; font-style: normal; font-size: 11px; text-shadow: 2px 1px 1px #777 -moz-text-shadow: 2px 1px 0px #777;-webkit-text-shadow: 2px 1px 0px #777;');
1517
1518 actionButtonImageAttributes = elementAttributes.addStyle('width: 16px; height: 17px; margin-left: auto; margin-right: auto; margin-top: 5px; padding-top: 2px; padding-bottom: 0px; margin-bottom: 0px; display:block;');
1519 actionButtonDisplayTextAttributes = fontTypeAttributes.addStyle('text-align: center; height: auto; color: #777; text-shadow: 0px 1px 0px #FFF; -moz-text-shadow: 0px 1px 0px #FFF; -webkit-text-shadow: 0px 1px 0px #FFF; font-size: 11px; margin-left: auto;margin-right: auto; margin-top: 5px; margin-bottom: 5px; padding-left: 10px; padding-right: 10px; width: auto; display:block;');
1520
1521
1522 createActionButton = function createActionButton(buttonImage, displayText, buttonStyle) {
1523 var image = DOM.BUILDER.IMG(actionButtonImageAttributes.put({src: buttonImage}).values());
1524 var text = DOM.BUILDER.SPAN(actionButtonDisplayTextAttributes.values());
1525 text.innerHTML = displayText;
1526 var button = DOM.BUILDER.BUTTON(actionButtonAttributes.addStyle(buttonStyle).values());
1527 button.appendChild(image);
1528 button.appendChild(text);
1529 return button;
1530 };
1531
1532 var createTitleButton = function createTitleButton(displayText, buttonStyle) {
1533 var image = DOM.BUILDER.IMG(titleButtonImageAttributes.values());
1534 var text = DOM.BUILDER.SPAN(titleButtonDisplayTextAttributes.values());
1535 text.innerHTML = displayText;
1536 var button = DOM.BUILDER.BUTTON(redButtonAttributes.addStyle(buttonStyle).addStyle(leftBorderStyle + rightBorderStyle).values());
1537 button.appendChild(image);
1538 button.appendChild(text);
1539 return button;
1540 };
1541
1542 var displayUpArrowUnderButton = function displayUpArrowUnderButton(button, upArrow){
1543 upArrow.style.display = 'block';
1544 upArrow.style.marginLeft = (button.offsetLeft + button.offsetWidth/2) + 'px';
1545 };
1546
1547 AjaxResultProcessor = function AjaxResultProcessor() {
1548 this.processSwitchModeResponse = function processSwitchModeResponse(result) {
1549 if (result.status == 200) {
1550 window.location.href = eval("(" + result.responseText + ")").switchModeRedirectUrl;
1551 } else {
1552 pageEditor.showMessage(result.statusText);
1553 }
1554 };
1555
1556
1557 this.processPublishedResponse = function processPublishedResponse(result) {
1558 var resultString = result.responseText;
1559 if (resultString == 'ok'){
1560 alert("Re-narration successfuly posted");
1561 window.location.reload();
1562 }
1563 else{
1564 console.warn(resultString);
1565 alert("Re-narration failed, please try later!");
1566 }
1567 };
1568 };
1569
1570
1571 M4ImageElement = function M4ImageElement(element) {
1572 var self = this;
1573
1574 if (typeof element.m4boltOriginalWidth == 'undefined') {
1575 element.m4boltOriginalWidth = element.width;
1576 }
1577 if (typeof element.m4boltOriginalHeight == 'undefined') {
1578 element.m4boltOriginalHeight = element.height;
1579 }
1580
1581 this.getOriginalSize = function getOriginalSize() {
1582 return { width: element.m4boltOriginalWidth, height: element.m4boltOriginalHeight };
1583 };
1584
1585 this.setRawImageSize = function setRawImageSize(size) {
1586 element.m4boltRawImageWidth = size.width;
1587 element.m4boltRawImageHeight = size.height;
1588
1589 return self;
1590 };
1591
1592 this.getRawImageSize = function getRawImageSize() {
1593 if (typeof element.m4boltRawImageWidth == 'undefined' || typeof element.m4boltRawImageHeight == 'undefined') {
1594 return { width : 0, height: 0 };
1595 }
1596 return { width : element.m4boltRawImageWidth, height : element.m4boltRawImageHeight };
1597 };
1598
1599 this.getFittedSize = function getFittedSize() {
1600 var size = self.getRawImageSize(), original = self.getOriginalSize();
1601
1602 if (size.width > original.width) {
1603 size.height = size.height * (original.width / size.width);
1604 size.width = original.width;
1605 }
1606 if (size.height > original.height) {
1607 size.width = size.width * (original.height / size.height);
1608 size.height = original.height;
1609 }
1610 size.height = Math.floor(size.height);
1611 size.width = Math.floor(size.width);
1612
1613 return size;
1614 };
1615
1616 this.isFittable = function isFittable() {
1617 return (typeof element.m4boltRawImageWidth != 'undefined' && element.m4boltRawImageWidth > element.m4boltOriginalWidth)
1618 || (typeof element.m4boltRawImageHeight != 'undefined' && element.m4boltRawImageHeight > element.m4boltOriginalHeight);
1619 };
1620 };
1621
1622 SplashWindow = function SplashWindow(pageEditor ) {
1623
1624 this.createLabels = function createLabels() {
1625
1626 msg = document.createElement('div');
1627 msg.setAttribute("id", "msgoverlay");
1628 msg.setAttribute("title", "PAGE EDITOR");
1629 msg.setAttribute("alipielements", "alipi");
1630 msg.setAttribute("style", "color:#000;line-height:25px;");
1631 document.body.appendChild(msg);
1632
1633 msgDesc = document.createElement("label");
1634 msgDesc.setAttribute("id", "msg-desc");
1635 msgDesc.innerHTML = 'Click on any part of the page, and you will activate buttons that allow you to modify text, replace images and add audio. Don\'t forget to hit "Publish" when you\'re finished editing so we can save your newly-crafted page... And at any moment if you need help then hit a "Help" button.<br /> Don\'t show this again ';
1636 msg.appendChild(msgDesc);
1637
1638 pubLabel = document.createElement("input");
1639 pubLabel.setAttribute("id", "check-box");
1640 pubLabel.setAttribute("alipielements", "alipi");
1641 pubLabel.setAttribute("type", "checkbox");
1642 pubLabel.setAttribute("name","msgcheckbox");
1643 pubLabel.setAttribute("style", "margin-top:20px;");
1644 msg.appendChild(pubLabel);
1645 };
1646
1647
1648 function display() {
1649 $(function() {
1650 $( "#msgoverlay" ).dialog({
1651 width:600,
1652 height:250,
1653 modal: true,
1654 close: function() {
1655 $("#msgoverlay").remove();
1656 },
1657 buttons: {
1658 OK: function() { hide();
1659 $("#msgoverlay").remove();
1660 }
1661 }
1662
1663 });
1664 });
1665 };
1666
1667 this.activate = function activate() {
1668
1669 var allCookies = document.cookie;
1670 if (allCookies.indexOf('m4.show.redbar.overlay=no') == -1) {
1671 display();
1672 } else {
1673 hide();
1674 }
1675
1676 };
1677
1678 function hide() {
1679 if (document.getElementById("check-box").checked) {
1680 document.cookie ='m4.show.redbar.overlay=no;'
1681 } else {
1682 // var date = new Date();
1683 // document.cookie ='m4.show.redbar.overlay=no;expires=' + date.toUTCString() + ';';
1684 $("#msgoverlay").hide();
1685 }
1686 };
1687 } ;
1688
1689
1690 //------------------------------------ Target UI --------------------------------------------
1691 TargetWindow = function TargetWindow(pageEditor ) {
1692
1693 this.createDialogBox = function createDialogBox() {
1694
1695 target = document.createElement("div");
1696 target.setAttribute("id", "targetoverlay");
1697 target.setAttribute("title", "Please choose the target");
1698 target.setAttribute("alipielements", "alipi");
1699 target.setAttribute("class", "ui-widget-header ui-corner-all");
1700 document.body.appendChild(target);
1701
1702 locLabel= document.createElement("label");
1703 locLabel.innerHTML = 'Select Location';
1704 locLabel.setAttribute("style", "position:absolute;top:5%;left:3%;color:#000;");
1705 target.appendChild(locLabel);
1706
1707 locName= document.createElement("input");
1708 locName.setAttribute("id","loc-select");
1709 locName.setAttribute("type","text");
1710 locName.setAttribute("alipielements", "alipi");
1711 locName.setAttribute("style","position:absolute;top:5%;left:40%;width:250px;");
1712 target.appendChild(locName);
1713
1714 langLabel= document.createElement("label");
1715 langLabel.innerHTML = 'Select Language';
1716 langLabel.setAttribute("style", "position:absolute;top:25%;left:3%;color:#000;");
1717 target.appendChild(langLabel);
1718
1719 langName= document.createElement("input");
1720 langName.setAttribute("id","lang-select");
1721 langName.setAttribute("type","text");
1722 langName.setAttribute("alipielements", "alipi");
1723 langName.setAttribute("style","position:absolute;top:25%;left:40%;width:250px;");
1724 target.appendChild(langName);
1725
1726 styleLabel= document.createElement("label");
1727 styleLabel.innerHTML = 'Select style';
1728 styleLabel.setAttribute("style", "position:absolute;top:45%;left:3%;color:#000;");
1729 target.appendChild(styleLabel);
1730
1731 styleSelect = document.createElement("input");
1732 styleSelect.setAttribute("id","styleSelect-select");
1733 styleSelect.setAttribute("type","text");
1734 styleSelect.setAttribute("alipielements", "alipi");
1735 styleSelect.setAttribute("style","position:absolute;top:45%;left:40%;width:250px;");
1736 target.appendChild(styleSelect);
1737
1738 authLabel= document.createElement("label");
1739 authLabel.innerHTML = 'Author Name';
1740 authLabel.setAttribute("style", "position:absolute;top:65%;left:3%;color:#000;");
1741 target.appendChild(authLabel);
1742
1743 author= document.createElement("input");
1744 author.setAttribute("id","auth-select");
1745 author.setAttribute("type","text");
1746 author.setAttribute("alipielements", "alipi");
1747 author.setAttribute("style","position:absolute;top:65%;left:40%;width:250px;");
1748 target.appendChild(author);
1749
1750 ourcheck = document.createElement("input");
1751 ourcheck.setAttribute("id","our-check");
1752 ourcheck.setAttribute("type","radio");
1753 ourcheck.setAttribute("name", "blog");
1754 ourcheck.setAttribute("alipielements", "alipi");
1755 ourcheck.setAttribute("style","position:absolute;top:85%;left:40%;");
1756 target.appendChild(ourcheck);
1757
1758 yourcheck = document.createElement("input");
1759 yourcheck.setAttribute("id","your-check");
1760 yourcheck.setAttribute("type","radio");
1761 yourcheck.setAttribute("name", "blog");
1762 yourcheck.setAttribute("alipielements", "alipi");
1763 yourcheck.setAttribute("style","position:absolute;top:85%;left:70%;");
1764 target.appendChild(yourcheck);
1765
1766 yourLabel = document.createElement('label');
1767 yourLabel.textContent = "Your blog";
1768 yourLabel.setAttribute("style","position:absolute;top:85%;left:45%;color:#000;");
1769 target.appendChild(yourLabel);
1770
1771 ourLabel = document.createElement('label');
1772 ourLabel.textContent = "Our blog";
1773 ourLabel.setAttribute("style","position:absolute;top:85%;left:75%;color:#000;");
1774 target.appendChild(ourLabel);
1775 }
1776
1777 this.activate = function activate() {
1778 $(function() {
1779 $( "#targetoverlay" ).dialog({
1780 height:500,
1781 width:500,
1782 modal: true,
1783 buttons: {
1784 OK: function() {
1785 overlayBar = new OverlayBar(pageEditor);
1786 overlayBar.blogpost();
1787 }
1788 },
1789 close: function() {
1790 $( "#targetoverlay" ).hide();
1791 }
1792 });
1793 });
1794
1795
1796
1797 $( "#loc-select" ).autocomplete({
1798 source: function(req, add){
1799
1800 //pass request to server
1801 $.getJSON("http://y.a11y.in/loc?", req, function(data) {
1802
1803 //create array for response objects
1804 var suggestions = [];
1805
1806 //process response
1807 $.each(data, function(i, val){
1808 //suggestions.push(val.country);
1809 for(i=0;i<val.length;i++){
1810 suggestions.push(val[i]);
1811 }
1812 });
1813
1814 //pass array to callback
1815 add(suggestions);
1816 });
1817 },
1818 });
1819
1820 $( "#lang-select" ).autocomplete({
1821 source: function(req, add){
1822
1823 //pass request to server
1824 $.getJSON("http://y.a11y.in/lang?", req, function(data) {
1825
1826 //create array for response objects
1827 var suggestions = [];
1828
1829 //process response
1830 $.each(data, function(i, val){
1831 //suggestions.push(val.country);
1832 for(i=0;i<val.length;i++){
1833 suggestions.push(val[i]);
1834 }
1835 });
1836
1837 //pass array to callback
1838 add(suggestions);
1839 });
1840 },
1841 });
1842
1843
1844 }
1845
1846 };
1847
1848 // ------------------------------------ Target UI end ---------------------------------------------
1849
1850 // ========================================== Edit Window start ======================================================
1851
1852
1853 EditWindow = function EditWindow(pageEditor) {
1854
1855 editor = document.createElement("div");
1856 editor.setAttribute("id", "editoroverlay");
1857 editor.setAttribute("title", "Edit window");
1858 editor.setAttribute("alipielements", "alipi");
1859 editor.setAttribute("class", "ui-widget-header ui-corner-all");
1860 document.body.appendChild(editor);
1861
1862 refLabel= document.createElement("label");
1863 refLabel.innerHTML = 'Reference';
1864 refLabel.setAttribute("style", "position:absolute;top:5%;left:20%;color:#000;font-size:25px;");
1865 editor.appendChild(refLabel);
1866
1867 refBox= document.createElement("textarea");
1868 refBox.setAttribute("id","reference");
1869 refBox.setAttribute("readonly", 'yes');
1870 refBox.setAttribute("style","position:absolute;top:15%;left:4%;min-width:450px;max-width:450px;min-height:370px;max-height:370px;font-size:15;text-align:justify;");
1871 editor.appendChild(refBox);
1872
1873 editLabel= document.createElement("label");
1874 editLabel.innerHTML = 'Editor';
1875 editLabel.setAttribute("style", "position:absolute;top:5%;left:70%;color:#000;font-size:25px;");
1876 editor.appendChild(editLabel);
1877
1878 editBox= document.createElement("textarea");
1879 editBox.setAttribute("id","editor");
1880 editBox.setAttribute("alipielements", "alipi");
1881 editBox.setAttribute("style","position:absolute;top:15%;left:51%;min-width:450px;max-width:450px;min-height:370px;max-height:370px;font-size:15;text-align:justify;");
1882 editor.appendChild(editBox);
1883
1884
1885 this.activate = function activate() {
1886 $(function() {
1887 $( "#editoroverlay" ).dialog({
1888 width:1000,
1889 height:550,
1890 modal: true,
1891 buttons: {
1892 "+": function() {
1893 if(document.getElementById('editor').style.fontSize == '30px'){
1894 // passthrough
1895 } else {
1896 document.getElementById('editor').style.fontSize = parseFloat(document.getElementById('editor').style.fontSize) + 1 + 'px';
1897 document.getElementById('reference').style.fontSize = parseFloat(document.getElementById('reference').style.fontSize) + 1 + 'px';
1898 }
1899 },
1900 "-": function() {
1901 if(document.getElementById('editor').style.fontSize == '10px'){
1902 } else {
1903 document.getElementById('editor').style.fontSize = parseFloat(document.getElementById('editor').style.fontSize) - 1 + 'px';
1904 document.getElementById('reference').style.fontSize = parseFloat(document.getElementById('reference').style.fontSize) - 1 + 'px';
1905 }
1906 },
1907 OK: function() {
1908 textElement = new TextElementPopup(pageEditor, true);
1909 textElement.textButtonOnClick();
1910 $( "#editoroverlay" ).remove();
1911 }
1912 },
1913 close: function() {
1914 document.getElementById("alipiSelectedElement").removeAttribute("id", "alipiSelectedElement");
1915 $( "#editoroverlay" ).remove();
1916 }
1917 });
1918 });
1919
1920 noteLabel= document.createElement("label");
1921 noteLabel.setAttribute("id", "note-label");
1922 noteLabel.innerHTML = ' Magnify or Demagnify ';
1923 noteLabel.setAttribute("style", "color:#000;font-size:15px;");
1924 $(noteLabel).insertAfter($(document.getElementsByClassName('ui-button-text')[0].parentNode));
1925
1926 document.getElementsByClassName('ui-button-text')[1].parentNode.style.marginRight = '635px';
1927 document.getElementsByClassName('ui-button-text')[2].parentNode.style.marginRight = '25px';
1928 document.getElementById("ui-dialog-title-editoroverlay").setAttribute("style","font-size:25px;");
1929
1930 }
1931 } ;
1932
1933
1934
1935 // =========================================== Edit Window end =======================================================
1936
1937 // ========================================== Help Window Start =================================================
1938
1939 HelpWindow = function HelpWindow(pageEditor ) {
1940
1941 this.createLabels = function createLabels() {
1942
1943 help = document.createElement('div');
1944 help.setAttribute("id", "helpwindow");
1945 help.setAttribute("alipielements", "alipi");
1946 help.setAttribute("style", "color:#000;line-height:16px;top:50px;");
1947 document.body.appendChild(help);
1948
1949 txtLabel = document.createElement("label");
1950 txtLabel.setAttribute("id", "txtlab");
1951 txtLabel.innerHTML = 'TEXT :-<p style="margin-left:50px";>Editor - It will popup a window and allow you to modify/replace text of select element on editor(right) box.</p><p style="margin-left:100px";>To delete - Empty the editor(right) box and press "OK".</p><p style="margin-left:50px";>See narrations - If the selected element has other narrations then it will list, on click.</p><p style="margin-left:50px";>Audio - It allows you to enter audio URL.</p>';
1952 help.appendChild(txtLabel);
1953
1954 imgLabel = document.createElement("label");
1955 imgLabel.setAttribute("id", "imglab");
1956 imgLabel.innerHTML = ' IMAGE:- <p style="margin-left:50px";> Replace - It allows you to enter image URL.</p><p style="margin-left:50px";> See narrations - If the selected element has other image narration then it will show, on click.</p>';
1957 help.appendChild(imgLabel);
1958
1959 undoLabel = document.createElement("label");
1960 undoLabel.setAttribute("id", "undolab");
1961 undoLabel.innerHTML = 'UNDO:- Use it when you want to revert back to previous change.<p style="margin-left:50px";> Revert deleted - Press \'Undo\' button twice. </p>';
1962 help.appendChild(undoLabel);
1963
1964 pubLabel = document.createElement("label");
1965 pubLabel.setAttribute("id", "publab");
1966 pubLabel.innerHTML = 'PUBLISH:- To publish your crafted changes to database and blog (our/your).<p style="margin-left:50px";>States - To the place you are targetting.</p><p style="margin-left:50px";>Languages - In language you publishing.</p><p style="margin-left:50px";>Style - In what style you crafted?</p><p style="margin-left:50px";> Author - Who is a crafter?</p><p style="margin-left:50px";>Our blog - If you don\'t have blogspot ID then check this to post it to our blog.</p>';
1967 help.appendChild(pubLabel);
1968
1969
1970 };
1971
1972 this.activate = function activate() {
1973 $(function() {
1974 $( "#helpwindow" ).dialog({
1975 width:800,
1976 height:550,
1977 modal: true,
1978 close: function() {
1979 $("#helpwindow").remove();
1980 }
1981 });
1982 });
1983 };
1984
1985 } ;
1986
1987
1988
1989 // ========================================= Help Window end ===================================================
1990 /*
1991 * Control for displaying/hiding an action panel that appears below the popup buttons.
1992 */
1993 PopupActionControl = function PopupActionControl(actionSlot ) {
1994
1995 this.open = function open(actionPanel) {
1996 if (actionSlot.firstChild) {
1997 actionSlot.replaceChild(actionPanel, actionSlot.firstChild);
1998 } else {
1999 actionSlot.appendChild(actionPanel);
2000 }
2001 actionSlot.style.display = "block";
2002 };
2003
2004 this.close = function close() {
2005 actionSlot.style.display = "none";
2006 };
2007 } ;
2008
2009 /*
2010 * control for displaying/hiding the popup buttons.
2011 */
2012 PopupControl = function PopupControl(pageEditor, rootElement, showAtCursor) {
2013 var self = this, selectedElement = null;
2014 var offsetX = 3, offsetY = 3;
2015 var popX = 0, popY = 0;
2016 var currentAction = null;
2017
2018 var blurListener = function blurListener(saveChanges) {
2019 self.close(saveChanges);
2020 };
2021
2022 this.onOpen = function onOpen(selectedElement) {
2023 };
2024
2025 this.onClose = function onClose(saveChanges) {
2026 };
2027
2028 this.openAt = function openAt(atElement, x, y) {
2029 var dimension = DOM.viewDimension(), popupWidth, popupHeight;
2030 popX = x;
2031 selectedElement = atElement;
2032 var position = DOM.findPosition(atElement);
2033 popY = position.y + selectedElement.offsetHeight + 15;
2034 var type = selectedElement.getAttribute('m4pageedittype');
2035 if (showAtCursor) {
2036 popY = y;
2037 }
2038 // To calculate the width, the element needs to be shown. So we move it off the screen temporarily.
2039 rootElement.style.left = '-10000px';
2040 rootElement.style.top = '-10000px';
2041 rootElement.style.width = 'auto';
2042 rootElement.style.display = 'block';
2043 var popupSize = DOM.findSize(rootElement);
2044 popupWidth = DOM.findSize(rootElement).width;
2045 // FF sometimes needs 1 pixel buffer. IE doesn't like it.
2046 if (!rootElement.currentStyle) {
2047 popupWidth = popupWidth + 1;
2048 }
2049
2050 rootElement.style.width = popupWidth + 'px';
2051 // If not enough space exist on the right on cursor, launch on the left side instead.
2052 if ((popX + popupWidth) > dimension[0]) {
2053 popX = dimension[0] - popupWidth - 3;
2054 if (popX < 0) {
2055 popX = 0;
2056 }
2057 }
2058
2059 rootElement.style.left = popX + 'px';
2060 rootElement.style.top = popY + 'px';
2061 pageEditor.loseFocus();
2062 pageEditor.addFocusListener(blurListener);
2063 self.onOpen(selectedElement);
2064 };
2065
2066 // @param saveChanges, save the current changes, default false, optional
2067 this.close = function close(saveChanges) {
2068 self.onClose(saveChanges);
2069 self.hideAction();
2070 rootElement.style.left = '0px';
2071 rootElement.style.top = '0px';
2072 rootElement.style.display = 'none';
2073 pageEditor.removeFocusListener(blurListener);
2074 if (saveChanges) {
2075 pageEditor.saveAndClose();
2076 } else {
2077 pageEditor.close();
2078 }
2079 selectedElement = null;
2080 };
2081
2082 this.showAction = function showAction(popupAction) {
2083 self.hideAction();
2084 if (popupAction) {
2085 currentAction = popupAction;
2086 currentAction.open(selectedElement);
2087 }
2088 };
2089
2090 this.hideAction = function hideAction() {
2091 if (currentAction) {
2092 currentAction.close();
2093 }
2094 }
2095 };
2096
2097 /*
2098 * Action for editing a hyperlink.
2099 */
2100
2101 function renAction(pageEditor, actionSlot) {
2102 var self = this, renInput,renDiv,selectedElement,renActionControl,optionInput,v,x,i,undoButton,element,vxpath,vdata, varray=[],previousData,xpath;
2103
2104 renActionControl = new PopupActionControl(actionSlot);
2105
2106 this.open = function open(element) {
2107
2108 renInput = DOM.BUILDER.SELECT(editTextInputAttributes.addStyle('margin-left: 5px; background: #FFFFFF;').addStyle(leftBorderStyle + rightBorderStyle).values());
2109
2110 undoButton=DOM.BUILDER.INPUT(undoSubmitButton.addStyle('vertical-align: middle; float:left; margin-left: 5px; margin-right: auto;').values());
2111
2112 renDiv = DOM.BUILDER.DIV(popupContainerAttributes.addStyle('overflow: hidden !important; display: none;position: relative; margin-left: auto; margin-right: auto; margin-top: 5px; margin-bottom: 5px; height: auto !important; height: 60px;').values(), renInput,undoButton);
2113
2114
2115
2116 xpath = DOM.getXPATH(element);
2117 previousData = element.textContent;
2118
2119 var xmlhttp = new XMLHttpRequest();
2120 d = window.location.search.split('?')[1];
2121 var a =[];
2122 for (var i = 0;i<d.split('&').length;i++){
2123 a[d.split('&')[i].split('=')[0]] = d.split('&')[i].split('=')[1];
2124 }
2125 var url = a['foruri'];
2126 var data="url="+encodeURIComponent(url)+"&xpath="+encodeURIComponent(xpath);
2127 xmlhttp.onreadystatechange = function()
2128 {
2129 if(xmlhttp.readyState == 4 && xmlhttp.status== 200)
2130 {
2131 if(xmlhttp.responseText=='')
2132 {
2133 renDiv.style.display = 'none';
2134 alert("Renarrations not available");
2135 }
2136 else {
2137 for (i=0;i<= varray.length;i++) varray.pop(i);
2138 for (i=0; i<=renInput.length;i++) renInput.remove(i,null);
2139
2140 x=DOM.BUILDER.OPTION("please choose a Re-narration");
2141 renInput.add(x,null);
2142
2143 renActionControl.open(renDiv);
2144 renDiv.style.display = 'block';
2145 var response=xmlhttp.responseText.substring(3).split('###');
2146 for (var j= 0; j< response.length ; j++){
2147 d ={}
2148 chunk = response[j].substring(1).split('&');
2149 for (var i= 0; i< chunk.length ; i++){
2150 pair =chunk[i].split("::");
2151 key = pair[0];
2152 value = pair[1];
2153 d[key] = value;
2154 }
2155 varray.push(d);
2156 }
2157 for(i=0;i<varray.length;i++) {
2158 lang_ = varray[i]['lang'];
2159 location_ = varray[i]['location'];
2160 style_ = varray[i]['style'];
2161 x=DOM.BUILDER.OPTION(lang_+', '+location_+', '+style_);
2162 renInput.add(x,null);
2163 }
2164 renInput.onchange=function(){
2165
2166 if (renInput.selectedIndex -1 < 0) alert("please choose a Re-narration ");
2167 else {
2168 DOM.evaluate(varray[renInput.selectedIndex - 1]['xpath'],varray[renInput.selectedIndex - 1]['data']);};
2169 renInput.selectedIndex = 0;
2170 }
2171
2172 undoButton.onclick =function(){
2173 DOM.evaluate(xpath,previousData);
2174 };
2175
2176 }
2177 }
2178 }
2179 xmlhttp.open("POST","http://dev.a11y.in/narration",true);
2180 xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
2181 xmlhttp.send(data);
2182
2183
2184 };
2185
2186
2187 this.close = function close() {
2188 selectedElement = null;
2189 };
2190 }
2191
2192
2193 //******************************** Shalini - Changed AudioupdatePopupAction from ImageUpdatePopupAction *****************
2194
2195 AudioUpdateByUrl = function AudioUpdateByUrl(pageEditor) {
2196 // var self = this, popupDiv, audioUrlInput, randomInput, audioUrlForm, selectedElement, targetName,audioElement;
2197 // var addUrlLabel = DOM.BUILDER.SPAN(normalFontAttributes.addStyle('width: 100%; display: block; float: left; font-size: 10px;position:relative; margin-top: 5px;margin-left: 0px; margin-right: 5px; margin-bottom: 5px; background: transparent; color: #747474; text-shadow: 0 1px 0 #FFFFFF; text-align: left;').values());
2198 // addUrlLabel.innerHTML = 'Add URL';
2199
2200 // audioUrlInput = DOM.BUILDER.INPUT(editTextInputAttributes.addStyle('display:block; background: #FFFFFF;').values());
2201 // randomInput = DOM.BUILDER.INPUT(editAttributes.put({ name : 'random', type : 'hidden', value : '1' }).values());
2202 // audioUrlForm = DOM.BUILDER.FORM(elementAttributes.values(),
2203 // audioUrlInput,
2204 // DOM.BUILDER.INPUT(editSubmitAttributes.values()));
2205 this.display = function display() {
2206 audioDiv = document.createElement("div");
2207 audioDiv.setAttribute("id", "audiodiv");
2208 audioDiv.setAttribute("alipielements", "alipi");
2209 audioDiv.setAttribute("title", "Enter ogg file link");
2210 document.body.appendChild(audioDiv);
2211
2212 urlInput = document.createElement("input");
2213 urlInput.setAttribute("id", "audiourl");
2214 urlInput.setAttribute("alipielements", "alipi");
2215 urlInput.setAttribute("type", "text");
2216 urlInput.setAttribute("style", "width:300px;");
2217 audioDiv.appendChild(urlInput);
2218
2219 $(function() {
2220 $( "#audiodiv" ).dialog({
2221 width:350,
2222 height:150,
2223 modal: true,
2224 close: function() {
2225 $("#audiodiv").remove();
2226 },
2227 buttons: {
2228 OK: function() {
2229 var url = urlInput.value;
2230 updateAudio(url);
2231 document.getElementById('alipiSelectedElement').removeAttribute('id', 'alipiSelectedElement');
2232 $("#audiodiv").remove();
2233 }
2234 }
2235
2236 });
2237 });
2238 };
2239
2240
2241 // function updateFormOnSubmit() {
2242 // var url = urlInput.value;
2243 // updateAudio(url);
2244 // return false;
2245 // };
2246
2247 // audioDiv = DOM.BUILDER.DIV(popupContainerAttributes.addStyle('width: 100%; float:left; position: relative; margin: 0px auto auto 10px; display: block;').values(), addUrlLabel, audioUrlForm);
2248
2249 // audioActionControl = new PopupActionControl(actionControl);
2250
2251 // this.getActionDiv = function getActionDiv() {
2252 // return audioDiv;
2253 // };
2254
2255 // this.open = function open(element) {
2256 // audioActionControl.open(audioDiv);
2257 // audioUrlInput.value = '';
2258 // selectedElement = element;
2259 // audioDiv.style.display = 'block';
2260 // };
2261
2262 // this.close = function close() {
2263 // selectedElement = null;
2264 // audioDiv.style.display = 'none';
2265 // };
2266
2267 updateAudio = function updateAudio(src) {
2268 var command;
2269 selectedElement = document.getElementById("alipiSelectedElement");
2270 // audioElement = urlInput;
2271 // if (audioElement) {
2272 // command = {
2273 // command : 'AUDIO_UPDATE',
2274 // element : audioElement,
2275 // elementId : audioElement.getAttribute('m4pageeditid'),
2276 // data : src,
2277 // // previousData : originalHref
2278 // };
2279 // } else {
2280 command = {
2281 command : 'AUDIO_CREATE',
2282 element : selectedElement,
2283 elementType : 'audio/ogg',
2284 xpath : DOM.getXPATH(selectedElement),
2285 url : window.location.href,
2286 elementId : selectedElement.getAttribute('m4pageeditid'),
2287 data : src,
2288 previousData : ''
2289 };
2290 // }
2291 pageEditor.commandApply(command);
2292 };
2293
2294 };
2295
2296
2297 //*******************************************************************
2298
2299 /**
2300 * Action for updating an image.
2301 */
2302 function ImageUpdatePopupAction(pageEditor, actionSlot, updateType) {
2303 var self = this, selectedElement, imagePopupDiv, backgroundUploadPopup, uploadPopupDiv, imageUrlPopup, imageUrlDiv,
2304 imageSizeSpan, imageFitCheckbox, headerDiv, updateSize, fitElement, imageActionControl;
2305
2306 imagePopupDiv = DOM.BUILDER.DIV(popupContainerAttributes.addStyle('position: relative; overflow: hidden !important; display: block; margin-top:3px; height: auto !important; height: 120px; margin-bottom: 10px;').values());
2307 headerDiv = DOM.BUILDER.DIV(normalFontAttributes.addStyle('position: relative;').values());
2308
2309 imageActionControl = new PopupActionControl(actionSlot);
2310
2311 imageSizeSpan = DOM.BUILDER.SPAN(normalFontAttributes.addStyle('font-size: 10px; position: relative; float: left; margin-top: 2px; margin-left: 10px; background: transparent; color: #747474; text-shadow: 0 1px 0 #FFFFFF;').values());
2312 imageSizeSpan.innerHTML = 'Image Size:';
2313 imageFitCheckbox = DOM.BUILDER.INPUT(editAttributes.put({ name : 'Fit Image', type : 'checkbox', checked : 'yes' }).addStyle('position:relative; margin-top: 2px; padding: 1px; background: transparent; float:right; vertical-align: bottom; display:block;').values());
2314
2315 var imageLabel = DOM.BUILDER.LABEL(normalFontAttributes.addStyle('font-size: 10px; float:right;position:relative; margin-top:2px; margin-left: 5px; margin-right: 5px;background: transparent; color: #747474; text-shadow: 0 1px 0 #FFFFFF;').values());
2316 imageLabel.innerHTML = 'Fit Image';
2317 headerDiv.appendChild(imageSizeSpan);
2318 headerDiv.appendChild(imageLabel);
2319 headerDiv.appendChild(imageFitCheckbox);
2320
2321 var backgroundImageOnLoad = function backgroundImageOnLoad(selectedElement, url, size) {
2322 var command = {
2323 command : 'BACKGROUND_IMAGE_UPDATE',
2324 element : selectedElement,
2325 elementId : selectedElement.getAttribute('m4pageeditid'),
2326 data : url,
2327 previousData : selectedElement.style.backgroundImage
2328 };
2329 pageEditor.commandApply(command);
2330 };
2331
2332 var sourceImageUpdateOnLoad = function sourceImageUpdateOnLoad(selectedElement, url, size) {
2333 var image = new M4ImageElement(selectedElement).setRawImageSize(size), command, fittedSize = size;
2334 if (imageFitCheckbox.checked) {
2335 fittedSize = image.getFittedSize();
2336 }
2337 command = {
2338 command : 'IMAGE_SRC_UPDATE',
2339 element : selectedElement,
2340 elementType : 'image',
2341 xpath : DOM.getXPATH(selectedElement),
2342 url : window.location.href,
2343 data : new UTIL.StringBuffer().append(fittedSize.width).append('x').append(fittedSize.height).append(',').append(url).toString(),
2344 previousData : {
2345 'src' : selectedElement.src,
2346 'size' : { width: selectedElement.width, height: selectedElement.height },
2347 'rawImageSize' : image.getRawImageSize()
2348 }
2349 };
2350
2351 updateSize();
2352 pageEditor.commandApply(command);
2353 };
2354 var imageOnLoad = backgroundImageOnLoad;
2355 var uploadButtonText = 'Upload BG Image';
2356
2357 if (updateType == 'IMAGE_SRC_UPDATE') {
2358 imageOnLoad = sourceImageUpdateOnLoad;
2359 uploadButtonText = 'Upload Image';
2360 imagePopupDiv.appendChild(headerDiv);
2361 }
2362
2363 backgroundUploadPopup = new ImageUpdateByUpload(self, uploadButtonText);
2364 backgroundUploadPopup.onImageLoad = imageOnLoad;
2365 uploadPopupDiv = backgroundUploadPopup.getActionDiv();
2366
2367 imageUrlPopup = new ImageUpdateByUrl(pageEditor, self);
2368 imageUrlPopup.onImageLoad = imageOnLoad;
2369 imageUrlDiv = imageUrlPopup.getActionDiv();
2370
2371
2372 imagePopupDiv.appendChild(uploadPopupDiv);
2373 imagePopupDiv.appendChild(imageUrlDiv);
2374
2375 this.open = function open(element) {
2376 imageActionControl.open(imagePopupDiv);
2377 selectedElement = element;
2378 headerDiv.style.width = imagePopupDiv.offsetWidth;
2379 backgroundUploadPopup.open(selectedElement);
2380 imageUrlPopup.open(selectedElement);
2381 updateSize();
2382 };
2383
2384 this.close = function close() {
2385 imageActionControl.close();
2386 backgroundUploadPopup.close();
2387 imageUrlPopup.close();
2388 selectedElement = null;
2389 };
2390
2391 this.onComplete = function onComplete() {
2392 };
2393
2394 this.onError = function onError() {
2395 };
2396
2397 this.actionComplete = function actionComplete() {
2398 self.onComplete();
2399 };
2400
2401 this.handleError = function handleError() {
2402 self.onError();
2403 };
2404
2405 updateSize = function updateSize() {
2406 if (selectedElement) {
2407 var size = DOM.findSize(selectedElement);
2408 imageSizeSpan.innerHTML = new UTIL.StringBuffer().append('Image Size ').append(size.width).append('x').append(size.height).append(' pixels').toString();
2409 }
2410 };
2411
2412 function ImageUpdateByUpload(actionControl, uploadButtonText) {
2413 var self = this, uploadForm, uploadingMessage, uploadIframe, fileInput, pageSlugInput,
2414 uploadSlugInput, targetName, randomInput, selectedElement = null, sizingImage, showLoading, uploadButton,
2415 uploadPopupDiv;
2416
2417 uploadPopupDiv = DOM.BUILDER.DIV(popupContainerAttributes.addStyle('width: 110px; overflow: none; display: block; position: relative; margin: 10px auto auto 10px; float:left;').values());
2418 uploadingMessage = DOM.BUILDER.SPAN(editTitleAttributes.addStyle("display:none").values(), "Loading...");
2419 fileInput = DOM.BUILDER.INPUT(editTextInputAttributes.put({ name : 'file', type : 'file', size : '20' }).addStyle('width: 110px; cursor: pointer; height: 30px;opacity: 0; -ms-filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0); filter:alpha(opacity=0); position: relative; float: none;').values());
2420
2421 pageSlugInput = DOM.BUILDER.INPUT(editAttributes.put({ name : 'pageSlug', type : 'hidden', value : pageSlug }).values());
2422 uploadSlugInput = DOM.BUILDER.INPUT(editAttributes.put({ name : 'uploadSlug', type : 'hidden', value : uploadSlug }).values());
2423 randomInput = DOM.BUILDER.INPUT(editAttributes.put({ name : 'random', type : 'hidden', value : '1' }).values());
2424
2425 targetName = 'm4-bolt-upload-target-' + Math.round(Math.random() * 10000000);
2426
2427 uploadButton = DOM.BUILDER.BUTTON(redButtonAttributes.addStyle('cursor: pointer;width: 110px; height: 25px; position: absolute; float:left; text-align: center;').addStyle(leftBorderStyle + rightBorderStyle).values(), uploadButtonText);
2428
2429 uploadButton.onclick = function uploadButtonOnClick(){
2430 return false;
2431 };
2432
2433 uploadForm = DOM.BUILDER.FORM(elementAttributes.put({ target : targetName, encType : 'multipart/form-data', method : 'post', action : '/app/page-edit/upload' }).addStyle('display:block; margin: auto;').values());
2434
2435 showLoading = function showLoading() {
2436 uploadForm.style.display = "none";
2437 uploadingMessage.style.width = '110 px';
2438 uploadingMessage.style.display = "block";
2439 };
2440
2441 uploadForm.onsubmit = function uploadFormOnSubmit() {
2442 showLoading();
2443 };
2444
2445 fileInput.onchange = function fileInputOnChange() {
2446 showLoading();
2447 uploadForm.submit();
2448 };
2449
2450 uploadIframe = DOM.BUILDER.IFRAME( { name : targetName, src : 'https://bo.lt/app/asset/empty.html?p=622fd096a39f5c36a6e06e41a9963dafaad61079', style : 'display: none' });
2451 UTIL.addEvent(uploadIframe, 'load', function uploadIframeOnLoad() {
2452 var iframeBody;
2453 if (uploadIframe.contentDocument) {
2454 iframeBody = uploadIframe.contentDocument.body;
2455 } else if (uploadIframe.contentWindow) {
2456 iframeBody = uploadIframe.contentWindow.document.body;
2457 }
2458 var upload, resultText = DOM.textContent(iframeBody);
2459
2460 if (!/^\s*\{.*\}\s*/.test(resultText) || selectedElement == null) {
2461 return;
2462 }
2463
2464 try {
2465 upload = eval("(" + resultText + ")");
2466 } catch (error) {
2467 console.error("Unable to interpret the upload image response", error);
2468 actionControl.handleError();
2469 return;
2470 }
2471
2472 if (!upload.success) {
2473 console.error("Unable to upload the specified file:", upload.error);
2474 actionControl.handleError();
2475 return;
2476 }
2477
2478 sizingImage = new Image();
2479 sizingImage.onload = function sizingImageOnLoad() {
2480 self.onImageLoad(selectedElement, upload.url, { width: sizingImage.width, height: sizingImage.height });
2481 actionControl.actionComplete();
2482 };
2483 sizingImage.src = upload.url;
2484 randomInput.value = randomInput.value + 1;
2485 });
2486
2487 uploadPopupDiv.appendChild(uploadForm);
2488 uploadPopupDiv.appendChild(uploadingMessage);
2489 uploadPopupDiv.appendChild(uploadIframe);
2490
2491 this.onImageLoad = function onImageLoad(selectedElement, url, size) {
2492 };
2493
2494 this.getActionDiv = function getActionDiv() {
2495 return uploadPopupDiv;
2496 };
2497
2498 this.open = function open(element) {
2499 selectedElement = element;
2500 uploadForm.style.display = "block";
2501 uploadingMessage.style.display = "none";
2502 fileInput.value = '';
2503 fileInput.select();
2504 };
2505
2506 this.close = function close() {
2507 selectedElement = null;
2508 uploadingMessage.style.display = "none";
2509 uploadForm.style.display = "block";
2510 };
2511 }
2512
2513 function ImageUpdateByUrl(pageEditor, actionControl) {
2514 var self = this, popupDiv, imageUrlInput, randomInput, imageUrlForm, selectedElement, targetName;
2515
2516 var addUrlLabel = DOM.BUILDER.SPAN(normalFontAttributes.addStyle('width: 100%; display: block; float: left; font-size: 10px;position:relative; margin-top: 5px;margin-left: 0px; margin-right: 5px; margin-bottom: 5px; background: transparent; color: #747474; text-shadow: 0 1px 0 #FFFFFF; text-align: left;').values());
2517 addUrlLabel.innerHTML = 'Add URL';
2518
2519 imageUrlInput = DOM.BUILDER.INPUT(editTextInputAttributes.addStyle('display:block; background: #FFFFFF;').values());
2520 randomInput = DOM.BUILDER.INPUT(editAttributes.put({ name : 'random', type : 'hidden', value : '1' }).values());
2521
2522 imageUrlForm = DOM.BUILDER.FORM(elementAttributes.put({ target : targetName, enctype : 'multipart/form-data', method : 'post', action : '/app/page-edit/upload' }).values(),
2523 imageUrlInput,
2524 DOM.BUILDER.INPUT(editAttributes.put({ name : 'pageSlug', type : 'hidden', value : pageSlug }).values()),
2525 randomInput,
2526 DOM.BUILDER.INPUT(editSubmitAttributes.values()));
2527
2528 imageUrlForm.onsubmit = function updateFormOnSubmit() {
2529 var url = imageUrlInput.value;
2530 if (url != '') {
2531 randomInput.value = randomInput.value + 1;
2532 var sizingImage = new Image();
2533 sizingImage.onload = function sizingImageOnLoad() {
2534 self.onImageLoad(selectedElement, url, { width: sizingImage.width, height: sizingImage.height });
2535 actionControl.actionComplete();
2536 };
2537 sizingImage.src = url;
2538 }
2539 return false;
2540 };
2541
2542 popupDiv = DOM.BUILDER.DIV(popupContainerAttributes.addStyle('width: 100%; float:left; position: relative; margin: 0px auto auto 10px; display: block;').values(),
2543 addUrlLabel, imageUrlForm);
2544
2545 this.getActionDiv = function getActionDiv() {
2546 return popupDiv;
2547 };
2548
2549 this.open = function open(element) {
2550 imageUrlInput.value = '';
2551 selectedElement = element;
2552 popupDiv.style.display = 'block';
2553 };
2554
2555 this.close = function close() {
2556 selectedElement = null;
2557 popupDiv.style.display = 'none';
2558 };
2559
2560 this.onImageLoad = function onImageLoad(element, url, size) {
2561 };
2562 }
2563
2564 }
2565
2566
2567
2568 /**
2569 * Popup for all editable elements except text.
2570 */
2571 function EditableElementPopup(pageEditor, imageElement) {
2572 var self = this, popupControl, deleteElement, imagePopupDiv, deleteButton,renButton,selectedElement,
2573 linkUpdateAction, linkButton, closeButton, imageButton, backgroundButton, redArrow,imageUpdateAction,
2574 imageUpdateDiv, uploadMode, backgroundButtonText, imageButtonText, buttonPanel, upArrow, actionSlot,subMenuAction,renUpdateAction;
2575
2576 this.popupAt = function popupAt(element, popX, popY) {
2577 popupControl.openAt(element, popX, popY);
2578 };
2579
2580 this.popdown = function popdown() {
2581 popupControl.close();
2582 };
2583
2584 if (imageElement) {
2585 uploadMode = 'IMAGE_SRC_UPDATE';
2586 backgroundButtonText = "Replace";
2587 imageButtonText = 'Image';
2588 }
2589
2590 buttonPanel = DOM.BUILDER.DIV(buttonPanelAttributes.values());
2591 upArrow = DOM.BUILDER.SPAN(greyArrowAttributes.values());
2592 actionSlot = DOM.BUILDER.DIV(actionPanelAttributes.values());
2593
2594 imagePopupDiv = DOM.BUILDER.DIV(popupContainerAttributes.addStyle('margin-bottom: 10px;').values());
2595
2596 popupControl = new PopupControl(pageEditor, imagePopupDiv, true);
2597 popupControl.onOpen = function onOpen(element) {
2598 selectedElement = element;
2599 var actionSlotWidth = DOM.findSize(imagePopupDiv).width - DOM.findSize(redArrow).width;
2600 var spanElement = imageButton.getElementsByTagName('span')[0];
2601 if (DOM.isElementOfType(selectedElement, 'body')) {
2602 actionSlotWidth = actionSlotWidth - DOM.findSize(deleteButton).width;
2603 deleteButton.style.display = 'none';
2604 spanElement.innerHTML = 'Body';
2605 } else {
2606 spanElement.innerHTML = imageButtonText;
2607 deleteButton.style.display = 'block';
2608 }
2609 actionSlot.style.width = actionSlotWidth + 'px';
2610 };
2611
2612 popupControl.onClose = function onClose() {
2613 upArrow.style.display = 'none';
2614 selectedElement = null;
2615 };
2616
2617 closeButton = DOM.BUILDER.BUTTON(closeButtonAttributes.values());
2618 closeButton.onclick = function closeButtonOnClick() {
2619 popupControl.close();
2620 upArrow.style.display = 'none';
2621 return false;
2622 };
2623
2624
2625 imageUpdateAction = new ImageUpdatePopupAction(pageEditor, actionSlot, uploadMode);
2626 imageUpdateAction.onComplete = function imageUpdateActionOnComplete() {
2627 self.popdown();
2628 };
2629
2630 var backgroundImage = 'http://dev.a11y.in/alipi/images/replace_image.png';
2631 backgroundButton = createActionButton(backgroundImage, backgroundButtonText, 'border-right: none;' + leftBorderStyle);
2632 backgroundButton.onclick = function backgroundButtonOnClick() {
2633 popupControl.showAction(imageUpdateAction);
2634 displayUpArrowUnderButton(backgroundButton, upArrow);
2635 return false;
2636 };
2637
2638 renUpdateAction = new renAction(pageEditor, actionSlot);
2639 renUpdateAction.onComplete = function renUpdateActionOnComplete() {
2640 self.popdown(true);
2641 };
2642
2643
2644 var renImage = 'http://dev.a11y.in/alipi/images/renarration.png';
2645 renButton = createActionButton(renImage, 'See (other) narrations', 'border-right: none;');
2646 renButton.onclick = function renButtonOnClick() {
2647 popupControl.showAction(renUpdateAction);
2648 return false;
2649 };
2650
2651 buttonPanel.appendChild(backgroundButton);
2652 buttonPanel.appendChild(renButton);
2653 imagePopupDiv.appendChild(closeButton);
2654 imagePopupDiv.appendChild(buttonPanel);
2655 imagePopupDiv.appendChild(actionSlot);
2656
2657 document.body.appendChild(imagePopupDiv);
2658
2659 deleteElement = function deleteElement() {
2660 var command = {
2661 command : 'DELETE',
2662 element : selectedElement,
2663 url : '',
2664 xpath : '',
2665 elementType : 'text',
2666 data : '',
2667 previousData : ''
2668 };
2669 pageEditor.commandApply(command);
2670 popupControl.close();
2671 };
2672 }
2673
2674 /**
2675 * Popup for text edit.
2676 */
2677 function TextElementPopup(pageEditor) {
2678 var self = this, updateText, deleteElement, textPopupDiv, selectedElement, originalTextContent, deleteButton,
2679 imageUpdateAction, popupControl, linkUpdateAction, linkButton, closeButton, textButton, doneButton,
2680 imageUpdateDiv, backgroundButton, redArrow, buttonPanel, upArrow, actionSlot,renButton, variablePassing;
2681
2682 this.popupAt = function popupAt(element, popX, popY) {
2683 popupControl.openAt(element, popX, popY);
2684 };
2685
2686 this.popdown = function popdown(saveChanges) {
2687 popupControl.close(saveChanges);
2688 };
2689
2690 buttonPanel = DOM.BUILDER.DIV(buttonPanelAttributes.values());
2691 upArrow = DOM.BUILDER.SPAN(greyArrowAttributes.values());
2692 actionSlot = DOM.BUILDER.DIV(actionPanelAttributes.values());
2693 redArrow = DOM.BUILDER.SPAN(redArrowAttributes.values());
2694 textPopupDiv = DOM.BUILDER.DIV(popupContainerAttributes.values());
2695
2696 var eatKeyboardEvents = function eatKeyboardEvents(event) {
2697 event.stopPropagation();
2698 };
2699 var handleKeyDown = function handleKeyDown(event) {
2700 switch (event.keyCode) {
2701 case 13:
2702 // Enter key
2703 self.popdown(true);
2704 event.stopPropagation();
2705 event.preventDefault();
2706
2707 return false;
2708 default:
2709 eatKeyboardEvents(event);
2710 }
2711 };
2712
2713 popupControl = new PopupControl(pageEditor, textPopupDiv, false);
2714 popupControl.onOpen = function onOpen(element) {
2715 selectedElement = element;
2716 originalTextContent = DOM.textContent(selectedElement);
2717 // actionSlot.style.marginLeft = (textButton.offsetWidth) + 'px';
2718 UTIL.addEvent(selectedElement, 'keydown', handleKeyDown);
2719 UTIL.addEvent(selectedElement, 'keyup', eatKeyboardEvents);
2720 UTIL.addEvent(selectedElement, 'keypress', eatKeyboardEvents);
2721 if (DOM.isIEBrowser() && DOM.isQuirksMode()) {
2722 actionSlot.style.marginTop = '-8px';
2723 actionSlot.style.paddingTop = '0px';
2724 }
2725 selectedElement.setAttribute('contentEditable', false);
2726 };
2727
2728 popupControl.onClose = function onClose(saveChanges) {
2729 upArrow.style.display = 'none';
2730 if (saveChanges && (DOM.textContent(selectedElement) != originalTextContent)) // || (saveChanges && hasAudio==true)
2731 {
2732 updateText();
2733 } else {
2734 DOM.textContent(selectedElement, originalTextContent);
2735 }
2736 selectedElement = null;
2737 originalTextContent = null;
2738 };
2739
2740 closeButton = DOM.BUILDER.BUTTON(closeButtonAttributes.values());
2741 closeButton.onclick = function closeButtonOnClick() {
2742 DOM.textContent(selectedElement, originalTextContent);
2743 self.popdown(false);
2744 upArrow.style.display = 'none';
2745 return false;
2746 };
2747
2748
2749
2750 var doneImage = 'http://y.a11y.in/alipi/images/done.png';
2751 doneButton = createActionButton(doneImage, 'Edit ', 'border-right: none;' + leftBorderStyle);
2752 doneButton.onclick = function doneButtonOnClick(elements) {
2753 editWindow = new EditWindow(pageEditor);
2754 document.getElementById('reference').value = selectedElement.textContent;
2755 document.getElementById('editor').value = selectedElement.textContent;
2756 selectedElement.setAttribute('id', 'alipiSelectedElement');
2757 document.getElementById("editor").removeAttribute("readonly");
2758 // DOM.textContent(selectedElement, originalTextContent);
2759 editWindow.activate();
2760 self.popdown(false);
2761 // upArrow.style.display = 'none';
2762 return false;
2763
2764 };
2765
2766
2767 this.textButtonOnClick = function textButtonOnClick() {
2768 self.popdown(true);
2769 document.getElementById('alipiSelectedElement').textContent = document.getElementById('editor').value;
2770 document.getElementById('alipiSelectedElement').removeAttribute('id', 'alipiSelectedElement');
2771 return false;
2772 };
2773
2774
2775 var renImage = 'http://dev.a11y.in/alipi/images/renarration.png';
2776 renButton = createActionButton(renImage, 'See (other) narrations', 'border-right: none;');
2777 renButton.onclick = function renButtonOnClick() {
2778 popupControl.showAction(renUpdateAction);
2779 return false;
2780 };
2781
2782 renUpdateAction = new renAction(pageEditor, actionSlot);
2783 renUpdateAction.onComplete = function renUpdateActionOnComplete() {
2784 self.popdown(true);
2785 };
2786
2787 audioUpdateAction = new AudioUpdateByUrl(pageEditor, actionSlot);
2788 audioUpdateAction.onComplete = function audioUpdateActionOnComplete() {
2789 self.popdown(false);
2790 };
2791
2792 var audioImage = 'http://dev.a11y.in/alipi/images/audio.png';
2793 audioButton = createActionButton(audioImage,'Audio','border-right:none;');
2794 audioButton.onclick = function audioButtonOnClick() {
2795 selectedElement.setAttribute('id', 'alipiSelectedElement');
2796 audioUpdateAction = new AudioUpdateByUrl(pageEditor);
2797 audioUpdateAction.display();
2798 self.popdown(true);
2799 return false;
2800 };
2801
2802
2803 imageUpdateAction = new ImageUpdatePopupAction(pageEditor, actionSlot, 'BACKGROUND_IMAGE_UPDATE');
2804 imageUpdateAction.onComplete = function imageUpdateActionOnComplete() {
2805 self.popdown(true);
2806 };
2807
2808 var backgroundImage = 'http://dev.a11y.in/alipi/images/replace_image.png';
2809 backgroundButton = createActionButton(backgroundImage, 'BG&nbsp;Image', 'border-right: none;');
2810 backgroundButton.onclick = function backgroundButtonOnClick() {
2811 popupControl.showAction(imageUpdateAction);
2812 imageUpdateAction.open(selectedElement.parentNode);
2813 displayUpArrowUnderButton(backgroundButton, upArrow);
2814 return false;
2815 };
2816
2817 buttonPanel.appendChild(doneButton);
2818 buttonPanel.appendChild(renButton);
2819 buttonPanel.appendChild(audioButton);
2820 textPopupDiv.appendChild(closeButton);
2821 textPopupDiv.appendChild(buttonPanel);
2822 textPopupDiv.appendChild(actionSlot);
2823 document.body.appendChild(textPopupDiv);
2824
2825 updateText = function updateText() {
2826 var command = {
2827 command : 'TEXT_UPDATE',
2828 element : selectedElement,
2829 url : window.location.href,
2830 xpath : DOM.getXPATH(selectedElement),
2831 elementType : 'text',
2832 data : DOM.textContent(selectedElement),
2833 previousData : originalTextContent
2834 };
2835 pageEditor.commandApply(command);
2836 if (DOM.textContent(selectedElement).length == 0) {
2837 deleteElement();
2838 }
2839 };
2840
2841 deleteElement = function deleteElement() {
2842 var command = {
2843 command : 'DELETE',
2844 element : selectedElement,
2845 url : '',
2846 elementType : 'text',
2847 data : '',
2848 xpath : '',
2849 data : '',
2850 previousData : ''
2851 };
2852 pageEditor.commandApply(command);
2853 };
2854 }
2855
2856
2857
2858 /**
2859 * Overlay bar which can function in either visual editor or html editor mode.
2860 */
2861 function OverlayBar(pageEditor, isVisualEditor) {
2862 var self = this, overlayDiv, firstRowDiv, firstRowStyleAttributes, messageDiv, publishButton, undoButton,fillUpButton;
2863 var moveDiv, editModeChangeOverlayDiv, buttonDiv, editModeChangeButtonDiv, editModeChangeSaveButton, editModeChangeDiscardButton;
2864 var redButtonStyleAttributes, fillUpButtonStyleAttributes, firstRowDivOffset, calculateScrollPositionY, wrapperDiv,showKeepOriginalOverlay, publishOptions = new PublishOptions();
2865
2866
2867 overlayDiv = document.createElement("div");
2868 overlayDiv.setAttribute("id", "overlay-div");
2869 overlayDiv.setAttribute("alipielements", "alipi");
2870 overlayDiv.setAttribute("style", "overflow-x:visible; position:fixed; z-index:2147483645; left:0; top:0; width:100%; height:30px; background-color:rgba(0, 0, 0, 0.5);");
2871 document.body.appendChild(overlayDiv);
2872
2873
2874 image = document.createElement("img");
2875 image.setAttribute("id", "close-image");
2876 image.setAttribute("alipielements", "alipi");
2877 image.setAttribute("src", "http://dev.a11y.in/alipi/images/close_button.png");
2878 image.setAttribute("style", "position:relative;width:25px;height:28px;");
2879 overlayDiv.appendChild(image);
2880 image.onclick=function(){
2881 answer = confirm("Do you really want to exit the editor?")
2882 if (answer !=0)
2883 {
2884 window.location.reload();
2885 }
2886 }
2887
2888
2889 messageDiv = document.createElement("div");
2890 messageDiv.setAttribute("id", "message-div");
2891 messageDiv.setAttribute("alipielements", "alipi");
2892 messageDiv.setAttribute("style", "position:relative;left:150px;bottom:26px;font-size:23px;font-weight:bold;color:#ffe;");
2893 overlayDiv.appendChild(messageDiv);
2894
2895 helpLink = document.createElement("input");
2896 helpLink.setAttribute("id", "help");
2897 helpLink.setAttribute("alipielements", "alipi");
2898 helpLink.setAttribute("type", "submit");
2899 helpLink.setAttribute("Value", "Help");
2900 helpLink.setAttribute("style", "position:relative;top:-55px;left:750px;font-size:18px;font-weight:bold;width:100px;height:30px;");
2901 overlayDiv.appendChild(helpLink);
2902 helpLink.onclick = function helpLinkOnClick() {
2903 helpWindow = new HelpWindow(pageEditor);
2904 helpWindow.createLabels();
2905 helpWindow.activate();
2906
2907 };
2908
2909
2910 undoButton = document.createElement("input");
2911 undoButton.setAttribute("id", "undo");
2912 undoButton.setAttribute("alipielements", "alipi");
2913 undoButton.setAttribute("type", "submit");
2914 undoButton.setAttribute("Value", "Undo");
2915 undoButton.setAttribute("style", "position:relative;top:-55px;left:825px;font-size:18px;font-weight:bold;width:100px;height:30px;");
2916 overlayDiv.appendChild(undoButton);
2917 undoButton.onclick = function undoButtonOnClick() {
2918 pageEditor.commandUndo();
2919 return false;
2920 };
2921
2922
2923 publishButton = document.createElement("input");
2924 publishButton.setAttribute("id", "publish");
2925 publishButton.setAttribute("alipielements", "alipi");
2926 publishButton.setAttribute("type", "submit");
2927 publishButton.setAttribute("Value", "Publish");
2928 publishButton.setAttribute("style", "position:relative;top:-55px;left:900px;font-size:18px;font-weight:bold;width:100px;height:30px;");
2929 overlayDiv.appendChild(publishButton);
2930 var dialog = 0;
2931 publishButton.onclick = function publishButtonOnClick() {
2932 if (pageEditor.hasChangesPending() /* && (pageEditor.formUncomplete() ==false) */ ) {
2933 targetWindow = new TargetWindow(pageEditor);
2934 if (dialog == 0) {
2935 targetWindow.createDialogBox();
2936 dialog = 1;
2937 }
2938 targetWindow.activate();
2939 } else {
2940 pageEditor.showMessage("Nothing to post");
2941 }
2942 };
2943
2944
2945 this.blogpost = function blogpost() {
2946 if (locName.value == "" || langName.value == "" || styleSelect.value == "" || author.value == "" || (ourcheck.checked == false && yourcheck.checked == false)) {
2947 alert("Please give all the details, it will be used further");
2948 } else {
2949 pageEditor.commandPublish();
2950 pageEditor.showMessage("... Please wait, your blog is being posted");
2951 $('#targetoverlay').remove();
2952 }
2953 };
2954 // End of okButton function
2955
2956 this.show = function show(activate) {
2957 // overlayDiv.style.display = 'block';
2958 var disabled = true;
2959 var opacity = '0.4';
2960 if (activate) {
2961 disabled = false;
2962 opacity = '1.0';
2963 }
2964
2965 undoButton.disabled = false;
2966 publishButton.disabled = false;
2967
2968 undoButton.style.opacity = "1";
2969 publishButton.style.opacity = "1";
2970 publishOptions.hide();
2971 };
2972
2973 this.message = function message(value) {
2974 messageDiv.innerHTML = value;
2975 };
2976
2977
2978 function PublishOptions() {
2979 var self = this, wrapperDiv, keepOriginalCheckbox, activateOptionsTimerId, cancelTimer, activatePublishOptions;
2980 var checkboxId = 'm4PublishOptionsCheckbox-' + new Date().getTime();
2981 keepOriginalCheckbox = DOM.BUILDER.INPUT(
2982 editAttributes.put({
2983 name : 'Publish Options',
2984 type : 'checkbox', id: checkboxId}).addStyle(
2985 'font-family: Helvetica Neue, Helvetica, Ariel, Sans-serif; font-size: 10px; width: 14px; height: 14px; margin: 0; padding: 0; position: relative; background: transparent;').values()
2986 );
2987 keepOriginalCheckbox.onclick = function() {
2988 keepOriginal = keepOriginalCheckbox.checked;
2989 };
2990 var backgroundImage = 'url(http://dev.a11y.in/alipi/images/container_save_new_page.png) no-repeat scroll 0 0 transparent';
2991 var position = 'fixed';
2992
2993 wrapperDiv = DOM.BUILDER.DIV(editAttributes.addStyle('font-family: Helvetica Neue, Helvetica, Ariel, Sans-serif; font-size: 10px; display: table; vertical-align: middle; z-index: 2147483647; margin: 0; width: 134px; height: 33px; line-height: 33px; position: '+ position+ '; right: 10px; background:'+ backgroundImage + ' ; display:none;').values(), DOM.BUILDER.SPAN(editAttributes.addStyle(('font-family: Helvetica Neue, Helvetica, Ariel, Sans-serif; font-size: 10px; display: table-cell; vertical-align: middle; height: 14px; hasLayout=true;')).values(), DOM.BUILDER.SPAN(editAttributes.addStyle('font-family: Helvetica Neue, Helvetica, Ariel, Sans-serif; font-size: 10px; display: inline; vertical-align: middle; height: 10px; width: 14px; padding: 0; margin: 1px 0 0 13px;').values(), keepOriginalCheckbox), DOM.BUILDER.LABEL(normalFontAttributes.put({'for' : checkboxId}).addStyle(('font-family: Helvetica Neue, Helvetica, Ariel, Sans-serif; display: inline; font-size: 10px; background: transparent; color: #E9E9E9; padding: 0 0 0 5px;')).values(),'Save as new page.')));
2994
2995 UTIL.addEvent(wrapperDiv, 'mouseout', function publishButtonMouseOut(event) {
2996 self.hide();
2997 });
2998
2999 UTIL.addEvent(wrapperDiv, 'mouseover', function publishButtonMouseOver(event) {
3000 cancelTimer();
3001 activatePublishOptions(true);
3002 });
3003
3004 document.body.appendChild(wrapperDiv);
3005
3006 this.show = function show(onTop, margin) {
3007 if (onTop) {
3008 wrapperDiv.style.top = '0px';
3009 wrapperDiv.style.marginTop = margin + 'px';
3010 DOM.deleteStyleProperty(wrapperDiv, 'bottom');
3011 } else {
3012 wrapperDiv.style.bottom = '0px';
3013 wrapperDiv.style.marginBottom = margin + 'px';;
3014 DOM.deleteStyleProperty(wrapperDiv, 'top');
3015 }
3016 activatePublishOptions(true);
3017 cancelTimer();
3018 activateOptionsTimerId = setTimeout(function() {
3019 activatePublishOptions(false);
3020 }, 5000);
3021 };
3022
3023 this.hide = function hide() {
3024 activatePublishOptions(false);
3025 };
3026
3027 this.scrollToPosition = function scrollToPosition(onTop, position) {
3028 if (onTop) {
3029 wrapperDiv.style.top = position;
3030 } else {
3031 wrapperDiv.style.bottom = position;
3032 }
3033 };
3034
3035 cancelTimer = function cancelTimer() {
3036 if (activateOptionsTimerId) {
3037 clearTimeout(activateOptionsTimerId);
3038 }
3039 };
3040
3041 activatePublishOptions = function activatePublishOptions(activate) {
3042 if (hasEditPermission == 'true' && activate) {
3043 wrapperDiv.style.display = 'table';
3044 } else {
3045 wrapperDiv.style.display = 'none';
3046 }
3047 };
3048 }
3049 }
3050
3051
3052 /**
3053 * Manages page level keyboard shortcuts.
3054 */
3055 function PageShortcuts(pageEditor) {
3056 this.enable = function enable() {
3057 DOM.addListener('keydown', function keydownHandler(event) {
3058 switch (event.keyCode) {
3059 case 27:
3060 // ESC
3061// event.preventDefault();
3062// event.stopPropagation();
3063// pageEditor.close();
3064// return false;
3065 // case 77:
3066 // // "m"
3067 // if (pageEditor.hasFocus()) {
3068 // event.preventDefault();
3069 // event.stopPropagation();
3070 // pageEditor.moveOverlayBar();
3071 // }
3072 // return false;
3073
3074 // case 85:
3075 // // "u"
3076 // if (pageEditor.hasFocus()) {
3077 // event.preventDefault();
3078 // event.stopPropagation();
3079 // pageEditor.commandUndo();
3080 // }
3081 return false;
3082 }
3083 }, true);
3084 }
3085 }
3086
3087 /**
3088 * Maintains command history and related features like undo and publish.
3089 */
3090 function EditCommandHistory(pageEditor) {
3091 var self = this, history = [], imageSrc, imageMatcher, imageHeight, imageWidth, buildDataString, anchorElement, anchorElementId, ajaxResultProcessor = new AjaxResultProcessor();
3092
3093 this.hasChangesPending = function hasChangesPending() {
3094 return history.length > 0;
3095 };
3096 this.formUncomplete = function formUnomplete(){
3097 return (locName == '' && langName=='' && styleName == '' );
3098 };
3099
3100 this.apply = function apply(command) {
3101 var poofPosition, poofDiv;
3102
3103 switch (command.command) {
3104 case 'TEXT_UPDATE':
3105 command.element = document.getElementById("alipiSelectedElement");
3106 command.previousData = document.getElementById("alipiSelectedElement").textContent;
3107 command.data = document.getElementById("editor").value;
3108 DOM.textContent(command.element, command.data);
3109 pageEditor.showMessage('Text changed');
3110 break;
3111 case 'AUDIO_SRC_UPDATE':
3112 textElementPopup.hasAudio = true;
3113 command.previousData = "";
3114 pageEditor.showMessage('Audio updated');
3115 break;
3116
3117 case 'DELETE':
3118 poofPosition = DOM.findPosition(command.element);
3119
3120 poofDiv = DOM.BUILDER.DIV({'style' : 'width:32px;height:32px;background: transparent url(http://y.a11y.in/alipi/images/poof.png) no-repeat;position:absolute;top:' + poofPosition.y + 'px;left:' + poofPosition.x + 'px;'});
3121 document.body.appendChild(poofDiv);
3122
3123 UTIL.animate(function(index, last) {
3124 if (last) {
3125 document.body.removeChild(poofDiv);
3126 } else {
3127 poofDiv.style.backgroundPosition = '0 -' + (index * 32) + 'px';
3128 }
3129 }, 5, 100);
3130
3131 DOM.overrideStyleProperty(command.element, 'display', 'none');
3132 pageEditor.showMessage('Section deleted');
3133 break;
3134
3135 case 'IMAGE_SRC_UPDATE':
3136 imageMatcher = new RegExp("(\\d+)x(\\d+),(.+)").exec(command.data);
3137 imageWidth = imageMatcher[1];
3138 imageHeight = imageMatcher[2];
3139 imageSrc = imageMatcher[3];
3140
3141 if (imageSrc && command.element.src != imageSrc) {
3142 command.element.src = imageSrc;
3143 pageEditor.showMessage('Image changed');
3144 }
3145 if (imageWidth == 0) {
3146 command.element.removeAttribute('width');
3147 } else {
3148 command.element.width = imageWidth;
3149 }
3150
3151 if (imageHeight == 0) {
3152 command.element.removeAttribute('height');
3153 } else {
3154 command.element.height = imageHeight;
3155 }
3156 break;
3157
3158 case 'ANCHOR_UPDATE':
3159 command.element.setAttribute('href', command.data);
3160 pageEditor.showMessage('Link changed');
3161 break;
3162
3163 case 'ANCHOR_CREATE':
3164 anchorElement = DOM.BUILDER.A({ 'href' : command.data });
3165 command.element.parentNode.replaceChild(anchorElement, command.element);
3166 anchorElement.appendChild(command.element);
3167 command.previousData = anchorElement;
3168 pageEditor.showMessage('Link added');
3169 break;
3170
3171 case 'AUDIO_UPDATE':
3172 command.element.setAttribute('src', command.data);
3173 pageEditor.showMessage('Audio changed');
3174 break;
3175
3176 case 'AUDIO_CREATE':
3177 audioElement = document.createElement('audio');
3178 audioElement.setAttribute("id", "audiotag");
3179 audioElement.setAttribute('src',command.data);
3180 audioElement.setAttribute('controls','controls');
3181 audioElement.setAttribute('style', 'display:table;');
3182 $(audioElement).insertBefore($(selectedElement));
3183 pageEditor.showMessage('Audio added');
3184 break;
3185
3186 default:
3187 console.error('Unknown command:', command);
3188 }
3189
3190 history.push(command);
3191 };
3192
3193 this.undo = function undo() {
3194 var imageElement, command;
3195
3196 if (self.hasChangesPending()) {
3197 command = history.pop();
3198 switch (command.command) {
3199 case 'TEXT_UPDATE':
3200 command.element.innerHTML = command.previousData;
3201 pageEditor.showMessage('Text change undone');
3202 break;
3203
3204 case 'DELETE':
3205 DOM.restoreStyleProperty(command.element, 'display', '');
3206 pageEditor.showMessage('Delete undone');
3207 break;
3208
3209 case 'IMAGE_SRC_UPDATE':
3210 imageElement = new M4ImageElement(command.element);
3211
3212 command.element.src = command.previousData.src;
3213 if (command.previousData.size.width) {
3214 command.element.width = command.previousData.size.width;
3215 } else {
3216 command.element.removeAttribute('width');
3217 }
3218 if (command.previousData.size.height) {
3219 command.element.height = command.previousData.size.height;
3220 } else {
3221 command.element.removeAttribute('height');
3222 }
3223 imageElement.setRawImageSize(command.previousData.rawImageSize)
3224
3225 pageEditor.showMessage('Image change undone');
3226 break;
3227
3228 case 'AUDIO_SRC_UPDATE':
3229 command.element.remove();
3230 pageEditor.showMessage('Link removed');
3231 break;
3232 case 'ANCHOR_UPDATE':
3233 command.element.setAttribute('href', command.previousData);
3234 pageEditor.showMessage('Link change undone');
3235 break;
3236
3237 case 'ANCHOR_CREATE':
3238 command.previousData.parentNode.replaceChild(command.element, command.previousData);
3239 pageEditor.showMessage('Link removed');
3240 break;
3241
3242 default:
3243 console.error('Unknown command:', command);
3244 }
3245 } else {
3246 pageEditor.showMessage('Nothing to undo');
3247 }
3248 };
3249
3250 this.publish = function publish() {
3251 var result;
3252 if(document.getElementById('our-check').checked)
3253 {
3254 localStorage.myContent = buildDataString();
3255 window.location.href = "http://dev.a11y.in/test.html";
3256 window.reload();
3257 }
3258 else{
3259
3260 AJAX.post('http://dev.a11y.in/test', buildDataString(), function(result) {
3261 ajaxResultProcessor.processPublishedResponse(result);
3262 });
3263 }
3264 };
3265
3266 // this.switchMode = function switchMode(saveChanges) {
3267 // var result, requestParameters;
3268
3269 // requestParameters = '?slug=' + pageSlug + '&uploadSlug=' + uploadSlug;
3270 // if (successUrl) {
3271 // requestParameters = requestParameters + '&successUrl=' + encodeURIComponent(successUrl);
3272 // }
3273
3274 // if (saveChanges) {
3275 // result = AJAX.post('/app/page-edit/switch-edit-mode' + requestParameters,
3276 // buildDataString());
3277 // ajaxResultProcessor.processSwitchModeResponse(result);
3278 // } else {
3279 // window.location.href = 'https://bo.lt/app/page-edit/html' + requestParameters;
3280 // }
3281 // };
3282
3283 buildDataString = function buildDataString() {
3284 var check_xpath = [], temp_history = [], index = [];
3285 for(x=0; x<history.length; x++) {
3286 check_xpath.push(history[x].xpath);
3287 }
3288 for(i=0; i<check_xpath.length-1; i++) {
3289 for(j=i+1; j<check_xpath.length; j++) {
3290 if ((check_xpath[i] == check_xpath[j]) && (history[i].elementType == history[j].elementType)) {
3291 index.push(i);
3292 }
3293 }
3294 }
3295 if (index.length > 0) {
3296 for (var z=0; z<index.length; z++) {
3297 delete history[index[z]];
3298 }
3299 }
3300
3301 for (var x=0; x<history.length; x++) {
3302 if (history[x] != undefined) {
3303 temp_history.push(history[x]);
3304 }
3305 }
3306
3307 history = temp_history;
3308
3309 var command, buffer;
3310 buffer = new UTIL.StringBuffer();
3311 UTIL.forEach(history, function(index, command) {
3312 buffer.append('###'); //separates the commands
3313 buffer.append('about='); //url=about //removed '&' on purpose
3314 buffer.append(window.location.search.split('=')[1]);
3315 buffer.append('&lang=');//lang
3316 buffer.append(encodeURIComponent(langName.value));
3317 buffer.append('&location=');//location
3318 buffer.append(encodeURIComponent(locName.value));
3319 buffer.append('&style=');//style
3320 buffer.append(encodeURIComponent(styleSelect.value));
3321 buffer.append('&blog='); //blog where to post
3322 buffer.append(encodeURIComponent("blog"));
3323 buffer.append('&elementtype='); // text, audio, img
3324 buffer.append(encodeURIComponent(command.elementType));
3325 buffer.append('&xpath=');//xpath
3326 buffer.append(encodeURIComponent(command.xpath));
3327 buffer.append('&data='); //data
3328 buffer.append(encodeURIComponent(command.data));
3329 buffer.append('&author='); //author
3330 if (author.value == '') {
3331 buffer.append(encodeURIComponent('Anonymous'));
3332 } else {
3333 buffer.append(encodeURIComponent(author.value));
3334 }
3335 }); console.log(buffer.toString());
3336 return buffer.toString().substring(3);
3337 };
3338 }
3339
3340 /**
3341 * Main coordinator for the visual editor's overlay, shortcuts, edits and primary popups.
3342 */
3343 function VisualPageEditor() {
3344 var self = this, overlayBar, pageShortcuts, editCommandHistory, editorHasFocus = true, listeners = new Array(),
3345 textElementSelector, imageElementSelector, editableElementSelector, preProcessors = new Array(),
3346 currentSelector = null, updateSelection, getSelectorForType, focus, closePopup;
3347 var ACTION = {
3348 MOUSE_OVER : 0, MOUSE_OUT: 1, MOUSE_CLICK: 2
3349 };
3350
3351 overlayBar = new OverlayBar(this, true);
3352 pageShortcuts = new PageShortcuts(this);
3353 editCommandHistory = new EditCommandHistory(this);
3354
3355 preProcessors.push(new FlashPreProcessor());
3356 preProcessors.push(new IframePreProcessor());
3357 preProcessors.push(new FormPreProcessor());
3358
3359 textElementSelector = new TextElementSelector(self);
3360 imageElementSelector = new ImageElementSelector(self);
3361 editableElementSelector = new EditableElementSelector(self);
3362
3363 this.hasChangesPending = function hasChangesPending() {
3364 return editCommandHistory.hasChangesPending();
3365 };
3366
3367
3368 this.formUncomplete = function fromUncomplete() {
3369 return editCommandHistory.formUncomplete();
3370 };
3371
3372 this.show = function show() {
3373
3374 DOM.addListener('mouseover', function globalMouseOverListener(event) {
3375 if(event.target.id != 'ok-button'){
3376 var type = event.target.getAttribute('m4pageedittype');
3377 if (type) {
3378 event.preventDefault();
3379 event.stopPropagation();
3380 updateSelection(ACTION.MOUSE_OVER, event);
3381 }}
3382 }, true);
3383
3384 DOM.addListener('mouseout', function globalMouseOutListener(event) {
3385 var type = event.target.getAttribute('m4pageedittype');
3386 if (type) {
3387 event.preventDefault();
3388 event.stopPropagation();
3389 updateSelection(ACTION.MOUSE_OUT, event);
3390 }
3391 }, true);
3392
3393 DOM.addListener('click', function globalClickListener(event) {
3394 var type = event.target.getAttribute('m4pageedittype');
3395 var alipiElements = event.target.getAttribute('alipiElements');
3396 if (event.target.getAttribute('m4pageeditcontrol')) {
3397 // click is passthrough for our controls
3398 } else if (type) {
3399 event.preventDefault();
3400 event.stopPropagation();
3401 updateSelection(ACTION.MOUSE_CLICK, event);
3402 } else if (event.target.id == "" || alipiElements || event.target.parentNode.attributes['class'].value == "ui-menu-item") { // click is passthrough for our controls
3403 } else {
3404 // normal page elements
3405 event.preventDefault();
3406 event.stopPropagation();
3407 self.saveAndClose();
3408 }
3409 }, true);
3410
3411 // We intercept mousedown so things like drop down box won't work during edit mode.
3412 DOM.addListener('mousedown', function globalMouseDownListener(event) {
3413
3414 var alipiElements = event.target.getAttribute('alipiElements');
3415 if (event.target.getAttribute('m4pageeditcontrol')) {
3416 // passthrough
3417 } else if (event.target.getAttribute('m4pageedittype')) {
3418 // passthrough
3419 } else if (event.target.id == "lang-select" || event.target.id == "loc-select" || alipiElements) {
3420 // passthrough
3421 } else if (event.clientX > document.body.clientWidth || event.clientY > document.body.clientHeight) {
3422 // passthrough if this click was outside of the html page, meaning on a scrollbar
3423 } else {
3424 // normal page elements
3425 event.preventDefault();
3426 event.stopPropagation();
3427 }
3428 }, true);
3429 pageShortcuts.enable();
3430 overlayBar.show(false);
3431 overlayBar.message("Ready to Narrate");
3432 };
3433
3434
3435 updateSelection = function updateSelection(action, event) {
3436 var type, selector, element = event.target;
3437 selector = getSelectorForType(element.getAttribute('m4pageedittype'));
3438 if (selector) {
3439 switch (action) {
3440 case ACTION.MOUSE_OVER:
3441 if (currentSelector == null) {
3442 selector.highlight(element);
3443 }
3444 break;
3445 case ACTION.MOUSE_OUT:
3446 if (currentSelector == null) {
3447 selector.unhighlight(element);
3448 }
3449 break;
3450 case ACTION.MOUSE_CLICK:
3451 if (currentSelector == null) {
3452 currentSelector = selector;
3453 currentSelector.select(element, event);
3454 } else if (currentSelector.isCurrentSelection(element)) {
3455 currentSelector.select(element, event);
3456 } else {
3457 self.saveAndClose();
3458 selector.focus();
3459 selector.highlight(element);
3460 }
3461 break;
3462 }
3463 }
3464 };
3465
3466 getSelectorForType = function getSelectorForType(type) {
3467
3468 switch (type) {
3469 case 'text':
3470 return textElementSelector;
3471 case 'image':
3472 return imageElementSelector;
3473 case 'edit':
3474 return editableElementSelector;
3475 }
3476 return null;
3477 };
3478
3479 focus = function focus(saveChanges) {
3480 editorHasFocus = true;
3481 for (var i = 0; i < listeners.length; i++) {
3482 listeners[i](saveChanges)
3483 }
3484 };
3485
3486 closePopup = function closePopup(saveChanges) {
3487 if (currentSelector != null) {
3488 currentSelector.unselect();
3489 currentSelector = null;
3490 }
3491 focus(saveChanges);
3492 };
3493
3494 this.loseFocus = function loseFocus() {
3495 editorHasFocus = false;
3496 };
3497
3498 this.hasFocus = function hasFocus() {
3499 return editorHasFocus;
3500 };
3501
3502 this.addFocusListener = function addFocusListener(listener) {
3503 listeners.push(listener)
3504 };
3505
3506 this.removeFocusListener = function(listener) {
3507 for (var i = 0; i < listeners.length; i++) {
3508 if (listeners[i] == listener) {
3509 listeners.splice(i, 1);
3510 }
3511 }
3512 };
3513
3514 this.close = function close() {
3515 closePopup(false);
3516 };
3517
3518 this.saveAndClose = function saveAndClose() {
3519 closePopup(true);
3520 };
3521
3522 // this composition is necessary to avoid circular dependencies
3523 // this.moveOverlayBar = function moveOverlayBar() {
3524 // overlayBar.move();
3525 // };
3526
3527 this.showMessage = function showMessage(message) {
3528 overlayBar.message(message);
3529 };
3530
3531 this.commandApply = function commandApply(command) {
3532 editCommandHistory.apply(command);
3533 };
3534
3535 this.commandUndo = function commandUndo() {
3536 editCommandHistory.undo();
3537 };
3538
3539 this.commandPublish = function commandPublish() {
3540
3541 overlayBar.show(false);
3542 self.saveAndClose();
3543 for (var i = 0; i < preProcessors.length; i++) {
3544 preProcessors[i].restore();
3545 }
3546 editCommandHistory.publish();
3547 overlayBar.show(true);
3548 };
3549
3550 this.activateEditor = function activateEditor() {
3551 overlayBar.show(true);
3552 for (var i = 0; i < preProcessors.length; i++) {
3553 preProcessors[i].process();
3554 }
3555 };
3556
3557 function IframePreProcessor () {
3558 this.process = function process() {
3559 // make iframes unclickable by overlaying transparent div over it.
3560 UTIL.forEach(document.getElementsByTagName('iframe'), function(index, iframe) {
3561 var displayStyle = null;
3562 if (document.defaultView && document.defaultView.getComputedStyle) {
3563 displayStyle = document.defaultView.getComputedStyle(iframe, null).getPropertyValue('display');
3564 } else if (iframe.currentStyle) {
3565 displayStyle = iframe.currentStyle['display'];
3566 }
3567 if(displayStyle != 'none') {
3568 DOM.clickBlocker(iframe);
3569 }
3570 var iframeSourceUrl = iframe.src;
3571 var isYouTubeIFrame = iframeSourceUrl.toLowerCase().indexOf('youtube') != -1;
3572 if (isYouTubeIFrame) {
3573 // If the flash object is visible when the wmode property is set, then the state doesn't get updated.
3574 // So first set the parent node's display property to 'none, then add the wmode property and finally
3575 // restore the original display proeprty back on the parent.
3576 DOM.overrideStylePropert(iframe.parentNode, 'display', 'none');
3577 if(iframeSourceUrl.indexOf('?') != -1) {
3578 iframe.src = iframeSourceUrl + '&wmode=opaque';
3579 } else {
3580 iframe.src = iframeSourceUrl + '?wmode=opaque';
3581 }
3582 DOM.restoreStyleProperty(iframe.parentNode, 'display');
3583 }
3584 });
3585 };
3586
3587 this.restore = function restore() {
3588 };
3589 };
3590
3591 function FlashPreProcessor() {
3592 this.process = function process() {
3593 // make flash objects unclickable by overlaying transparent div over it.
3594 // If the flash object is visible when the wmode property is set, then the state doesn't get updated.
3595 // So first set the parent node's display property to 'none, then add the wmode property and finally
3596 // restore the original display proeprty back on the parent.
3597 UTIL.forEach(document.getElementsByTagName('object'), function(index, value) {
3598 DOM.overrideStyleProperty(value.parentNode, 'display', 'none');
3599 DOM.clickBlocker(value);
3600 var param = document.createElement('param');
3601 param.setAttribute('name', 'wmode');
3602 param.setAttribute('value', 'opaque');
3603 value.appendChild(param);
3604 DOM.restoreStyleProperty(value.parentNode, 'display');
3605 });
3606
3607 UTIL.forEach(document.getElementsByTagName('embed'), function(index, value) {
3608 DOM.overrideStyleProperty(value.parentNode, 'display', 'none');
3609 DOM.clickBlocker(value);
3610 value.setAttribute('wmode', 'opaque');
3611 DOM.restoreStyleProperty(value.parentNode, 'display');
3612 });
3613 };
3614
3615 this.restore = function restore() {
3616 };
3617 };
3618
3619 function FormPreProcessor () {
3620 var overrideElementAttribute = function overrideElementAttribute(nodeName, attributeName, attributeValue) {
3621 UTIL.forEach(document.getElementsByTagName(nodeName), function(index, inputElement) {
3622 var type = inputElement.getAttribute('m4pageeditcontrol');
3623 if (!type) {
3624 DOM.overrideAttribute(inputElement, attributeName, attributeValue);
3625 }
3626 });
3627 };
3628
3629 var restoreElementAttribute = function restoreElementAttribute(nodeName, attributeName) {
3630 UTIL.forEach(document.getElementsByTagName(nodeName), function(index, inputElement) {
3631 var type = inputElement.getAttribute('m4pageeditcontrol');
3632 if (!type) {
3633 DOM.restoreAttribute(inputElement, attributeName);
3634 }
3635 });
3636 };
3637
3638 this.process = function process() {
3639 overrideElementAttribute('input', 'readonly', 'true');
3640 overrideElementAttribute('textarea', 'readonly', 'true');
3641 };
3642
3643 this.restore = function restore() {
3644 restoreElementAttribute('input', 'readonly');
3645 restoreElementAttribute('textarea', 'readonly');
3646 };
3647 };
3648
3649 function ImageElementSelector(pageEditor) {
3650 var self = this, imageElementPopup = new EditableElementPopup(pageEditor, true), lastSelection = null;
3651 this.highlight = function highlight(element) {
3652 DOM.overrideStyleProperty(element, 'outline', '#777 solid 2px');
3653 DOM.overrideStyleProperty(element, 'cursor', 'pointer');
3654 };
3655
3656 this.unhighlight = function unhighlight(element) {
3657 DOM.restoreStyleProperty(element, 'cursor', '');
3658 DOM.restoreStyleProperty(element, 'outline', '');
3659 };
3660
3661 this.select = function select(element, event) {
3662 if (lastSelection == null) {
3663 lastSelection = element;
3664 self.unhighlight(lastSelection);
3665 self.highlight(lastSelection);
3666 imageElementPopup.popupAt(lastSelection, event.pageX, event.pageY);
3667 }
3668 };
3669
3670 this.unselect = function unselect() {
3671 if (lastSelection) {
3672 self.unhighlight(lastSelection);
3673 }
3674 lastSelection = null;
3675 };
3676
3677 this.isCurrentSelection = function isCurrentSelection(element) {
3678 return lastSelection == element;
3679 };
3680
3681 this.focus = function focus(element) {
3682 // NO OP
3683 };
3684 };
3685
3686 function EditableElementSelector(pageEditor) {
3687 var self = this, editableElementPopup = new EditableElementPopup(pageEditor, false), lastSelection = null;
3688
3689 this.highlight = function highlight(element) {
3690 DOM.overrideStyleProperty(element, 'outline', '');
3691 DOM.overrideStyleProperty(element, 'cursor', 'pointer');
3692 };
3693
3694 this.unhighlight = function unhighlight(element) {
3695 DOM.restoreStyleProperty(element, 'cursor', '');
3696 DOM.restoreStyleProperty(element, 'outline', '');
3697 };
3698
3699 this.select = function select(element, event) {
3700 if (lastSelection == null) {
3701 lastSelection = element;
3702 self.unhighlight(lastSelection);
3703 self.highlight(lastSelection);
3704 editableElementPopup.popupAt(lastSelection, event.pageX, event.pageY);
3705 }
3706 };
3707
3708 this.unselect = function unselect() {
3709 if (lastSelection) {
3710 self.unhighlight(lastSelection);
3711 }
3712 lastSelection = null;
3713 };
3714
3715 this.isCurrentSelection = function isCurrentSelection(element) {
3716 return lastSelection == element;
3717 }
3718
3719 this.focus = function focus(element) {
3720 // NO OP
3721 };
3722 };
3723
3724 function TextElementSelector(pageEditor) {
3725 var self = this, lastSelection = null, textElementPopup = new TextElementPopup(pageEditor), editor,
3726 findAnchorAncestor, internalHighlight;
3727
3728 if(DOM.isIEBrowser()) {
3729 editor = new InternetExplorerInlineEditor();
3730 } else {
3731 editor = new DefaultInlineEditor();
3732 }
3733
3734 this.highlight = function highlight(element) {
3735
3736 internalHighlight(element, '#fff', '#bbb', 'pointer');
3737 editor.activate(element);
3738 };
3739
3740 this.unhighlight = function unhighlight(element) {
3741 DOM.restoreStyleProperty(element, 'borderLeft', '');
3742 DOM.restoreStyleProperty(element, 'borderRight', '');
3743 DOM.restoreStyleProperty(element, 'cursor', '');
3744 DOM.restoreStyleProperty(element, 'backgroundColor', '');
3745 DOM.restoreStyleProperty(element, 'color', '');
3746 editor.deactivate(element);
3747 };
3748
3749 this.select = function select(element, event) {
3750 if (lastSelection == null) {
3751 lastSelection = element;
3752 self.unhighlight(lastSelection);
3753 editor.activate(element);
3754 internalHighlight(lastSelection, '#333', '#fff', 'text');
3755 textElementPopup.popupAt(lastSelection, event.pageX, event.pageY);
3756 }
3757 editor.startEditing(event);
3758 };
3759
3760
3761 this.unselect = function unselect() {
3762 if (lastSelection) {
3763 self.unhighlight(lastSelection);
3764 editor.stopEditing();
3765 }
3766 lastSelection = null;
3767 };
3768
3769 this.isCurrentSelection = function isCurrentSelection(element) {
3770 return lastSelection == element;
3771 };
3772
3773 this.focus = function focus(element) {
3774 editor.focus();
3775 };
3776 internalHighlight = function internalHighlight(element, highlightColor, highlightBackground, cursorType) {
3777 // because element containing text often have a calculated height of
3778 // 0, even when text is showing, we need to highlight using background
3779 // color.
3780 DOM.overrideStyleProperty(element, 'cursor', cursorType);
3781 DOM.overrideStyleProperty(element, 'borderLeft', '#FFF solid 2px'); // Ajay -changed color but can't notice where
3782 DOM.overrideStyleProperty(element, 'borderRight', '#000 solid 2px'); // Ajay- Same here
3783 DOM.overrideStyleProperty(element, 'color', highlightColor);
3784 DOM.overrideStyleProperty(element, 'backgroundColor', highlightBackground);
3785 };
3786
3787 function DefaultInlineEditor () {
3788 var self = this, currentEditableElement = null, activateAncestorNodes, ancestorsEditable = false, makeAncestorsEditable, updateCursorPosition;
3789
3790 // FF doesn't let you delete the text inside the span if the ancestor is another inline element and that is uneditable
3791 // http://htmlhelp.com/reference/html40/inline.html
3792 var ELEMENTS_TO_OVERRIDE = {'a': 'a', 'abbr': 'abbr', 'acronym': 'acronym', 'b': 'b', 'basefont' : 'basefont',
3793 'bdo': 'bdo', 'big' : 'big', 'br': 'br', 'cite': 'cite', 'dfn': 'dfn', 'em': 'em', 'font': 'font', 'i': 'i',
3794 'img': 'img', 'input': 'input', 'kbd': 'kbd', 'label': 'label', 'q': 'q', 's': 's', 'samp': 'samp',
3795 'select': 'select','small': 'small', 'span': 'span', 'strike': 'strike', 'strong': 'strong', 'sub': 'sub',
3796 'sup': 'sup', 'textarea': 'textarea', 'tt': 'tt', 'u': 'u', 'var': 'var'};
3797
3798 this.activate = function activate(element) {
3799 currentEditableElement = element;
3800 DOM.overrideAttribute(currentEditableElement, 'contentEditable', 'true');
3801 };
3802
3803 this.deactivate = function deactivate() {
3804 if (currentEditableElement) {
3805 DOM.restoreAttribute(currentEditableElement,'contentEditable');
3806 }
3807 };
3808
3809 this.startEditing = function startEditing(event) {
3810 if (currentEditableElement && event.rangeOffset) {
3811 // FF specific
3812 ancestorsEditable = true;
3813 makeAncestorsEditable(currentEditableElement.parentNode, true);
3814 updateCursorPosition(event);
3815 }
3816 };
3817
3818 this.stopEditing = function stopEditing() {
3819 if (currentEditableElement && ancestorsEditable) {
3820 ancestorsEditable = false;
3821 makeAncestorsEditable(currentEditableElement.parentNode, false);
3822 }
3823 self.deactivate();
3824 currentEditableElement = null;
3825 };
3826
3827 this.focus = function focus() {
3828 window.getSelection().removeAllRanges();
3829 };
3830
3831 updateCursorPosition = function updateCursorPosition(event) {
3832 var selection = window.getSelection();
3833 var range = selection.getRangeAt(0);
3834
3835 if (selection.anchorOffset == selection.focusOffset) {
3836 selection.collapse(currentEditableElement.firstChild, event.rangeOffset);
3837 } else {
3838 range.setStart(currentEditableElement.firstChild, selection.anchorOffset);
3839 range.setEnd(currentEditableElement.firstChild, selection.focusOffset);
3840 }
3841 };
3842
3843 makeAncestorsEditable = function makeAncestorsEditable(element, editable) {
3844 if (ELEMENTS_TO_OVERRIDE[element.nodeName.toLowerCase()]) {
3845 if (editable) {
3846 DOM.overrideAttribute(element, 'contentEditable', 'true');
3847 } else {
3848 DOM.restoreAttribute(element, 'contentEditable');
3849 }
3850 }
3851 if (element.parentNode) {
3852 makeAncestorsEditable(element.parentNode, editable);
3853 } else {
3854 return;
3855 }
3856 }
3857 };
3858 };
3859 }
3860
3861 /**
3862 * Main coordinator for the html editor's overlay and other functionality.
3863 */
3864 function HtmlPageEditor(editor) {
3865 var self = this, overlayBar, buildDataString, ajaxResultProcessor = new AjaxResultProcessor();
3866
3867 overlayBar = new OverlayBar(this, false);
3868
3869 this.hasChangesPending = function hasChangesPending() {
3870 return editor.getSession().getUndoManager().$undoStack.length > 0;
3871 };
3872
3873 this.show = function show() {
3874 overlayBar.show(false);
3875 overlayBar.message('New page created for editing');
3876 };
3877
3878 // this composition is necessary to avoid circular dependencies
3879 this.showMessage = function showMessage(message) {
3880 overlayBar.message(message);
3881 };
3882
3883 this.commandUndo = function commandUndo() {
3884 if (self.hasChangesPending()) {
3885 editor.undo();
3886 self.showMessage('Change undone');
3887 } else {
3888 self.showMessage('Nothing to undo');
3889 }
3890 };
3891
3892 this.commandPublish = function commandPublish() {
3893 var result;
3894 splashWindow.show('Saving...');
3895 overlayBar.show(false);
3896 result = AJAX.post('/app/page-edit/publish?slug=' + pageSlug + '&uploadSlug=' + uploadSlug + '&keepOriginal=' + keepOriginal,
3897 buildDataString(), function(result) {
3898 ajaxResultProcessor.processPublishedResponse(result);
3899 });
3900
3901 overlayBar.show(true);
3902 };
3903
3904 this.commandSwitchMode = function commandSwitchMode(saveChanges) {
3905 var result;
3906
3907 overlayBar.enableSwitchSave(false);
3908 var successUrlParam = '';
3909 if (successUrl) {
3910 successUrlParam = '&successUrl=' + encodeURIComponent(successUrl);
3911 }
3912 if (saveChanges) {
3913 result = AJAX.post('/app/page-edit/switch-edit-mode?slug=' + pageSlug + '&uploadSlug=' + uploadSlug + successUrlParam, buildDataString());
3914 } else {
3915 window.location.href = 'https://bo.lt/app/page-edit/?slug=' + pageSlug + '&uploadSlug=' + uploadSlug + successUrlParam;
3916 return;
3917 }
3918 ajaxResultProcessor.processSwitchModeResponse(result);
3919
3920 overlayBar.enableSwitchSave(true);
3921 };
3922
3923 buildDataString = function buildDataString() {
3924 return 'htmlContent=' + encodeURIComponent(editor.getSession().getValue());
3925 };
3926
3927 this.activateditor = function activateEditor() {
3928 overlayBar.show(true);
3929 };
3930
3931 this.close = function close() {
3932 //no op for html editor. added to keep the editor interface consistent
3933 };
3934
3935 this.saveAndClose = function saveAndClose() {
3936 //no op for html editor. added to keep the editor interface consistent
3937 };
3938
3939 }
3940 splashWindow = new SplashWindow(pageEditor);
3941 splashWindow.createLabels();
3942 splashWindow.activate();
3943 if (editMode != 'HTML') {
3944 pageEditor = new VisualPageEditor();
3945 pageEditor.show();
3946 }
3947
3948 var activateEditor = function activateEditor() {
3949 if (editMode == 'HTML') {
3950 var editor, htmlMode;
3951 editor = ace.edit("editor");
3952 htmlMode = require("ace/mode/html").Mode;
3953 editor.setTheme("ace/theme/eclipse");
3954 editor.setShowPrintMargin(false);
3955 editor.getSession().setMode(new htmlMode());
3956 editor.getSession().setUseWrapMode(true);
3957 pageEditor = new HtmlPageEditor(editor);
3958 }
3959 pageEditor.activateEditor();
3960 if (splashWindow) {
3961 splashWindow.activate();
3962 }
3963 }
3964 loadingTimerId = setTimeout(activateEditor, 000);
3965 UTIL.addEvent(window, 'load', function() {
3966 clearTimeout(loadingTimerId);
3967 activateEditor();
3968 });
3969
3970}