git-svn-id: svn://euphorik.ch/pompage@45 02bbb61a-6d21-0410-aba0-cb053bdfd66a
[pompage.git] / doc / webdeveloper / features / display_line_guides.js
diff --git a/doc/webdeveloper/features/display_line_guides.js b/doc/webdeveloper/features/display_line_guides.js
new file mode 100644 (file)
index 0000000..bea24ce
--- /dev/null
@@ -0,0 +1,495 @@
+var webdeveloper_lineGuideSelected = null;
+
+// Adds a horizontal line guide
+function webdeveloper_addHorizontalLineGuide()
+{
+    var contentDocument    = webdeveloper_getContentDocument();
+    var contentWindow      = webdeveloper_getContentWindow();
+    var documentHeight     = contentDocument.height;
+    var lineGuide          = contentDocument.createElement("div");
+    var lineGuidePositions = webdeveloper_getHorizontalLineGuidePositions(contentDocument);
+    var spacing            = contentWindow.pageYOffset + 100;
+
+    lineGuide.style.backgroundColor = webdeveloper_getStringPreference("webdeveloper.line.guides.color");
+    lineGuide.style.top             = 0;
+
+    lineGuide.addEventListener("mousedown", webdeveloper_selectLineGuide, false);
+    lineGuide.addEventListener("mouseout", webdeveloper_mouseoutLineGuide, false);
+    lineGuide.addEventListener("mouseover", webdeveloper_mouseoverLineGuide, false);
+    lineGuide.addEventListener("mouseup", webdeveloper_deselectLineGuide, false);
+
+    webdeveloper_sizeHorizontalLineGuide(lineGuide, contentDocument);
+
+    // While the spacing is less than the document height
+    while(spacing < documentHeight)
+    {
+        // If there is already a line guide at this position
+        if(webdeveloper_contains(lineGuidePositions, spacing + "px"))
+        {
+            spacing += 100;
+        }
+        else
+        {
+            lineGuide.style.top = spacing + "px";
+            break;
+        }
+    }
+
+    lineGuide.setAttribute("class", "webdeveloper-line-guide webdeveloper-horizontal-line-guide");
+    webdeveloper_getDocumentBodyElement(contentDocument).appendChild(lineGuide);
+}
+
+// Adds a vertical line guide
+function webdeveloper_addVerticalLineGuide()
+{
+    var contentDocument    = webdeveloper_getContentDocument();
+    var contentWindow      = webdeveloper_getContentWindow();
+    var documentWidth      = contentDocument.width;
+    var lineGuide          = contentDocument.createElement("div");
+    var lineGuidePositions = webdeveloper_getVerticalLineGuidePositions(contentDocument);
+    var spacing            = contentWindow.pageXOffset + 100;
+
+    lineGuide.style.backgroundColor = webdeveloper_getStringPreference("webdeveloper.line.guides.color");
+    lineGuide.style.left            = 0;
+
+    lineGuide.addEventListener("mousedown", webdeveloper_selectLineGuide, false);
+    lineGuide.addEventListener("mouseout", webdeveloper_mouseoutLineGuide, false);
+    lineGuide.addEventListener("mouseover", webdeveloper_mouseoverLineGuide, false);
+    lineGuide.addEventListener("mouseup", webdeveloper_deselectLineGuide, false);
+
+    webdeveloper_sizeVerticalLineGuide(lineGuide, contentDocument);
+
+    // While the spacing is less than the document width
+    while(spacing < documentWidth)
+    {
+        // If there is already a line guide at this position
+        if(webdeveloper_contains(lineGuidePositions, spacing + "px"))
+        {
+            spacing += 100;
+        }
+        else
+        {
+            lineGuide.style.left = spacing + "px";
+            break;
+        }
+    }
+
+    lineGuide.setAttribute("class", "webdeveloper-line-guide webdeveloper-vertical-line-guide");
+    webdeveloper_getDocumentBodyElement(contentDocument).appendChild(lineGuide);
+}
+
+// Called when a line guide is deselected
+function webdeveloper_deselectLineGuide(event)
+{
+    webdeveloper_lineGuideSelected = null;
+}
+
+// Displays line guides
+function webdeveloper_displayLineGuides(element)
+{
+    // If the page has frames
+    if(webdeveloper_pageHasFrames())
+    {
+        window.openDialog("chrome://webdeveloper/content/message/message.xul", "webdeveloper-message-dialog", "centerscreen,chrome,modal", document.getElementById("webdeveloper-string-bundle").getString("webdeveloper_framesNotSupported"));
+    }
+    else
+    {
+        var checked         = false;
+        var contentDocument = webdeveloper_getContentDocument();
+        var divElement      = null;
+
+        // If the element is set
+        if(element)
+        {
+            checked = element.getAttribute("checked");
+        }
+
+        webdeveloper_configureElement(document.getElementById("webdeveloper-line-guides-toolbar"), "hidden", !checked);
+
+        // If displaying line guides
+        if(checked)
+        {
+            divElement = contentDocument.createElement("div");
+
+            document.getElementById("webdeveloper.line.guides.color").color = webdeveloper_getStringPreference("webdeveloper.line.guides.color");
+
+            webdeveloper_addHorizontalLineGuide();
+            webdeveloper_addVerticalLineGuide();
+
+            divElement.setAttribute("id", "webdeveloper-line-guide-information");
+            webdeveloper_getDocumentBodyElement(contentDocument).appendChild(divElement);
+
+            contentDocument.addEventListener("mousemove", webdeveloper_moveLineGuide, false);
+            window.addEventListener("resize", webdeveloper_resizeLineGuides, false);
+        }
+        else
+        {
+            divElement = contentDocument.getElementById("webdeveloper-line-guide-information");
+
+            webdeveloper_removeElement(divElement);
+            webdeveloper_removeLineGuides(contentDocument);
+
+            // Try to remove the event listener
+            try
+            {
+                contentDocument.removeEventListener("mousemove", webdeveloper_moveLineGuide, false);
+            }
+            catch(exception)
+            {
+                // Do nothing
+            }
+
+            // Try to remove the event listener
+            try
+            {
+                window.removeEventListener("resize", webdeveloper_resizeLineGuides, false);
+            }
+            catch(exception)
+            {
+                // Do nothing
+            }
+
+            webdeveloper_lineGuideSelected = null;
+        }
+
+        webdeveloper_toggleStyleSheet(element, "chrome://webdeveloper/content/stylesheets/display_line_guides.css", "webdeveloper-display-line-guides");
+    }
+}
+
+// Returns an array containing the horizontal line guide positions
+function webdeveloper_getHorizontalLineGuidePositions(contentDocument)
+{
+    return webdeveloper_getLineGuidePositions(contentDocument, true);
+}
+
+// Returns the line guide position nearest to the given line guide position
+function webdeveloper_getLineGuidePosition(contentDocument, horizontal, lineGuidePosition, next)
+{
+    var lineGuidePositions     = webdeveloper_getLineGuidePositions(contentDocument, horizontal);
+    var lineGuidesLength       = lineGuidePositions.length;
+    var otherLineGuidePosition = 0;
+    var position               = 0;
+
+    // Loop through the line guide positions
+    for(var i = 0; i < lineGuidesLength; i++)
+    {
+        otherLineGuidePosition = lineGuidePositions[i];
+        otherLineGuidePosition = otherLineGuidePosition.substring(0, otherLineGuidePosition.length - 2);
+
+        // If looking for the next line guide position, the other line guide position is greater than the line guide position and the other line guide position is greater than the saved position
+        if(next && otherLineGuidePosition > lineGuidePosition && otherLineGuidePosition > position)
+        {
+            position = otherLineGuidePosition;
+        }
+        else if(!next && otherLineGuidePosition < lineGuidePosition && otherLineGuidePosition > position)
+        {
+            position = otherLineGuidePosition;
+        }
+    }
+
+    return position;
+}
+
+// Returns an array containing the line guide positions
+function webdeveloper_getLineGuidePositions(contentDocument, horizontal)
+{
+    var divElement         = null;
+    var divElementClass    = null;
+    var divElements        = contentDocument.getElementsByTagName("div");
+    var divElementsLength  = divElements.length;
+    var lineGuidePositions = new Array();
+
+    // Loop through the div elements
+    for(var i = 0; i < divElementsLength; i++)
+    {
+        divElement = divElements[i];
+
+        // If the div element is set
+        if(divElement)
+        {
+            divElementClass = divElement.getAttribute("class");
+
+            // If the class exists and contains webdeveloper-line-guide
+            if(divElementClass && divElementClass.indexOf("webdeveloper-line-guide") != -1)
+            {
+                // If looking for horizontal line guides and the class contains webdeveloper-horizontal-line-guide
+                if(horizontal && divElementClass.indexOf("webdeveloper-horizontal-line-guide") != -1)
+                {
+                    lineGuidePositions.push(divElement.style.top);
+                }
+                else if(!horizontal && divElementClass.indexOf("webdeveloper-vertical-line-guide") != -1)
+                {
+                    lineGuidePositions.push(divElement.style.left);
+                }
+            }
+        }
+    }
+
+    return lineGuidePositions;
+}
+
+// Returns an array containing the vertical line guide positions
+function webdeveloper_getVerticalLineGuidePositions(contentDocument)
+{
+    return webdeveloper_getLineGuidePositions(contentDocument, false);
+}
+
+// Called when the mouse is not over a line guide
+function webdeveloper_mouseoutLineGuide(event)
+{
+    var element = event.target;
+
+    // If the element is set
+    if(element)
+    {
+        var ownerDocument = element.ownerDocument;
+
+        // If the element has an owner document
+        if(ownerDocument)
+        {
+            var lineGuideInformation = ownerDocument.getElementById("webdeveloper-line-guide-information");
+
+            // If the line guide information is found
+            if(lineGuideInformation)
+            {
+                lineGuideInformation.style.display = "none";
+            }
+        }
+    }
+}
+
+// Called when the mouse is over a line guide
+function webdeveloper_mouseoverLineGuide(event)
+{
+    var element = event.target;
+
+    // If the element is set
+    if(element)
+    {
+        var ownerDocument = element.ownerDocument;
+
+        // If the element has an owner document
+        if(ownerDocument)
+        {
+            var lineGuideInformation = ownerDocument.getElementById("webdeveloper-line-guide-information");
+
+            // If the line guide information is found
+            if(lineGuideInformation)
+            {
+                var headerElement       = ownerDocument.createElement("h1");
+                var horizontalLineGuide = true;
+                var lineGuidePositions  = null;
+                var pElement            = ownerDocument.createElement("p");
+                var position            = 0;
+                var stringBundle        = document.getElementById("webdeveloper-string-bundle");
+                var xPosition           = event.pageX;
+                var yPosition           = event.pageY;
+
+                // If the line guide has a class attribute and it contains webdeveloper-vertical-line-guide
+                if(element.hasAttribute("class") && element.getAttribute("class").indexOf("webdeveloper-vertical-line-guide") != -1)
+                {
+                    horizontalLineGuide = false;
+                }
+
+                // If this is a horizontal line guide
+                if(horizontalLineGuide)
+                {
+                    position = yPosition;
+                }
+                else
+                {
+                    position = xPosition;
+                }
+
+                webdeveloper_removeAllChildElements(lineGuideInformation);
+
+                headerElement.appendChild(ownerDocument.createTextNode(stringBundle.getString("webdeveloper_position") + " = " + position));
+                lineGuideInformation.appendChild(headerElement);
+
+                pElement.appendChild(ownerDocument.createTextNode(stringBundle.getString("webdeveloper_previousLineGuide") + " = " + webdeveloper_getLineGuidePosition(ownerDocument, horizontalLineGuide, position, false)));
+                lineGuideInformation.appendChild(pElement);
+
+                pElement = ownerDocument.createElement("p");
+                pElement.appendChild(ownerDocument.createTextNode(stringBundle.getString("webdeveloper_nextLineGuide") + " = " + webdeveloper_getLineGuidePosition(ownerDocument, horizontalLineGuide, position, true)));
+                lineGuideInformation.appendChild(pElement);
+
+                webdeveloper_adjustElementPosition(lineGuideInformation, xPosition, yPosition, 10);
+
+                // Show the line guide information
+                lineGuideInformation.style.display = "block";
+            }
+        }
+    }
+}
+
+// Called when a line guide is moved
+function webdeveloper_moveLineGuide(event)
+{
+    // If a line guide is selected
+    if(webdeveloper_lineGuideSelected)
+    {
+        // If the line guide has a class attribute and it contains webdeveloper-horizontal-line-guide
+        if(webdeveloper_lineGuideSelected.hasAttribute("class") && webdeveloper_lineGuideSelected.getAttribute("class").indexOf("webdeveloper-horizontal-line-guide") != -1)
+        {
+            webdeveloper_lineGuideSelected.style.top = event.pageY + "px";
+        }
+        else
+        {
+            webdeveloper_lineGuideSelected.style.left = event.pageX + "px";
+        }
+    }
+}
+
+// Remove the line guides from the document
+function webdeveloper_removeLineGuides(ownerDocument)
+{
+    var divElement        = null;
+    var divElements       = ownerDocument.getElementsByTagName("div");
+    var divElementsLength = divElements.length;
+
+    // Loop through the div elements
+    for(var i = 0; i < divElementsLength; i++)
+    {
+        divElement = divElements[i];
+
+        // If the div element is set and the class exists and contains webdeveloper-line-guide
+        if(divElement && divElement.hasAttribute("class") && divElement.getAttribute("class").indexOf("webdeveloper-line-guide") != -1)
+        {
+            webdeveloper_removeElement(divElement);
+            i--;
+        }
+    }
+}
+
+// Resizes the line guides when the window is resized
+function webdeveloper_resizeLineGuides(event)
+{
+    var contentDocument   = webdeveloper_getContentDocument();
+    var divElement        = null;
+    var divElementClass   = null;
+    var divElements       = contentDocument.getElementsByTagName("div");
+    var divElementsLength = divElements.length;
+
+    // Loop through the div elements
+    for(var i = 0; i < divElementsLength; i++)
+    {
+        divElement = divElements[i];
+
+        // If the div element is set
+        if(divElement)
+        {
+            divElementClass = divElement.getAttribute("class");
+
+            // If the class exists and contains webdeveloper-line-guide
+            if(divElementClass && divElementClass.indexOf("webdeveloper-line-guide") != -1)
+            {
+                // If the class contains webdeveloper-horizontal-line-guide
+                if(divElementClass.indexOf("webdeveloper-horizontal-line-guide") != -1)
+                {
+                    webdeveloper_sizeHorizontalLineGuide(divElement, contentDocument);
+                }
+                else
+                {
+                    webdeveloper_sizeVerticalLineGuide(divElement, contentDocument);
+                }
+            }
+        }
+    }
+}
+
+// Called when a line guide is selected
+function webdeveloper_selectLineGuide(event)
+{
+    // If the click was not a right click
+    if(event.button != 2)
+    {
+        var element = event.target;
+
+        // If the element is set
+        if(element)
+        {
+            webdeveloper_lineGuideSelected = element;
+        }
+    }
+}
+
+// Sets the size of a horizontal line guide
+function webdeveloper_sizeHorizontalLineGuide(lineGuide, contentDocument)
+{
+    webdeveloper_sizeLineGuide(lineGuide, contentDocument, true);
+}
+
+// Sets the size of a line guide
+function webdeveloper_sizeLineGuide(lineGuide, contentDocument, horizontal)
+{
+    // If the line guide and page document are set
+    if(lineGuide && contentDocument)
+    {
+        var contentWindow = webdeveloper_getContentWindow();
+
+        // If sizing a horizontal line guide
+        if(horizontal)
+        {
+            var documentWidth = contentDocument.width;
+            var viewportWidth = contentWindow.innerWidth;
+
+            // If the viewport width is greater than the document width
+            if(viewportWidth > documentWidth)
+            {
+                lineGuide.style.width = viewportWidth + "px";
+            }
+            else
+            {
+                lineGuide.style.width = documentWidth + "px";
+            }
+        }
+        else
+        {
+            var documentHeight = contentDocument.height;
+            var viewportHeight = contentWindow.innerHeight;
+
+            // If the viewport height is greater than the document height
+            if(viewportHeight > documentHeight)
+            {
+                lineGuide.style.height = viewportHeight + "px";
+            }
+            else
+            {
+                lineGuide.style.height = documentHeight + "px";
+            }
+        }
+    }
+}
+
+// Sets the size of a vertical line guide
+function webdeveloper_sizeVerticalLineGuide(lineGuide, contentDocument)
+{
+    webdeveloper_sizeLineGuide(lineGuide, contentDocument, false);
+}
+
+// Updates the line guides color
+function webdeveloper_updateLineGuideColor(colorPicker)
+{
+    // If the color picker is set
+    if(colorPicker)
+    {
+        var color             = colorPicker.color;
+        var divElement        = null;
+        var divElements       = webdeveloper_getContentDocument().getElementsByTagName("div");
+        var divElementsLength = divElements.length;
+
+        webdeveloper_setStringPreference("webdeveloper.line.guides.color", color);
+
+        // Loop through the div elements
+        for(var i = 0; i < divElementsLength; i++)
+        {
+            divElement = divElements[i];
+
+            // If the div element is set and the class exists and contains webdeveloper-line-guide
+            if(divElement && divElement.hasAttribute("class") && divElement.getAttribute("class").indexOf("webdeveloper-line-guide") != -1)
+            {
+                divElement.style.backgroundColor = color;
+            }
+        }
+    }
+}