WMD editor freezes Internet Explorer 7 for 3 seconds on load - internet-explorer-7

I am using the WMD editor's original code (not the Stack Overflow version) since I need multiple of them on the same page and Stack Overflow's version makes heavy use of element IDs internally since they aren't going to be having more than one editor instance per page.
The code runs fine in Firefox 3.5, etc. However, when I run it in Internet Explorer 8 (in Internet Explorer 7 compatibility mode), it freezes the whole browser for about 3 sec. before a new instance shows up. I tried profiling it with Internet Explorer's development tools, and it seems that the getWidth() function on line 520 of the minified version of the code is taking up all the time. However, when I tried to hard-code the return (since it was always returning the same thing), the bottleneck shifted to the getHeight() function.
I am attaching the code I am using to convert it to a jQuery plugin.
jQuery.fn.wmd = function(params) {
function createInstance(container, params) {
/* Make sure WMD has finished loading */
if (!Attacklab || !Attacklab.wmd) {
alert("WMD hasn't finished loading!");
return;
}
var defaultParams = {
width : "600px",
rows : 6,
autogrow : false,
preview : false,
previewDivClassName: "wmd-preview-div"
};
if (typeof(params) == "undefined") {
var params = defaultParams;
}
else {
var params = jQuery.extend({}, defaultParams, params);
}
/* Build the DOM elements */
var textarea = document.createElement("textarea");
textarea.style.width = params.width;
textarea.rows = params.rows;
jQuery(container).append(textarea);
var previewDiv = document.createElement("div");
if (params.preview) {
jQuery(previewDiv).addClass(params.previewDivClassName);
jQuery(container).append(previewDiv);
}
/* Build the preview manager */
var panes = {input:textarea, preview:previewDiv, output:null};
var previewManager = new Attacklab.wmd.previewManager(panes);
/* Build the editor and tell it to refresh the preview after commands */
var editor = new Attacklab.wmd.editor(textarea,previewManager.refresh);
/* Save everything so we can destroy it all later */
var wmdInstance = {ta:textarea, div:previewDiv, ed:editor, pm:previewManager};
var wmdInstanceId = $(container).attr('postID');
wmdInstanceProcs.add(wmdInstanceId, wmdInstance);
if (params.autogrow) {
// $(textarea).autogrow();
}
};
if (jQuery(this).html().length > 0) {
var wmdInstanceId = jQuery(this).attr('postID');
var inst = wmdInstanceProcs.get(wmdInstanceId);
jQuery(inst.ta).show();
}
else {
createInstance(this, params);
}
}
jQuery.fn.unwmd = function(params) {
var wmdInstanceId = $(this).attr('postID');
var inst = wmdInstanceProcs.get(wmdInstanceId);
if (inst != null) {
jQuery(inst.ta).hide();
}
}
wmdInstanceProcs = function() {
var wmdInstances = { };
var getProc = function(wmdInstanceId) {
var inst = wmdInstances[wmdInstanceId];
if (typeof(inst) != "undefined") {
return inst;
}
else {
return null;
}
};
var addProc = function(wmdInstanceId, wmdInstance) {
wmdInstances[wmdInstanceId] = wmdInstance;
};
return {
add: addProc,
get: getProc
};
}();
Any help would be much appreciated.

Maybe the freeze in load time is due to IE 7 rendering the JavaScript. Firefox may be faster at rendering and so it makes IE appear to freeze.

Related

How to apply delay in JSZip API to load?

How to apply delay in JSZip API ? I want to zip multiple file. but I want to add some delay between transferring the files from webserver. How to add delay in below code?
This is for browser and deploying binaries inside the device.
$scope.download = function () {
var urls = ["/FILES/AlertLog.txt",
"/FILES/AuditLog.txt",
"/FILES/TotLog.txt",
"/FILES/Historian.csv",
"/FILES/History2.csv",
"/FILES/Factory.cfg",
"/FILES/SLog.txt",
"/FILES/se.dump",
"/FILES/AssertLog.txt",
"/FILES/History2.csv",
"/FILES/History3.csv",
"/FILES/History4.csv"
];
compress_files(urls);
}
function compress_files(urls) {
var zip = new JSZip();
var deferreds = [];
for (var i = 0; i < urls.length; i++) {
$timeout(function(){ deferreds.push(addToZip(zip, urls[i], i));
},200);// issue to deferreds variable =>undefined
$.when.apply(window, deferreds).done(generateZip);
}
function addToZip(zip, url, i) {
var deferred = $.Deferred();
JSZipUtils.getBinaryContent(url, function (err, data) {
if(err) {
deferred.resolve(zip);
}
else {
var arr=url.split("/");
zip.file(arr[2], data, { binary: true });
deferred.resolve(zip);
}
});
return deferred;
}
add some delay of milliseconds between transferring the files from the webserver.
I am trying to download the individual file by giving some delay. It fixed my problem
function downloadAll(files){
if(files.length == 0) return;
file = files.pop();
var theAnchor = $('<a />')
.attr('href', file[1])
.attr('download',file[0])
// Firefox does not fires click if the link is outside
// the DOM
.appendTo('body');
theAnchor[0].click();
theAnchor.remove();
downloadAll(files); }
function downloadAll(files){
if(files.length == 0) return;
file = files.pop();
var theAnchor = $('<a />')
.attr('href', file[1])
.attr('download',file[0])
// Firefox does not fires click if the link is outside
// the DOM
.appendTo('body');
theAnchor[0].click();
theAnchor.remove();
downloadAll(files);
}
$('a.download-csv').on('click', function(){
downloadAll([
['file1.csv', 'data:text/csv;charset=utf8,'+
encodeURIComponent('my,csv,file\and,so,on')],
['file2.txt', 'data:text/plain;charset=utf8,'+
encodeURIComponent('this script can do what I need.')],
['file3.js', 'data:text/javascriptcharset=utf8,'+
encodeURIComponent('alert(\'You can donate me your house if you like this script :-) \')')]
]);
});

Redactor editor text format issues with Chrome version 58

We're using Redactor(https://imperavi.com/redactor/) version 10.1.1 and not migrated to Redactor II due to lot of dependencies on project.
Recently We're facing a very weird issue with Chrome version 58. Issues are:
-- Not able to format bold, italic, underline, sup, sub etc. for selected text
Kindly let us know is there any fix for this. Any kind of help would be greatly appreciated.
Update as per accepted work around solution:
// Provided solution is tested for Redactor version 10.1.1
createMarkers: function()
{
this.selection.get();
var node1 = this.selection.getMarker(1);
this.selection.setMarker(this.range, node1, true);
if (this.range.collapsed === false) {
var node2 = this.selection.getMarker(2);
this.selection.setMarker(this.range, node2, false);
// Fix for Chrome58 Issues
if (this.utils.browser('chrome')) {
this.caret.set(node1, 0, node2, 0);
}
// End Chrome58 Issues
}
this.savedSel = this.$editor.html();
},
I think I may have found the solution: It seems that Chrome 58 (sometimes) resets the selection when we call Range.insertNode.
The solution I suggest is to restore the selection when the Redactor adds the selection markers: In the createMarkers function, right after setting the node2 marker, you can add this function call:
this.caret.set(node1, 0, node2, 0);
Here's the solution that should fix Redactor for concrete5 (but it should also work for other projects too).
instead of this in 10.2.5 version
Overall you can do like that:
rewrite setMarker function:
setMarker: function (range, node, type) {
var nclone = window.getSelection().getRangeAt(0).cloneRange();
range = range.cloneRange();
try {
var selection = window.getSelection();
range.collapse(type);
range.insertNode(node);
selection.removeAllRanges();
selection.addRange(nclone);
}
catch (e)
{
this.focus.setStart();
}
},
or add fix in createMarkers function:
// Provided solution is tested for Redactor version 10.1.1
createMarkers: function()
{
this.selection.get();
var node1 = this.selection.getMarker(1);
this.selection.setMarker(this.range, node1, true);
if (this.range.collapsed === false)
{
var node2 = this.selection.getMarker(2);
this.selection.setMarker(this.range, node2, false);
// Fix for Chrome58 Issues
if (this.utils.browser('chrome')) {
this.caret.set(node1, 0, node2, 0);
}
// End Chrome58 Issues
}
this.savedSel = this.$editor.html();
},
this is working and tested on chrome 60.
original code is like this in both 10.2.2 and 10.2.5
getNodes: function()
{
this.selection.get();
var startNode = this.selection.getNodesMarker(1);
var endNode = this.selection.getNodesMarker(2);
if (this.range.collapsed === false)
{
if (window.getSelection) {
var sel = window.getSelection();
if (sel.rangeCount > 0) {
var range = sel.getRangeAt(0);
var startPointNode = range.startContainer, startOffset = range.startOffset;
var boundaryRange = range.cloneRange();
boundaryRange.collapse(false);
boundaryRange.insertNode(endNode);
boundaryRange.setStart(startPointNode, startOffset);
boundaryRange.collapse(true);
boundaryRange.insertNode(startNode);
// Reselect the original text
range.setStartAfter(startNode);
range.setEndBefore(endNode);
sel.removeAllRanges();
sel.addRange(range);
}
}
}
else
{
this.selection.setNodesMarker(this.range, startNode, true);
endNode = startNode;
}
how to change it?

Extjs - drag drop restriction

How do I restrict the drag operation not exceeding certain boundary. Is there any config in extjs (version 3), I saw that, Ext.dd.DragZone class is used. But Im not sure what is the usability. I saw a method dropNotAllowed. Is that the method, that has to be used? if so, how should I use that? Please provide some examples.
Im looking for something similar to (jquery UI's draggable containment property)
http://docs.sencha.com/extjs/3.4.0/#!/api/Ext.dd.DragZone-cfg-dropNotAllowed
I tried using the set X and Y constraints, but it did not work-out:
abc.prototype.initDrag = function(v) {
v.dragZoneobj = new Ext.dd.DragZone(v.getEl(), {
getDragData : function(e) {
var sourceEl = e.getTarget(v.itemSelector, 10);
// sourceEl.setXConstraint( 0, 10 );
var t = e.getTarget();
var rowIndex = abc.grid.getView().findRowIndex(t);
var columnIndex = abc.grid.getView().findCellIndex(t);
if ((rowIndex !== false) && (columnIndex !== false)) {
if (sourceEl) {
abc.isDragged = true;
abc.scriptGrid.isDraggableForObject = false;
abc.scriptGrid.dragRowIndex = false;
d = sourceEl.cloneNode(true);
d.id = Ext.id();
d.textContent = sourceEl.innerHTML;
// d.setXConstraint( 0, 10 );
// d.setYConstraint( 0, 10 );
return {
ddel : d,
sourceEl : d,
sourceStore : v.store
}
}
}
},
getRepairXY : function() {
return this.dragData.repairXY;
},
});
}
Both are commented in the above code. The above code is initiated when the panel is rendered.
edit:
How these setX and setYcontraints have to be used?
By default, the element can be dragged any place on the screen. In the doc there are two methods setXConstraint( iLeft, iRight, iTickSize) and setYConstraint( iUp, iDown, iTickSize )
These two methods is used to set to limit the vertical travel and horizental travel of the element.

Breeze 1-m-1 in HotTowel Angular with local storage

I've had a requirement recently to implement a UI for managing a many-many relationship. Ward Bell kindly provided this plunker showing how to implement using 1-m-1 with Angular and Breeze.
My app's design is based largely (especially the datacontext and the local storage) is based largely on John Papa's recent Pluralsight courses.
In my app, BusUnit = Hero and Dimension = Power (in reference to Ward's example.
Everything seems to be working well when I force the app to fetch data from the server, in that my updates to a business unit's dimensions reflect correctly. The problem I'm facing now is when I navigate away from the page and back again (which gets data from local storage). In this case:
if I previously added a new dimension to a business unit, everything is ok, but
if i previously marked a business unit's dimension for deletion and the save, the dimension still appears for the business unit in question.
this is the controller code that initially gets business units and their dimensions:
function getdboardStructure() {
var busUnitsPromise = datacontextSvc.busUnits.getByDboardConfigId(vm.dboardConfig.id);
var dimensionsPromise = datacontextSvc.dimensions.getByDboardConfigId(vm.dboardConfig.id);
$q.all([busUnitsPromise, dimensionsPromise])
.then(function (values) {
vm.busUnits = values[0];
vm.dims = values[1];
createBusUnitVms();
//vm.currentBusUnitVm = vm.busUnitVms[0]; // not required as using accordion instead of drop-down
vm.hasChanges = false;
});
}
this is the code in my controller that prepares for the save:
function applyBusUnitDimensionSelections(busUnitVm) {
var busUnit = busUnitVm.busUnit;
var mapVms = busUnitVm.dimensionMapVms;
var dimensionHash = createBusUnitDimensionHash(busUnit);
mapVms.forEach(function (mapVm) {
var map = dimensionHash[mapVm.dimension.id];
if (mapVm.selected) {
if (!map) {
datacontextSvc.busUnits.addBusUnitDimension(busUnit, mapVm.dimension)
.then(function () {
});
}
} else {
if (map) {
datacontextSvc.markDeleted(map);
}
}
});
}
this is the code in my controller that executes the save:
function save() {
if (!canSave()) {
return $q.when(null);
}
vm.isSaving = true;
vm.busUnitVms.forEach(applyBusUnitDimensionSelections);
return datacontextSvc.save().then(function (saveResult) {
vm.isSaving = false;
trapSavedDboardConfigId(saveResult); // not relevant to use case
}, function (error) {
vm.isSaving = false;
});
}
this is the code in my repository that add a new busUnitDimension entity:
function addBusUnitDimension(busUnit, dimension) {
var newBusUnitDimension = this.em.createEntity(busUnitDimension);
newBusUnitDimension.busUnitId = busUnit.id;
newBusUnitDimension.dimensionId = dimension.id;
return this.$q.when(newBusUnitDimension);
}
this is my datacontext code for marking an item deleted:
function markDeleted(entity) {
return entity.entityAspect.setDeleted();
}
and finally this is the repository code to get business units and their join table entities:
function getByDboardConfigId(dboardConfigId, forceRefresh) {
var self = this;
var predicate = pred.create('dboardConfigId', '==', dboardConfigId);
var busUnits;
if (self.zStorage.areItemsLoaded('busUnits') && !forceRefresh) {
busUnits = self._getAllLocal(entityName, orderBy, predicate);
return self.$q.when(busUnits);
}
return eq.from('BusUnits')
.expand('BusUnitDimensions')
.where(predicate)
.orderBy(orderBy)
.using(self.em).execute()
.to$q(succeeded, self._failed);
function succeeded(data) {
busUnits = data.results;
self.zStorage.areItemsLoaded('busUnits', true);
self.zStorage.save();
//self.logSuccess('Retrieved ' + busUnits.length + ' business units from server', busUnits.length, true);
return busUnits;
}
}
My departure from John's course examples is that I'm using expand in the function I use to get Business Units from the server, and my hypothesis is that this has something to do with the fact that breeze is going to the server everytime I refresh the page (without clearing cache) instead, and that this also has something to do with the error i'm receiving if I navigate away and then back to the page.
Can anyone offer and suggestions?
Appreciate this was a long time ago and you have probably solved it or moved on but I came up against the same problem recently that took me ages to resolve.
The answer I found is that you have to edit JP's angular.breeze.storagewip.js file.
I contains the names of the entities hard-coded into the file and you will need to change these to match your own entities.
There are two functions where you need to do this, examples below show the changes with the four entities I am using:
function zStorageCore($rootScope, zStorageConfig) {
var storeConfig = zStorageConfig.config;
var storeMeta = {
breezeVersion: breeze.version,
appVersion: storeConfig.version,
isLoaded: {
elementAssets : false,
surveyors : false,
elements : false,
assets : false
}
};
and...
function checkStoreImportVersionAndParseData(importedData) {
if (!importedData) {
return importedData;
}
try {
var data = JSON.parse(importedData);
var importMeta = data[0];
if (importMeta.breezeVersion === storeMeta.breezeVersion &&
importMeta.appVersion === storeMeta.appVersion) {
if (importMeta.isLoaded) {
storeMeta.isLoaded.assets = storeMeta.isLoaded.assets || importMeta.isLoaded.assets;
storeMeta.isLoaded.elements = storeMeta.isLoaded.elements || importMeta.isLoaded.elements;
storeMeta.isLoaded.surveyors = storeMeta.isLoaded.surveyors || importMeta.isLoaded.surveyors;
storeMeta.isLoaded.elementAssets = storeMeta.isLoaded.elementAssets || importMeta.isLoaded.elementAssets;
}
return data[1];
} else {
_broadcast(storeConfig.events.error,
'Did not load from storage because mismatched versions',
{ current: storeMeta, storage: importMeta });
}
} catch (ex) {
_broadcast(storeConfig.events.error, 'Exception during load from storage: ' + ex.message, ex);
}
return null; // failed
}
I solved this by comparing JP's Style Guide course files with his SPA/Angular/Breeze course.

Userscript breaking pages outside of domain

Even though I have my userscript restricted to one domain, any site I visit that uses Jquery experiences all kinds of nasty issues when my script is active. Checking the error console in chrome reveals an identical error on all sites:
"Uncaught TypeError: Property '$' of object [object Window]"
What's causing this? My objective is to get my userscript running in noconflict mode on a site that uses both jquery and prototype. I didn't make the code above var = myFunction, so I don't know what about it is causing the problem I'm running into. Any suggestions?
// ==UserScript==
// #name Restore Dashboard Tags
// #namespace http://userstyles.org
// #description This script restores a user's tracked tag list to the sidebar on tumblr
// #author
// #homepage
// #history 1.0 first version
// #include http://www.tumblr.com/*
// #match http://www.tumblr.com/*
// ==/UserScript==
var jQuery, $ = null;
function addJQuery(callback) {
var p = null;
if(window.opera || window.navigator.vendor.match(/Google/)) {
var div = document.createElement("div");
div.setAttribute("onclick", "return window;");
p = div.onclick();
}
else {
p = Window;
}
jQuery = $ = p.jQuery.noConflict();
callback();
}
var myFunction = function() {
jQuery('div#right_column ul:first-child').after('<ul class="controls_section" id="tracked_tags"></ul>');
jQuery('div.tracked_tags a').each(function (i) {
var tagID = jQuery(this).attr("id");
var tagIDNumber = tagID.replace('tag_','');
var tagName = jQuery(this).attr("href");
var tagNameClean = tagName.replace('/tagged/','');
var tagContent ='';
tagContent += '<li><a href="'+tagName+'" id="'+tagID+'" class="tag">';
tagContent += '<div class="hide_overflow">'+tagNameClean+'</div>';
tagContent += '<span id="tag_unread_'+tagIDNumber+'" class="count" style=""></span></a></li>';
jQuery(tagContent).appendTo('div#right_column ul#tracked_tags');
});
};
var NewPosts = function(){
jQuery('div.tracked_tags > div').each(function (i) {
var thisIndex = jQuery(this).index();
if (jQuery(this).find('small').length){
var postCount = jQuery(this).find('small').text();
jQuery('div#right_column ul#tracked_tags li:eq('+thisIndex+')').find('.count').html(postCount.replace("new posts", "") );
}
});
setTimeout(NewPosts,30000);
}
addJQuery(myFunction);
addJQuery(NewPosts);
The problem has been solved! Someone on another site IDed the culprit as jQuery = $ = p.jQuery.noConflict();; since I wasn't loading my own copy of Jquery I didn't need noConflict, and its usage was hiding Jquery from the rest of the page.

Resources