Get the html node for this element

@param \DOMElement $node
@param \AppShed\Remote\XML\DOMDocument $xml
@param \AppShed\Remote\HTML\Settings $settings
320018
protected function getHTMLNodeInner($node, $xml, $settings)
    {
        $node->setAttribute('data-no-glow', 'no-glow');
        $node->appendChild($inner = $xml->createElement('div', 'item-icon-inner'));
        $inner->appendChild(
            $icon = $xml->createElement('div', 'app-icon' . (empty($this->innerClass) ? '' : ' ' . $this->innerClass))
        );
        $icon->appendChild(
            $xml->createElement(
                'div',
                [
                    'class' => 'image',
                    'style' => $this->icon ? 'background-image:url(\'' . $this->icon->getUrl() . '\')' : ''
                ]
            )
        );
        $icon->appendChild($xml->createElement('div', ['class' => 'background']));
        $this->applyLinkToNode($xml, $icon, $settings);
        $inner->appendChild($xml->createElement('div', ['class' => 'title', 'text' => $this->title]));
    }
1361393
public function apply( \DOMText $textnode, Settings $settings, $is_title = false ) {
		if ( empty( $settings['dashSpacing'] ) ) {
			return;
		}

		// Various special characters and regular expressions.
		$s = $settings->dash_style();

		if ( $s != $this->cached_dash_style ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison -- object value comparison.
			$this->update_dash_spacing_regex( $s->parenthetical_dash(), $s->parenthetical_space(), $s->interval_dash(), $s->interval_space() );
			$this->cached_dash_style = $s;
		}

		// Cache $textnode->data for this fix.
		$node_data = $textnode->data;

		$node_data = \preg_replace( self::EM_DASH_SPACING,             $this->em_dash_replacement,            $node_data );
		$node_data = \preg_replace( $this->parenthetical_dash_spacing, $this->parenthetical_dash_replacement, $node_data );
		$node_data = \preg_replace( $this->interval_dash_spacing,      $this->interval_dash_replacement,      $node_data );

		// Restore textnode content.
		$textnode->data = $node_data;
	}
376313
public static function createDocumentFromNode(\DOMNode $node, $docOptions = 0)
    {
        $xmldoc = self::createXmlDocument($docOptions);
        XmlUtil::$xmlNsPrefix[spl_object_hash($xmldoc)] = array();
        $root = $xmldoc->importNode($node, true);
        $xmldoc->appendChild($root);
        return $xmldoc;
    }
1097043
protected function getHTMLNodeInner($node, $xml, $settings)
    {
        if (!empty($this->title)) {
            $node->appendChild($xml->createElement('div', ['class' => 'title', 'text' => $this->title]));
        }

        $node->appendChild(
            $inner = $xml->createElement(
                'div',
                'selected-container' . (empty($this->title) ? ' no-title' : '')
            )
        );

        $inner->appendChild(
            $select = $xml->createElement(
                'select',
                [
                    'name' => $this->variableName,
                    'data-variable' => $this->variableName,
                    'data-save-value' => $this->save
                ]
            )
        );

        foreach ($this->options as $option) {
            $optionNode = $xml->createElement('option', ['value' => $option['value'], 'text' => $option['name']]);
            $select->appendChild($optionNode);
            if ($option['value'] == $this->value) {
                $optionNode->setAttribute('selected', 'selected');
            }
        }
    }
1239458
protected function getHTMLNodeInner($node, $xml, $settings)
    {
        $css = new CSSDocument();
        $idSelector = $css->getIdSelector($this->getIdType() . $settings->getPrefix() . $this->getId());
        if ($this->customCSS) {
            $css->addCSSText($this->customCSS, $idSelector);
        }
        $this->getCSS($css, $settings);
        if ($this->splash) {
            $this->splash->toCSS($css, $idSelector . $css->getClassSelector('splash'));
        }

        if ($this->name) {
            $node->setAttribute('data-name', $this->name);
        }

        if ($this->description) {
            $node->setAttribute('data-description', $this->description);
        }

        if ($this->flag) {
            $node->setAttribute('data-flag', $this->flag);
        }

        if ($this->previewUrl) {
            $node->setAttribute('data-preview-url', $this->previewUrl);
        }

        if ($this->webviewUrl) {
            $node->setAttribute('data-webview-url', $this->webviewUrl);
        }

        if ($this->disableIos7) {
            $node->setAttribute('data-disable-ios7', 'data-disable-ios7');
        }

        if ($this->disableMasking) {
            $node->setAttribute('data-disable-masking', 'data-disable-masking');
        }

        if ($this->icon) {
            $node->setAttribute('data-icon', $this->icon->getUrl());
            $idSelector = $css->getIdSelector($this->getIdType() . $settings->getPrefix() . $this->getId());
            $css->addRule(
                [".android .phone-navigator $idSelector.app .app-navigator .screen .header .back"],
                'background-image',
                $css->getURLValue($this->icon->getUrl())
            );
            $css->addRule(
                [".blackberry .phone-navigator $idSelector.app .app-navigator .screen .header"],
                'background-image',
                $css->getURLValue($this->icon->getUrl())
            );
        }

        if ($settings->getFetchUrl()) {
            $node->setAttribute('data-fetch-url', $settings->getFetchUrl());
        }

        $node->appendChild($navigator = $xml->createElement('div', 'app-navigator'));
        $navigator->appendChild($navinner = $xml->createElement('div', 'app-navigator-inner'));
        $navinner->appendChild($xml->createElement('div', 'app-navigator-inner-sides'));
        $navinner->appendChild($xml->createElement('div', 'app-navigator-inner-sides'));

        if ($this->ads) {
            $xml->addClass($navigator, 'ads');
            $node->appendChild($xml->createElement('div', 'ad-holder'));
        }

        $node->appendChild(($tabbarOuter = $xml->createElement('div', 'tab-bar')));
        $tabbarOuter->appendChild(($tabbar = $xml->createElement('table')));
        $tabbar->appendChild(($tabbarinner = $xml->createElement('tr', 'tar-bar-inner')));

        foreach ($this->children as $tab) {
            $tabbarinner->appendChild($tab->getHTMLNode($xml, $settings));
            $tab->getCSS($css, $settings);
        }

        $settings->addApp(
            $this->getId(),
            $xml->saveXML($node),
            $css,
            $this->splash ? "<style scoped>" . $css->toSplashString(
                ) . "</style><div class=\"splash\" id=\"app" . $this->getId() . "\"></div>" : null,
            $this->updated === true ? new \DateTime() : $this->updated,
            ['login' => null, 'register' => null],
            $this->js
        );
    }
400598
public function saveXML(\DOMNode $node = null, $options = null)
    {
        $xml = parent::saveXML($node, $options);
        $xml = $this->fixEntities($xml);
        return $xml;
    }
142943
public function addNode($NodeID, array $Settings = [])
    {
        /* if the node already exists, ignore */
        if (isset($this->Data[$NodeID])) {
            return 0;
        }

        $Name = isset($Settings["Name"]) ? $Settings["Name"] : "Node " . $NodeID;
        $Connections = isset($Settings["Connections"]) ? $Settings["Connections"] : null;

        $R = isset($Settings["R"]) ? $Settings["R"] : $this->Default["R"];
        $G = isset($Settings["G"]) ? $Settings["G"] : $this->Default["G"];
        $B = isset($Settings["B"]) ? $Settings["B"] : $this->Default["B"];
        $Alpha = isset($Settings["Alpha"]) ? $Settings["Alpha"] : $this->Default["Alpha"];
        $BorderR = isset($Settings["BorderR"]) ? $Settings["BorderR"] : $this->Default["BorderR"];
        $BorderG = isset($Settings["BorderG"]) ? $Settings["BorderG"] : $this->Default["BorderG"];
        $BorderB = isset($Settings["BorderB"]) ? $Settings["BorderB"] : $this->Default["BorderB"];
        $BorderAlpha = isset($Settings["BorderAlpha"]) ? $Settings["BorderAlpha"] : $this->Default["BorderAlpha"];
        $Surrounding = isset($Settings["Surrounding"]) ? $Settings["Surrounding"] : $this->Default["Surrounding"];
        $BackgroundR = isset($Settings["BackgroundR"]) ? $Settings["BackgroundR"] : $this->Default["BackgroundR"];
        $BackgroundG = isset($Settings["BackgroundG"]) ? $Settings["BackgroundG"] : $this->Default["BackgroundG"];
        $BackgroundB = isset($Settings["BackgroundB"]) ? $Settings["BackgroundB"] : $this->Default["BackgroundB"];
        $BackgroundAlpha = isset($Settings["BackgroundAlpha"])
            ? $Settings["BackgroundAlpha"] : $this->Default["BackgroundAlpha"]
        ;
        $Force = isset($Settings["Force"]) ? $Settings["Force"] : $this->Default["Force"];
        $NodeType = isset($Settings["NodeType"]) ? $Settings["NodeType"] : $this->Default["NodeType"];
        $Size = isset($Settings["Size"]) ? $Settings["Size"] : $this->Default["Size"];
        $Shape = isset($Settings["Shape"]) ? $Settings["Shape"] : $this->Default["Shape"];
        $FreeZone = isset($Settings["FreeZone"]) ? $Settings["FreeZone"] : $this->Default["FreeZone"];

        if ($Surrounding != null) {
            $BorderR = $R + $Surrounding;
            $BorderG = $G + $Surrounding;
            $BorderB = $B + $Surrounding;
        }

        $this->Data[$NodeID]["R"] = $R;
        $this->Data[$NodeID]["G"] = $G;
        $this->Data[$NodeID]["B"] = $B;
        $this->Data[$NodeID]["Alpha"] = $Alpha;
        $this->Data[$NodeID]["BorderR"] = $BorderR;
        $this->Data[$NodeID]["BorderG"] = $BorderG;
        $this->Data[$NodeID]["BorderB"] = $BorderB;
        $this->Data[$NodeID]["BorderAlpha"] = $BorderAlpha;
        $this->Data[$NodeID]["BackgroundR"] = $BackgroundR;
        $this->Data[$NodeID]["BackgroundG"] = $BackgroundG;
        $this->Data[$NodeID]["BackgroundB"] = $BackgroundB;
        $this->Data[$NodeID]["BackgroundAlpha"] = $BackgroundAlpha;
        $this->Data[$NodeID]["Name"] = $Name;
        $this->Data[$NodeID]["Force"] = $Force;
        $this->Data[$NodeID]["Type"] = $NodeType;
        $this->Data[$NodeID]["Size"] = $Size;
        $this->Data[$NodeID]["Shape"] = $Shape;
        $this->Data[$NodeID]["FreeZone"] = $FreeZone;
        if ($Connections != null) {
            if (is_array($Connections)) {
                foreach ($Connections as $Key => $Value) {
                    $this->Data[$NodeID]["Connections"][] = $Value;
                }
            } else {
                $this->Data[$NodeID]["Connections"][] = $Connections;
            }
        }
    }
1170332
private function getValue(\DOMElement $node)
    {
        $value = $node->nodeValue;

        if ('boolean' === $type = $node->getAttribute('type')) {
            return 'true' === $value;
        }

        settype($value, $type);

        return $value;
    }
286482
private static function convertNode(XMLElement $element, DOMNode $node)
    {
        if ($node->hasAttributes()) {
            foreach ($node->attributes as $name => $attrEl) {
                $element->setAttribute($name, General::sanitize($attrEl->value));
            }
        }

        if ($node->hasChildNodes()) {
            foreach ($node->childNodes as $childNode) {
                if ($childNode instanceof DOMCdataSection) {
                    $element->setValue(General::wrapInCDATA($childNode->data));
                } elseif ($childNode instanceof DOMText) {
                    if ($childNode->isWhitespaceInElementContent() === false) {
                        $element->setValue(General::sanitize($childNode->data));
                    }
                } elseif ($childNode instanceof DOMElement) {
                    self::convert($element, $childNode);
                }
            }
        }
    }
373134
public function apply( \DOMText $textnode, Settings $settings, $is_title = false ) {
		if ( ! DOM::has_class( $textnode, $this->classes_to_avoid ) ) {
			$this->apply_internal( $textnode, $settings, $is_title );
		}
	}
1210048
public function apply( \DOMText $textnode, Settings $settings, $is_title = false ) {
		if ( empty( $settings['frenchPunctuationSpacing'] ) ) {
			return;
		}

		// Use the proper non-breaking narrow space.
		$no_break_narrow_space = $settings->no_break_narrow_space();

		// Need to get context of adjacent characters outside adjacent inline tags or HTML comment
		// if we have adjacent characters add them to the text.
		$previous_character = DOM::get_prev_chr( $textnode );
		$next_character     = DOM::get_next_chr( $textnode );
		$node_data          = "{$previous_character}{$textnode->data}"; // $next_character is not included on purpose.
		$f                  = Strings::functions( "{$node_data}{$next_character}" ); // Include $next_character for determining encodiing.

		$node_data = \preg_replace( self::INSERT_SPACE_BEFORE_CLOSING_QUOTE, '$1' . $no_break_narrow_space . '$3$4', $node_data );
		$node_data = \preg_replace( self::INSERT_NARROW_SPACE,               '$1' . $no_break_narrow_space . '$3$4', $node_data );
		$node_data = \preg_replace( self::INSERT_FULL_SPACE,                 '$1' . U::NO_BREAK_SPACE . '$3$4',      $node_data );

		// The next rule depends on the following characters as well.
		$node_data = \preg_replace( self::INSERT_SPACE_AFTER_OPENING_QUOTE,  '$1$2' . $no_break_narrow_space . '$4', "{$node_data}{$next_character}" );

		// If we have adjacent characters remove them from the text.
		$textnode->data = self::remove_adjacent_characters( $node_data, $f['strlen'], $f['substr'], $f['strlen']( $previous_character ), $f['strlen']( $next_character ) );
	}
1372728
protected function getHTMLNodeInner($node, $xml, $settings)
    {
        if (!empty($this->title)) {
            $node->appendChild($xml->createElement('div', ['class' => 'title', 'text' => $this->title]));
        }
        $node->appendChild(
            $inner = $xml->createElement('div', 'textbox-container' . (empty($this->title) ? ' no-title' : ''))
        );
        $inner->appendChild(
            $xml->createElement(
                'input',
                [
                    'class' => 'textbox' . ($this->localSearch ? ' localsearch' : ''),
                    'type' => static::INPUT_TYPE,
                    'name' => $this->variableName,
                    'value' => $this->value,
                    'placeholder' => $this->placeHolder,
                    'data-variable' => $this->variableName,
                    'data-save-value' => $this->save,
                    'data-autocomplete-url' => $this->autocomplete,
                    'data-autocomplete-variable' => $this->autoCompleteVariable ? $this->autoCompleteVariable : $this->variableName
                ]
            )
        );
    }
468112
public function apply( \DOMText $textnode, Settings $settings, $is_title = false ) {
		if ( empty( $settings['smartMarks'] ) ) {
			return;
		}

		// Cache textnode content.
		$node_data = $textnode->data;

		// Escape usage of "501(c)(1...29)" (US non-profit).
		$node_data = \preg_replace( self::ESCAPE_501C, '$1' . RE::ESCAPE_MARKER . '$2' . RE::ESCAPE_MARKER . '$3', $node_data );

		// Replace marks.
		$node_data = \str_replace( $this->marks, $this->replacements, $node_data );

		// Un-escape escaped sequences & resetore textnode content.
		$textnode->data = \str_replace( RE::ESCAPE_MARKER, '', $node_data );
	}
98954
protected function getHTMLNodeBase($node, $xml, $settings, $css, &$javascripts)
    {
        parent::getHTMLNodeBase($node, $xml, $settings, $css, $javascripts);
        $node->setAttribute('data-zoom', $this->zoom);
    }
497040
protected function getHTMLNodeInner($node, $xml, $settings)
    {
        $node->setAttribute('data-capturetype', $this->type);
        $node->setAttribute('data-name', $this->variableName);
        $node->setAttribute('data-save-value', $this->save);

        $node->appendChild($on = $xml->createElement('div', 'on'));

        $on->appendChild($xml->createElement('div', 'image'));
        $on->appendChild($xml->createElement('div', ['class' => 'title', 'text' => $this->title]));
        $on->appendChild($xml->createElement('div', ['class' => 'text', 'text' => $this->subtitle]));

        $on->appendChild($xml->createElement('button', ['class' => 'capture', 'text' => 'Capture']));
        $on->appendChild($xml->createElement('button', ['class' => 'choose', 'text' => 'Choose']));

        $node->appendChild($off = $xml->createElement('div', 'off'));

        $off->appendChild(
            $xml->createElement('div', ['class' => 'title', 'text' => ucfirst($this->type) . ' Capture'])
        );
        $off->appendChild(
            $xml->createElement(
                'div',
                [
                    'class' => 'text',
                    'text' => "You need to install this app via the store to use {$this->type} capture"
                ]
            )
        );
    }
915872
protected function applyLinkToNode(DOMDocument $xml, \DOMElement $node, Settings $settings)
    {
        switch ($this->linktype) {
            case LinkConstants::LINK_JAVASCRIPT:
                $node->setAttribute('data-linktype', LinkConstants::LINK_JAVASCRIPT);
                $node->setAttribute('data-href', $this->getIdType() . $settings->getPrefix() . $this->getId());
                break;
            case LinkConstants::LINK_APP:
                $node->setAttribute('data-linktype', LinkConstants::LINK_APP);
                if ($this->screen instanceof App) {
                    $this->app->getHTMLNode($xml, $settings);
                    $node->setAttribute('data-href', $settings->getPrefix() . $this->app->getId());
                } else {
                    $node->setAttribute('data-href', $settings->getPrefix() . $this->app);
                }
                break;
            case LinkConstants::LINK_SCREEN:
                $node->setAttribute('data-linktype', LinkConstants::LINK_SCREEN);
                if ($this->screen instanceof Screen) {
                    $this->screen->getHTMLNode($xml, $settings);
                    $node->setAttribute('data-href', $settings->getPrefix() . $this->screen->getId());
                } elseif ($this->appshedLink) {
                    $node->setAttribute('data-href', $this->screen);
                    $node->setAttribute('data-appshed', 'appshed');
                } else {
                    $node->setAttribute('data-href', $settings->getPrefix() . $this->screen);
                }
                if (!empty($this->elementId)) {
                    $node->setAttribute('data-element', $this->elementId);
                }
                break;
            case LinkConstants::LINK_TAB:
                $node->setAttribute('data-linktype', LinkConstants::LINK_TAB);
                if ($this->tab instanceof Tab) {
                    $node->setAttribute('data-href', $settings->getPrefix() . $this->tab->getId());
                } elseif ($this->appshedLink) {
                    $node->setAttribute('data-href', $this->tab);
                    $node->setAttribute('data-appshed', 'appshed');
                } else {
                    $node->setAttribute('data-href', $settings->getPrefix() . $this->tab);
                }
                break;
            case LinkConstants::LINK_FILE:
                $node->setAttribute('data-linktype', LinkConstants::LINK_FILE);
                $node->setAttribute('data-href', $this->fileUrl);
                if ($this->fileName) {
                    $node->setAttribute('data-filename', $this->fileName);
                }
                break;
            case LinkConstants::LINK_SOUND:
                $node->setAttribute('data-linktype', LinkConstants::LINK_SOUND);
                $node->setAttribute('data-href', $this->soundUrl);
                if ($this->soundName) {
                    $node->setAttribute('data-filename', $this->soundName);
                }
                break;
            case LinkConstants::LINK_WEB:
                $node->setAttribute('data-linktype', LinkConstants::LINK_WEB);
                $node->setAttribute('data-href', $this->applyVariablesToUrl($this->webUrl));
                $node->setAttribute('data-weblinktype', $this->webType);
                break;
            case LinkConstants::LINK_REMOTE:
                $node->setAttribute('data-linktype', LinkConstants::LINK_REMOTE);
                $node->setAttribute('data-href', $this->applyVariablesToUrl($this->remoteUrl));
                $node->setAttribute('data-direct', 'direct');
                break;
            case LinkConstants::LINK_LOGIN:
                $node->setAttribute('data-linktype', LinkConstants::LINK_LOGIN);
                $node->setAttribute('data-href', $this->loginId);
                break;
            case LinkConstants::LINK_REGISTER:
                $node->setAttribute('data-linktype', LinkConstants::LINK_REGISTER);
                $node->setAttribute('data-href', $this->registerId);
                break;
            case LinkConstants::LINK_YOUTUBE:
                $node->setAttribute('data-linktype', LinkConstants::LINK_YOUTUBE);
                $node->setAttribute('data-href', $this->youTubeUrl);
                break;
            case LinkConstants::LINK_VIMEO:
                $node->setAttribute('data-linktype', LinkConstants::LINK_VIMEO);
                $node->setAttribute('data-href', $this->vimeoUrl);
                break;
            case LinkConstants::LINK_VIDEO:
                $node->setAttribute('data-linktype', LinkConstants::LINK_VIDEO);
                $node->setAttribute('data-href', $this->videoUrl);
                break;
            case LinkConstants::LINK_FACEBOOK:
                $node->setAttribute('data-linktype', LinkConstants::LINK_FACEBOOK);
                $node->setAttribute('data-href', $this->facebookUrl);
                break;
            case LinkConstants::LINK_TWITTER:
                $node->setAttribute('data-linktype', LinkConstants::LINK_TWITTER);
                $node->setAttribute('data-href', $this->twitterScreenName);
                break;
            case LinkConstants::LINK_BBM:
                $node->setAttribute('data-linktype', LinkConstants::LINK_BBM);
                break;
            case LinkConstants::LINK_REFRESH:
                $node->setAttribute('data-linktype', LinkConstants::LINK_REFRESH);
                break;
            case LinkConstants::LINK_EMAIL:
                if ($settings->getEmailPreview()) {
                    $screen = new Screen('Email');
                    $screen->setId('email' . $this->getId());
                    $screen->setEditable(false);
                    $screen->setBack($settings->getCurrentScreen());

                    $screen->addChild(new Input('email_to', 'To', $this->emailTo));
                    $screen->addChild(new Input('email_subject', 'Subject', $this->emailSubject));
                    $screen->addChild(new TextArea('email_body', 'Message', $this->emailBody));

                    $send = new Button('Send');
                    $send->setWebLink(
                        'mailto:{email_to}?subject={email_subject}&body={email_body}',
                        LinkConstants::WEBLINK_EXTERNAL
                    );
                    $screen->addChild($send);
                    $screen->getHTMLNode($xml, $settings);
                    $node->setAttribute('data-linktype', LinkConstants::LINK_SCREEN);
                    $node->setAttribute('data-href', $settings->getPrefix() . $screen->getId());
                } else {
                    $node->setAttribute('data-linktype', LinkConstants::LINK_WEB);
                    $node->setAttribute(
                        'data-href',
                        'mailto:' . $this->emailTo . '?' . http_build_query(
                            [
                                'subject' => $this->emailSubject,
                                'body' => $this->emailBody
                            ]
                        )
                    );
                    $node->setAttribute('data-weblinktype', LinkConstants::WEBLINK_EXTERNAL);
                }
                break;
            case LinkConstants::LINK_PHONE:
                if ($settings->getPhonePreview()) {
                    $screen = new Screen('Phone');
                    $screen->setId('phone' . $this->getId());
                    $screen->setScroll(false);
                    $screen->setEditable(false);
                    $screen->setBack($settings->getCurrentScreen());
                    $screen->addClass('phone-screen');
                    $screen->setHeader(false);
                    $screen->setTabs(false);

                    $top = new LinkElement($this->phoneNumber);
                    $top->addClass('top');
                    $screen->addChild($top);

                    $end = new LinkElement('End');
                    $end->addClass('bottom');
                    $end->setBackLink();
                    $screen->addChild($end);

                    $screen->getHTMLNode($xml, $settings);
                    $node->setAttribute('data-linktype', LinkConstants::LINK_SCREEN);
                    $node->setAttribute('data-href', $settings->getPrefix() . $screen->getId());
                } else {
                    $node->setAttribute('data-linktype', 'web');
                    $node->setAttribute('data-href', 'tel:' . $this->phoneNumber);
                    $node->setAttribute('data-weblinktype', LinkConstants::WEBLINK_CONFIRM);
                    $node->setAttribute('data-confirm-message', 'Click to make a call to ' . $this->phoneNumber);
                    $node->setAttribute('data-okbtn', 'Call');
                }
                break;
            case LinkConstants::LINK_BACK:
                $node->setAttribute('data-linktype', LinkConstants::LINK_BACK);
                if ($this->backScreenId) {
                    $node->setAttribute('data-href', $this->backScreenId);
                }
                break;
            case LinkConstants::LINK_IOT:
                $node->setAttribute('data-linktype', LinkConstants::LINK_IOT);
                $node->setAttribute('data-href', $this->iotPinName);
                $node->setAttribute('data-value', $this->iotValue);
                break;
        }
        if ($node->hasAttribute('data-linktype')) {
            $xml->addClass($node, 'link');
            if ($this->linkArrow === true) {
                $node->appendChild($xml->createElement('div', 'link-arrow'));
            } else {
                if ($this->linkArrow === false) {
                    $xml->addClass($node, 'link-no-arrow');
                }
            }
            $node->setAttribute('x-blackberry-focusable', 'true');
        }
    }
536464
protected function restoreZoneFromXml(DOMElement $node)
    {
        $zoneId = null;
        $zoneIdentifier = null;
        $action = null;
        $blocks = array();
        $attributes = array();

        if ($node->hasAttributes()) {
            foreach ($node->attributes as $attr) {
                switch ($attr->name) {
                    case 'id':
                        // Stored Id has following format : id_<zoneId>, so extract <zoneId>
                        $zoneId = substr(
                            $attr->value,
                            strpos($attr->value, '_') + 1
                        );
                        break;
                    case 'action':
                        $action = $attr->value;
                        break;
                    default:
                        $attributes[$attr->name] = $attr->value;
                }
            }
        }

        foreach ($node->childNodes as $node) {
            if ($node->nodeType !== XML_ELEMENT_NODE) {
                continue;
            }

            switch ($node->nodeName) {
                case 'block':
                    $block = $this->restoreBlockFromXml($node);
                    $blocks[] = $block;
                    break;
                case 'zone_identifier':
                    $zoneIdentifier = $node->nodeValue;
                    break;
                default:
                    $attributes[$node->nodeName] = $node->nodeValue;
            }
        }

        return new Parts\Zone(
            array(
                'id' => $zoneId,
                'identifier' => $zoneIdentifier,
                'attributes' => $attributes,
                'action' => $action,
                'blocks' => $blocks,
            )
        );
    }