تخطَّ إلى المحتوى

Apache Cordova / PhoneGap دليل مرجعي سريع

Apache Cordova / PhoneGap - Hybrid Mobile App Development

Apache Cordova (المعروف سابقًا باسم PhoneGap) هو إطار تطوير تطبيقات الهاتف المحمول الذي يمكّن المطورين من بناء تطبيقات الهاتف المحمول الأصلية باستخدام HTML، و CSS، و JavaScript. يوفر وصولًا إلى واجهات برمجة التطبيقات الخاصة بالجهاز من خلال إضافات JavaScript.

[No text to translate]

جدول المحتويات

التثبيت

المتطلبات الأساسية

# Install Node.js (version 12 or later)
# Download from nodejs.org

# Verify Node.js installation
node --version
npm --version

# Install Java Development Kit (JDK) 8 or later
# Download from Oracle or use OpenJDK

# Install Android Studio (for Android development)
# Download from developer.android.com

# Install Xcode (for iOS development, macOS only)
# Download from Mac App Store

# Set environment variables
export ANDROID_HOME=$HOME/Library/Android/sdk
export PATH=$PATH:$ANDROID_HOME/tools
export PATH=$PATH:$ANDROID_HOME/platform-tools
```[No specific text provided]

### تثبيت Cordova واجهة سطر الأوامر
```bash
# Install Cordova CLI globally
npm install -g cordova

# Verify installation
cordova --version

# Check requirements for platforms
cordova requirements

# Install platform-specific tools
# For Android
npm install -g gradle

# For iOS (macOS only)
npm install -g ios-deploy
```[No specific text provided]

### واجهة سطر أوامر PhoneGap (بديل)
```bash
# Install PhoneGap CLI (Adobe's distribution)
npm install -g phonegap

# Verify installation
phonegap --version

# PhoneGap Build service (deprecated)
# Use Cordova CLI for new projects
```[No specific text provided]

## البدء

### إنشاء مشروع جديد
```bash
# Create new Cordova project
cordova create MyApp com.example.myapp "My App"

# Navigate to project directory
cd MyApp

# Add platforms
cordova platform add android
cordova platform add ios

# Add plugins
cordova plugin add cordova-plugin-device
cordova plugin add cordova-plugin-camera

# Build the app
cordova build

# Run on device/emulator
cordova run android
cordova run ios
```[No specific text provided]

### قوالب المشروع
```bash
# Create with specific template
cordova create MyApp com.example.myapp "My App" --template hello-world

# Create with custom template
cordova create MyApp com.example.myapp "My App" --template https://github.com/user/template.git

# Create blank project
cordova create MyApp com.example.myapp "My App" --template blank

# Create with TypeScript template
cordova create MyApp com.example.myapp "My App" --template cordova-template-typescript
```[No specific text provided]

## هيكل المشروع

### الهيكل الأساسي

MyApp/ ├── config.xml # Cordova configuration ├── package.json # Node.js dependencies ├── www/ # Web assets │ ├── index.html # Main HTML file │ ├── css/ # Stylesheets │ ├── js/ # JavaScript files │ └── img/ # Images ├── platforms/ # Platform-specific code (generated) │ ├── android/ │ └── ios/ ├── plugins/ # Installed plugins (generated) ├── hooks/ # Build hooks └── res/ # Resources (icons, splash screens) ├── icon/ └── screen/


### www/index.html
```html
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
    <title>My App</title>
    <link rel="stylesheet" type="text/css" href="css/index.css">
</head>
<body>
    <div class="app">
        <h1>Apache Cordova</h1>
        <div id="deviceready" class="blink">
            <p class="event listening">Connecting to Device</p>
            <p class="event received">Device is Ready</p>
        </div>
    </div>
    <script type="text/javascript" src="cordova.js"></script>
    <script type="text/javascript" src="js/index.js"></script>
</body>
</html>
```[No specific text provided]

### www/js/index.js
```javascript
var app = {
    // Application Constructor
    initialize: function() {
        document.addEventListener('deviceready', this.onDeviceReady.bind(this), false);
    },

    // deviceready Event Handler
    onDeviceReady: function() {
        this.receivedEvent('deviceready');
        
        // Cordova is now initialized. Have fun!
        console.log('Running cordova-' + cordova.platformId + '@' + cordova.version);
        
        // Example: Get device information
        console.log('Device Model: ' + device.model);
        console.log('Device Platform: ' + device.platform);
        console.log('Device Version: ' + device.version);
    },

    // Update DOM on a Received Event
    receivedEvent: function(id) {
        var parentElement = document.getElementById(id);
        var listeningElement = parentElement.querySelector('.listening');
        var receivedElement = parentElement.querySelector('.received');

        listeningElement.setAttribute('style', 'display:none;');
        receivedElement.setAttribute('style', 'display:block;');

        console.log('Received Event: ' + id);
    }
};

app.initialize();
```[No specific text provided]

## أوامر واجهة سطر الأوامر

### إدارة المشروع
```bash
# Create new project
cordova create <path> [id [name [config]]] [options]

# Add platform
cordova platform add <platform-name>
cordova platform add android
cordova platform add ios
cordova platform add browser

# Remove platform
cordova platform remove <platform-name>
cordova platform rm android

# List platforms
cordova platform list
cordova platform ls

# Update platform
cordova platform update <platform-name>

# Check platform version
cordova platform version
```[No specific text provided]

### إدارة الإضافات
```bash
# Add plugin
cordova plugin add <plugin-name>
cordova plugin add cordova-plugin-camera
cordova plugin add cordova-plugin-device

# Add plugin with variables
cordova plugin add cordova-plugin-facebook4 --variable APP_ID="123456789" --variable APP_NAME="myApplication"

# Remove plugin
cordova plugin remove <plugin-name>
cordova plugin rm cordova-plugin-camera

# List plugins
cordova plugin list
cordova plugin ls

# Search plugins
cordova plugin search camera

# Update plugin
cordova plugin update <plugin-name>
```[No specific text provided]

### البناء والتشغيل
```bash
# Build for all platforms
cordova build

# Build for specific platform
cordova build android
cordova build ios

# Build with options
cordova build android --release
cordova build ios --device

# Run on emulator
cordova emulate android
cordova emulate ios

# Run on device
cordova run android
cordova run ios

# Run with options
cordova run android --device
cordova run ios --target="iPhone-12"

# Serve for browser testing
cordova serve
cordova serve --port=8080
```[No specific text provided]

### أوامر المعلومات
```bash
# Check requirements
cordova requirements

# Get help
cordova help
cordova help platform

# Check version
cordova --version
cordova -v

# Get info about project
cordova info

# List available templates
cordova template list
```[No specific text provided]

## إدارة المنصات

### منصة Android
```bash
# Add Android platform
cordova platform add android

# Build for Android
cordova build android

# Run on Android emulator
cordova emulate android

# Run on Android device
cordova run android --device

# Build release APK
cordova build android --release

# Build with specific API level
cordova build android --gradleArg=-PcdvBuildToolsVersion=28.0.3

# Clean Android build
cordova clean android
```[No specific text provided]

### منصة iOS
```bash
# Add iOS platform (macOS only)
cordova platform add ios

# Build for iOS
cordova build ios

# Run on iOS simulator
cordova emulate ios

# Run on iOS device
cordova run ios --device

# Build for specific device
cordova build ios --device

# Build with provisioning profile
cordova build ios --codeSignIdentity="iPhone Developer" --provisioningProfile="UUID"

# Clean iOS build
cordova clean ios
```[No specific text provided]

### منصة المتصفح
```bash
# Add browser platform
cordova platform add browser

# Run in browser
cordova run browser

# Serve for browser testing
cordova serve

# Build for browser
cordova build browser
```[No specific text provided]

## نظام الإضافات

### الإضافات الأساسية
```bash
# Device Information
cordova plugin add cordova-plugin-device

# Camera
cordova plugin add cordova-plugin-camera

# File System
cordova plugin add cordova-plugin-file

# Network Information
cordova plugin add cordova-plugin-network-information

# Geolocation
cordova plugin add cordova-plugin-geolocation

# Contacts
cordova plugin add cordova-plugin-contacts

# Media
cordova plugin add cordova-plugin-media

# File Transfer
cordova plugin add cordova-plugin-file-transfer

# InAppBrowser
cordova plugin add cordova-plugin-inappbrowser

# Dialogs
cordova plugin add cordova-plugin-dialogs

# Vibration
cordova plugin add cordova-plugin-vibration

# Battery Status
cordova plugin add cordova-plugin-battery-status

# Splash Screen
cordova plugin add cordova-plugin-splashscreen

# Status Bar
cordova plugin add cordova-plugin-statusbar

# Whitelist
cordova plugin add cordova-plugin-whitelist
```[No specific text provided]

### أمثلة على استخدام الإضافات
```javascript
// Device Plugin
document.addEventListener("deviceready", function() {
    console.log("Device Model: " + device.model);
    console.log("Device Platform: " + device.platform);
    console.log("Device Version: " + device.version);
    console.log("Device UUID: " + device.uuid);
    console.log("Device Cordova: " + device.cordova);
}, false);

// Camera Plugin
function takePicture() {
    var options = {
        quality: 75,
        destinationType: Camera.DestinationType.FILE_URI,
        sourceType: Camera.PictureSourceType.CAMERA,
        encodingType: Camera.EncodingType.JPEG,
        targetWidth: 300,
        targetHeight: 300
    };

    navigator.camera.getPicture(onSuccess, onFail, options);

    function onSuccess(imageURI) {
        var image = document.getElementById('myImage');
        image.src = imageURI;
    }

    function onFail(message) {
        alert('Failed because: ' + message);
    }
}

// Geolocation Plugin
function getCurrentPosition() {
    var options = {
        enableHighAccuracy: true,
        timeout: 5000,
        maximumAge: 0
    };

    navigator.geolocation.getCurrentPosition(onSuccess, onError, options);

    function onSuccess(position) {
        console.log('Latitude: ' + position.coords.latitude);
        console.log('Longitude: ' + position.coords.longitude);
        console.log('Altitude: ' + position.coords.altitude);
        console.log('Accuracy: ' + position.coords.accuracy);
        console.log('Timestamp: ' + position.timestamp);
    }

    function onError(error) {
        alert('code: ' + error.code + '\n' + 'message: ' + error.message);
    }
}

// File Plugin
function writeFile() {
    window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fs) {
        fs.root.getFile("test.txt", {create: true, exclusive: false}, function(fileEntry) {
            fileEntry.createWriter(function(fileWriter) {
                fileWriter.onwriteend = function() {
                    console.log("Successful file write...");
                };

                fileWriter.onerror = function(e) {
                    console.log("Failed file write: " + e.toString());
                };

                var dataObj = new Blob(['some file data'], { type: 'text/plain' });
                fileWriter.write(dataObj);
            });
        }, onErrorCreateFile);
    }, onErrorLoadFs);
}

// Network Information Plugin
function checkConnection() {
    var networkState = navigator.connection.type;

    var states = {};
    states[Connection.UNKNOWN]  = 'Unknown connection';
    states[Connection.ETHERNET] = 'Ethernet connection';
    states[Connection.WIFI]     = 'WiFi connection';
    states[Connection.CELL_2G]  = 'Cell 2G connection';
    states[Connection.CELL_3G]  = 'Cell 3G connection';
    states[Connection.CELL_4G]  = 'Cell 4G connection';
    states[Connection.CELL]     = 'Cell generic connection';
    states[Connection.NONE]     = 'No network connection';

    alert('Connection type: ' + states[networkState]);
}
```[No specific text provided]

## الإعدادات

### config.xml

Note: For sections with no specific text (marked as [No specific text provided]), I've left them as placeholders. If you provide the specific text, I can translate those sections as well.```xml
<?xml version='1.0' encoding='utf-8'?>
<widget id="com.example.myapp" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
    <name>My App</name>
    <description>
        A sample Apache Cordova application.
    </description>
    <author email="dev@cordova.apache.org" href="http://cordova.io">
        Apache Cordova Team
    </author>
    
    <!-- Content source -->
    <content src="index.html" />
    
    <!-- Access control -->
    <access origin="*" />
    <allow-intent href="http://*/*" />
    <allow-intent href="https://*/*" />
    <allow-intent href="tel:*" />
    <allow-intent href="sms:*" />
    <allow-intent href="mailto:*" />
    <allow-intent href="geo:*" />
    
    <!-- Platform-specific configurations -->
    <platform name="android">
        <allow-intent href="market:*" />
        <icon density="ldpi" src="res/icon/android/ldpi.png" />
        <icon density="mdpi" src="res/icon/android/mdpi.png" />
        <icon density="hdpi" src="res/icon/android/hdpi.png" />
        <icon density="xhdpi" src="res/icon/android/xhdpi.png" />
        <icon density="xxhdpi" src="res/icon/android/xxhdpi.png" />
        <icon density="xxxhdpi" src="res/icon/android/xxxhdpi.png" />
        <splash density="land-ldpi" src="res/screen/android/splash-land-ldpi.png" />
        <splash density="land-mdpi" src="res/screen/android/splash-land-mdpi.png" />
        <splash density="land-hdpi" src="res/screen/android/splash-land-hdpi.png" />
        <splash density="land-xhdpi" src="res/screen/android/splash-land-xhdpi.png" />
        <splash density="land-xxhdpi" src="res/screen/android/splash-land-xxhdpi.png" />
        <splash density="land-xxxhdpi" src="res/screen/android/splash-land-xxxhdpi.png" />
        <splash density="port-ldpi" src="res/screen/android/splash-port-ldpi.png" />
        <splash density="port-mdpi" src="res/screen/android/splash-port-mdpi.png" />
        <splash density="port-hdpi" src="res/screen/android/splash-port-hdpi.png" />
        <splash density="port-xhdpi" src="res/screen/android/splash-port-xhdpi.png" />
        <splash density="port-xxhdpi" src="res/screen/android/splash-port-xxhdpi.png" />
        <splash density="port-xxxhdpi" src="res/screen/android/splash-port-xxxhdpi.png" />
    </platform>
    
    <platform name="ios">
        <allow-intent href="itms:*" />
        <allow-intent href="itms-apps:*" />
        <icon height="57" src="res/icon/ios/icon.png" width="57" />
        <icon height="114" src="res/icon/ios/icon@2x.png" width="114" />
        <icon height="40" src="res/icon/ios/icon-40.png" width="40" />
        <icon height="80" src="res/icon/ios/icon-40@2x.png" width="80" />
        <icon height="120" src="res/icon/ios/icon-40@3x.png" width="120" />
        <icon height="50" src="res/icon/ios/icon-50.png" width="50" />
        <icon height="100" src="res/icon/ios/icon-50@2x.png" width="100" />
        <icon height="60" src="res/icon/ios/icon-60.png" width="60" />
        <icon height="120" src="res/icon/ios/icon-60@2x.png" width="120" />
        <icon height="180" src="res/icon/ios/icon-60@3x.png" width="180" />
        <icon height="72" src="res/icon/ios/icon-72.png" width="72" />
        <icon height="144" src="res/icon/ios/icon-72@2x.png" width="144" />
        <icon height="76" src="res/icon/ios/icon-76.png" width="76" />
        <icon height="152" src="res/icon/ios/icon-76@2x.png" width="152" />
        <icon height="167" src="res/icon/ios/icon-83.5@2x.png" width="167" />
        <icon height="29" src="res/icon/ios/icon-small.png" width="29" />
        <icon height="58" src="res/icon/ios/icon-small@2x.png" width="58" />
        <icon height="87" src="res/icon/ios/icon-small@3x.png" width="87" />
        <splash height="1136" src="res/screen/ios/Default-568h@2x~iphone.png" width="640" />
        <splash height="1334" src="res/screen/ios/Default-667h.png" width="750" />
        <splash height="2208" src="res/screen/ios/Default-736h.png" width="1242" />
        <splash height="1242" src="res/screen/ios/Default-Landscape-736h.png" width="2208" />
        <splash height="1536" src="res/screen/ios/Default-Landscape@2x~ipad.png" width="2048" />
        <splash height="2048" src="res/screen/ios/Default-Landscape@~ipadpro.png" width="2732" />
        <splash height="768" src="res/screen/ios/Default-Landscape~ipad.png" width="1024" />
        <splash height="2048" src="res/screen/ios/Default-Portrait@2x~ipad.png" width="1536" />
        <splash height="2732" src="res/screen/ios/Default-Portrait@~ipadpro.png" width="2048" />
        <splash height="1024" src="res/screen/ios/Default-Portrait~ipad.png" width="768" />
        <splash height="960" src="res/screen/ios/Default@2x~iphone.png" width="640" />
        <splash height="480" src="res/screen/ios/Default~iphone.png" width="320" />
        <splash height="2732" src="res/screen/ios/Default@2x~universal~anyany.png" width="2732" />
    </platform>
    
    <!-- Preferences -->
    <preference name="DisallowOverscroll" value="true" />
    <preference name="android-minSdkVersion" value="19" />
    <preference name="BackupWebStorage" value="none" />
    <preference name="SplashMaintainAspectRatio" value="true" />
    <preference name="FadeSplashScreenDuration" value="300" />
    <preference name="SplashShowOnlyFirstTime" value="false" />
    <preference name="SplashScreen" value="screen" />
    <preference name="SplashScreenDelay" value="3000" />
    
    <!-- Plugin configurations -->
    <plugin name="cordova-plugin-whitelist" spec="1" />
    <plugin name="cordova-plugin-statusbar" spec="2" />
    <plugin name="cordova-plugin-device" spec="2" />
    <plugin name="cordova-plugin-splashscreen" spec="5" />
    <plugin name="cordova-plugin-ionic-webview" spec="^4.0.0" />
    <plugin name="cordova-plugin-ionic-keyboard" spec="^2.0.5" />
</widget>
```### تفضيلات خاصة بالمنصة
```xml
<!-- Android-specific preferences -->
<platform name="android">
    <preference name="android-minSdkVersion" value="19" />
    <preference name="android-targetSdkVersion" value="28" />
    <preference name="android-installLocation" value="auto" />
    <preference name="Orientation" value="portrait" />
    <preference name="Fullscreen" value="false" />
    <preference name="KeepRunning" value="true" />
    <preference name="LoadUrlTimeoutValue" value="20000" />
    <preference name="SplashScreen" value="splash" />
    <preference name="SplashScreenDelay" value="3000" />
    <preference name="InAppBrowserStorageEnabled" value="true" />
    <preference name="LoadingDialog" value="My Title,My Message" />
    <preference name="ErrorUrl" value="myErrorPage.html" />
    <preference name="ShowTitle" value="true" />
    <preference name="LogLevel" value="VERBOSE" />
</platform>

<!-- iOS-specific preferences -->
<platform name="ios">
    <preference name="CordovaWebViewEngine" value="CDVUIWebViewEngine" />
    <preference name="MinimumOSVersion" value="10.0" />
    <preference name="AllowInlineMediaPlayback" value="false" />
    <preference name="BackupWebStorage" value="none" />
    <preference name="TopActivityIndicator" value="gray" />
    <preference name="EnableViewportScale" value="false" />
    <preference name="KeyboardDisplayRequiresUserAction" value="true" />
    <preference name="SuppressesIncrementalRendering" value="false" />
    <preference name="SuppressesLongPressGesture" value="false" />
    <preference name="Suppresses3DTouchGesture" value="false" />
    <preference name="GapBetweenPages" value="0" />
    <preference name="PageLength" value="0" />
    <preference name="PaginationBreakingMode" value="page" />
    <preference name="PaginationMode" value="unpaginated" />
</platform>
```## واجهات برمجة التطبيقات للأجهزة
```javascript
// Take picture from camera
function capturePhoto() {
    var options = {
        quality: 50,
        destinationType: Camera.DestinationType.FILE_URI,
        sourceType: Camera.PictureSourceType.CAMERA,
        encodingType: Camera.EncodingType.JPEG,
        targetWidth: 300,
        targetHeight: 300,
        mediaType: Camera.MediaType.PICTURE,
        allowEdit: true,
        correctOrientation: true
    };

    navigator.camera.getPicture(onPhotoSuccess, onPhotoError, options);
}

// Select picture from gallery
function selectPhoto() {
    var options = {
        quality: 50,
        destinationType: Camera.DestinationType.FILE_URI,
        sourceType: Camera.PictureSourceType.PHOTOLIBRARY,
        mediaType: Camera.MediaType.PICTURE,
        allowEdit: true,
        encodingType: Camera.EncodingType.JPEG,
        targetWidth: 300,
        targetHeight: 300
    };

    navigator.camera.getPicture(onPhotoSuccess, onPhotoError, options);
}

function onPhotoSuccess(imageURI) {
    var image = document.getElementById('myImage');
    image.src = imageURI;
}

function onPhotoError(message) {
    alert('Failed because: ' + message);
}

// Cleanup camera resources
function cleanup() {
    navigator.camera.cleanup(onSuccess, onFail);
    
    function onSuccess() {
        console.log("Camera cleanup success.")
    }
    
    function onFail(message) {
        alert('Failed because: ' + message);
    }
}
```### واجهة برمجة التطبيقات الخاصة بالكاميرا
```javascript
// Get current position
function getCurrentLocation() {
    var options = {
        enableHighAccuracy: true,
        timeout: 10000,
        maximumAge: 60000
    };

    navigator.geolocation.getCurrentPosition(onLocationSuccess, onLocationError, options);
}

// Watch position changes
var watchID = null;

function watchLocation() {
    var options = {
        enableHighAccuracy: true,
        timeout: 30000,
        maximumAge: 60000
    };

    watchID = navigator.geolocation.watchPosition(onLocationSuccess, onLocationError, options);
}

function stopWatching() {
    if (watchID != null) {
        navigator.geolocation.clearWatch(watchID);
        watchID = null;
    }
}

function onLocationSuccess(position) {
    var element = document.getElementById('geolocation');
    element.innerHTML = 'Latitude: ' + position.coords.latitude + '<br />' +
                        'Longitude: ' + position.coords.longitude + '<br />' +
                        'Altitude: ' + position.coords.altitude + '<br />' +
                        'Accuracy: ' + position.coords.accuracy + '<br />' +
                        'Altitude Accuracy: ' + position.coords.altitudeAccuracy + '<br />' +
                        'Heading: ' + position.coords.heading + '<br />' +
                        'Speed: ' + position.coords.speed + '<br />' +
                        'Timestamp: ' + position.timestamp + '<br />';
}

function onLocationError(error) {
    alert('code: ' + error.code + '\n' + 'message: ' + error.message + '\n');
}
```### واجهة برمجة التطبيقات الخاصة بتحديد الموقع الجغرافي
```javascript
// Request file system
function requestFileSystem() {
    window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, onFileSystemSuccess, onFileSystemError);
}

function onFileSystemSuccess(fileSystem) {
    console.log(fileSystem.name);
    console.log(fileSystem.root.name);
}

function onFileSystemError(error) {
    console.log(error.code);
}

// Create file
function createFile() {
    window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fs) {
        fs.root.getFile("newFile.txt", {create: true, exclusive: false}, function(fileEntry) {
            console.log("File created: " + fileEntry.fullPath);
        }, onErrorCreateFile);
    }, onErrorLoadFs);
}

// Write to file
function writeToFile() {
    window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fs) {
        fs.root.getFile("newFile.txt", {create: true, exclusive: false}, function(fileEntry) {
            fileEntry.createWriter(function(fileWriter) {
                fileWriter.onwriteend = function() {
                    console.log("Successful file write...");
                    readFile();
                };

                fileWriter.onerror = function(e) {
                    console.log("Failed file write: " + e.toString());
                };

                var dataObj = new Blob(['some file data'], { type: 'text/plain' });
                fileWriter.write(dataObj);
            });
        }, onErrorCreateFile);
    }, onErrorLoadFs);
}

// Read file
function readFile() {
    window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fs) {
        fs.root.getFile("newFile.txt", {}, function(fileEntry) {
            fileEntry.file(function(file) {
                var reader = new FileReader();

                reader.onloadend = function() {
                    console.log("Successful file read: " + this.result);
                    displayFileData(fileEntry.fullPath + ": " + this.result);
                };

                reader.readAsText(file);
            }, onErrorReadFile);
        }, onErrorCreateFile);
    }, onErrorLoadFs);
}

// Delete file
function deleteFile() {
    window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fs) {
        fs.root.getFile("newFile.txt", {create: false}, function(fileEntry) {
            fileEntry.remove(function() {
                console.log("File deleted");
            }, onErrorDeleteFile);
        }, onErrorCreateFile);
    }, onErrorLoadFs);
}

function onErrorLoadFs(error) {
    console.log(error.code);
}

function onErrorCreateFile(error) {
    console.log(error.code);
}

function onErrorReadFile(error) {
    console.log(error.code);
}

function onErrorDeleteFile(error) {
    console.log(error.code);
}

function displayFileData(data) {
    document.getElementById("fileData").innerHTML = data;
}
```### واجهة برمجة التطبيقات الخاصة بنظام الملفات
```javascript
// Create contact
function createContact() {
    var contact = navigator.contacts.create();
    contact.displayName = "Plumber";
    contact.nickname = "Plumber";
    
    var name = new ContactName();
    name.givenName = "Jane";
    name.familyName = "Doe";
    contact.name = name;
    
    var phoneNumbers = [];
    phoneNumbers[0] = new ContactField('work', '212-555-1234', false);
    phoneNumbers[1] = new ContactField('mobile', '917-555-5432', true);
    contact.phoneNumbers = phoneNumbers;
    
    var emails = [];
    emails[0] = new ContactField('work', 'jane_doe@company.com', false);
    contact.emails = emails;
    
    contact.save(onContactSaveSuccess, onContactSaveError);
}

function onContactSaveSuccess(contact) {
    alert("Save Success");
}

function onContactSaveError(contactError) {
    alert("Error = " + contactError.code);
}

// Find contacts
function findContacts() {
    var options = new ContactFindOptions();
    options.filter = "Bob";
    options.multiple = true;
    var fields = ["displayName", "name"];
    navigator.contacts.find(fields, onContactFindSuccess, onContactFindError, options);
}

function onContactFindSuccess(contacts) {
    for (var i = 0; i < contacts.length; i++) {
        console.log("Display Name = " + contacts[i].displayName);
    }
}

function onContactFindError(contactError) {
    alert('onError!');
}

// Clone contact
function cloneContact() {
    var clone = contact.clone();
    clone.name.givenName = "John";
    clone.save(onContactSaveSuccess, onContactSaveError);
}

// Remove contact
function removeContact() {
    contact.remove(onContactRemoveSuccess, onContactRemoveError);
}

function onContactRemoveSuccess() {
    alert("Removal Success");
}

function onContactRemoveError(contactError) {
    alert("Error = " + contactError.code);
}
```### واجهة برمجة التطبيقات الخاصة بجهات الاتصال
```html
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>jQuery Mobile App</title>
    <link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css">
    <script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
    <script src="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
</head>
<body>
    <div data-role="page" id="home">
        <div data-role="header">
            <h1>My App</h1>
        </div>
        <div data-role="content">
            <ul data-role="listview" data-inset="true">
                <li><a href="#page2">Page 2</a></li>
                <li><a href="#page3">Page 3</a></li>
            </ul>
            <button onclick="takePicture()">Take Picture</button>
        </div>
        <div data-role="footer">
            <h4>Footer</h4>
        </div>
    </div>
    
    <div data-role="page" id="page2">
        <div data-role="header">
            <a href="#home" data-icon="arrow-l">Back</a>
            <h1>Page 2</h1>
        </div>
        <div data-role="content">
            <p>This is page 2</p>
        </div>
    </div>
    
    <script src="cordova.js"></script>
    <script src="js/index.js"></script>
</body>
</html>
```## أطر واجهات المستخدم
```html
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, minimal-ui, viewport-fit=cover">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
    <title>Framework7 App</title>
    <link rel="stylesheet" href="lib/framework7/css/framework7.bundle.min.css">
    <link rel="stylesheet" href="css/app.css">
</head>
<body>
    <div id="app">
        <div class="view view-main view-init" data-url="/">
            <div class="page" data-name="home">
                <div class="navbar">
                    <div class="navbar-bg"></div>
                    <div class="navbar-inner">
                        <div class="title">My App</div>
                    </div>
                </div>
                <div class="page-content">
                    <div class="block">
                        <p>Welcome to my Cordova app with Framework7!</p>
                        <a class="button button-fill" onclick="takePicture()">Take Picture</a>
                    </div>
                </div>
            </div>
        </div>
    </div>
    
    <script src="lib/framework7/js/framework7.bundle.min.js"></script>
    <script src="cordova.js"></script>
    <script src="js/app.js"></script>
</body>
</html>
```### دمج jQuery Mobile
```bash
# Install Ionic CLI
npm install -g @ionic/cli

# Create Ionic Cordova project
ionic start myApp tabs --type=angular --cordova

# Add platforms
ionic cordova platform add android
ionic cordova platform add ios

# Add plugins
ionic cordova plugin add cordova-plugin-camera

# Build and run
ionic cordova build android
ionic cordova run android
```### دمج Framework7
```bash
# Install live reload plugin
cordova plugin add cordova-plugin-browsersync

# Run with live reload
cordova run android --live-reload
cordova run ios --live-reload

# Serve for browser development
cordova serve
cordova serve --port=8080

# Use browser platform for quick testing
cordova platform add browser
cordova run browser
```### دمج Ionic Framework
```bash
# Install CodePush plugin
cordova plugin add cordova-plugin-code-push

# Configure CodePush
# Add to config.xml:
# <preference name="CodePushDeploymentKey" value="YOUR_DEPLOYMENT_KEY" />

# Release update
code-push release-cordova myApp-Android www 1.0.0
code-push release-cordova myApp-iOS www 1.0.0
```## سير العمل التطويري
```javascript
// hooks/before_build/010_add_platform_class.js
module.exports = function(context) {
    var fs = require('fs');
    var path = require('path');
    
    var platformsMap = {
        'android': 'android',
        'ios': 'ios',
        'browser': 'browser'
    };
    
    var platforms = context.opts.cordova.platforms;
    
    platforms.forEach(function(platform) {
        var indexPath = path.join(context.opts.projectRoot, 'www', 'index.html');
        var indexContent = fs.readFileSync(indexPath, 'utf8');
        
        // Add platform-specific class to body
        var platformClass = platformsMap[platform];
        if (platformClass) {
            indexContent = indexContent.replace(
                /<body([^>]*)>/,
                '<body$1 class="platform-' + platformClass + '">'
            );
            
            fs.writeFileSync(indexPath, indexContent);
        }
    });
};
```### التحميل المباشر
```javascript
// js/config.js
var Config = {
    development: {
        apiUrl: 'http://localhost:3000/api',
        debug: true
    },
    production: {
        apiUrl: 'https://api.myapp.com',
        debug: false
    }
};

// Detect environment
var environment = 'development';
if (window.location.protocol === 'file:') {
    environment = 'production';
}

var config = Config[environment];

// Usage
console.log('API URL:', config.apiUrl);
console.log('Debug mode:', config.debug);
```### الدفع السريع للكود
```bash
# Build debug version
cordova build android
cordova build ios

# Run debug on device
cordova run android --device --debug
cordova run ios --device --debug

# Enable debugging
cordova build android --debug
cordova build ios --debug
```### خطافات البناء
```bash
# Build release version
cordova build android --release
cordova build ios --release

# Sign Android APK
# Generate keystore
keytool -genkey -v -keystore my-release-key.keystore -alias alias_name -keyalg RSA -keysize 2048 -validity 10000

# Sign APK
jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore my-release-key.keystore platforms/android/app/build/outputs/apk/release/app-release-unsigned.apk alias_name

# Align APK
zipalign -v 4 platforms/android/app/build/outputs/apk/release/app-release-unsigned.apk MyApp.apk
```### إعدادات البيئة
```javascript
// test/spec/test.js
describe('App Tests', function() {
    beforeEach(function(done) {
        document.addEventListener('deviceready', done, false);
    });

    it('should have device plugin', function() {
        expect(window.device).toBeDefined();
        expect(device.platform).toBeDefined();
    });

    it('should have camera plugin', function() {
        expect(navigator.camera).toBeDefined();
        expect(navigator.camera.getPicture).toBeDefined();
    });

    it('should take picture', function(done) {
        var options = {
            quality: 50,
            destinationType: Camera.DestinationType.FILE_URI,
            sourceType: Camera.PictureSourceType.CAMERA
        };

        navigator.camera.getPicture(
            function(imageURI) {
                expect(imageURI).toBeDefined();
                done();
            },
            function(error) {
                fail('Camera error: ' + error);
                done();
            },
            options
        );
    });
});

// Run tests with Jasmine
// Include jasmine.js and jasmine-html.js in test.html
```## البناء والاختبار
```bash
# Chrome DevTools for Android
# 1. Enable USB debugging on Android device
# 2. Connect device to computer
# 3. Open Chrome and go to chrome://inspect
# 4. Select your app from the list

# Safari Web Inspector for iOS
# 1. Enable Web Inspector on iOS device (Settings > Safari > Advanced)
# 2. Connect device to Mac
# 3. Open Safari > Develop > [Device Name] > [App Name]

# Weinre (Web Inspector Remote)
npm install -g weinre
weinre --boundHost 0.0.0.0 --httpPort 8080

# Add to index.html:
# <script src="http://YOUR_IP:8080/target/target-script-min.js#anonymous"></script>
```### بنى التصحيح
```javascript
// Enhanced console logging
var Logger = {
    log: function(message, data) {
        if (window.console) {
            console.log('[LOG] ' + message, data || '');
        }
        this.writeToFile('LOG', message, data);
    },
    
    error: function(message, error) {
        if (window.console) {
            console.error('[ERROR] ' + message, error || '');
        }
        this.writeToFile('ERROR', message, error);
    },
    
    warn: function(message, data) {
        if (window.console) {
            console.warn('[WARN] ' + message, data || '');
        }
        this.writeToFile('WARN', message, data);
    },
    
    writeToFile: function(level, message, data) {
        // Write logs to file for later analysis
        var logEntry = new Date().toISOString() + ' [' + level + '] ' + message;
        if (data) {
            logEntry += ' ' + JSON.stringify(data);
        }
        
        // Implementation depends on file plugin
        // this.appendToLogFile(logEntry);
    }
};

// Usage
Logger.log('App started');
Logger.error('Network error', error);
Logger.warn('Low battery', batteryLevel);
```### بنى الإصدار
```javascript
// Global error handler
window.onerror = function(message, source, lineno, colno, error) {
    Logger.error('Global error: ' + message, {
        source: source,
        line: lineno,
        column: colno,
        error: error
    });
    
    // Send error to analytics service
    // Analytics.trackError(message, source, lineno);
    
    return true; // Prevent default browser error handling
};

// Unhandled promise rejection handler
window.addEventListener('unhandledrejection', function(event) {
    Logger.error('Unhandled promise rejection', event.reason);
    event.preventDefault();
});

// Cordova-specific error handling
document.addEventListener('deviceready', function() {
    // Handle plugin errors
    if (window.plugins && window.plugins.toast) {
        window.plugins.toast.showShortTop = function(message) {
            try {
                window.plugins.toast.show(message, 'short', 'top');
            } catch (error) {
                Logger.error('Toast plugin error', error);
                alert(message); // Fallback
            }
        };
    }
}, false);
```### الاختبار التلقائي
```javascript
// Efficient DOM manipulation
var DOMUtils = {
    createElement: function(tag, attributes, content) {
        var element = document.createElement(tag);
        
        if (attributes) {
            for (var attr in attributes) {
                element.setAttribute(attr, attributes[attr]);
            }
        }
        
        if (content) {
            element.innerHTML = content;
        }
        
        return element;
    },
    
    removeElement: function(element) {
        if (element && element.parentNode) {
            element.parentNode.removeChild(element);
        }
    },
    
    clearElement: function(element) {
        while (element.firstChild) {
            element.removeChild(element.firstChild);
        }
    }
};

// Memory-efficient list rendering
var ListView = {
    render: function(container, items, itemRenderer) {
        // Clear existing content
        DOMUtils.clearElement(container);
        
        // Use document fragment for efficient DOM updates
        var fragment = document.createDocumentFragment();
        
        items.forEach(function(item, index) {
            var itemElement = itemRenderer(item, index);
            fragment.appendChild(itemElement);
        });
        
        container.appendChild(fragment);
    },
    
    renderVirtual: function(container, items, itemRenderer, visibleCount) {
        // Virtual scrolling for large lists
        var startIndex = 0;
        var endIndex = Math.min(visibleCount, items.length);
        
        DOMUtils.clearElement(container);
        
        for (var i = startIndex; i < endIndex; i++) {
            var itemElement = itemRenderer(items[i], i);
            container.appendChild(itemElement);
        }
    }
};
```## التصحيح
```javascript
// Lazy loading images
var ImageLoader = {
    loadImage: function(src, callback) {
        var img = new Image();
        
        img.onload = function() {
            callback(null, img);
        };
        
        img.onerror = function() {
            callback(new Error('Failed to load image: ' + src));
        };
        
        img.src = src;
    },
    
    resizeImage: function(file, maxWidth, maxHeight, quality, callback) {
        var canvas = document.createElement('canvas');
        var ctx = canvas.getContext('2d');
        var img = new Image();
        
        img.onload = function() {
            var ratio = Math.min(maxWidth / img.width, maxHeight / img.height);
            canvas.width = img.width * ratio;
            canvas.height = img.height * ratio;
            
            ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
            
            canvas.toBlob(callback, 'image/jpeg', quality);
        };
        
        img.src = URL.createObjectURL(file);
    },
    
    preloadImages: function(urls, callback) {
        var loaded = 0;
        var total = urls.length;
        var images = [];
        
        if (total === 0) {
            callback(null, images);
            return;
        }
        
        urls.forEach(function(url, index) {
            this.loadImage(url, function(error, img) {
                if (error) {
                    callback(error);
                    return;
                }
                
                images[index] = img;
                loaded++;
                
                if (loaded === total) {
                    callback(null, images);
                }
            });
        }.bind(this));
    }
};
```### تحسين الشبكة
```javascript
// Network request manager
var NetworkManager = {
    cache: {},
    
    request: function(url, options, callback) {
        options = options || {};
        
        // Check cache first
        if (options.cache && this.cache[url]) {
            callback(null, this.cache[url]);
            return;
        }
        
        var xhr = new XMLHttpRequest();
        
        xhr.onreadystatechange = function() {
            if (xhr.readyState === 4) {
                if (xhr.status >= 200 && xhr.status < 300) {
                    var response = xhr.responseText;
                    
                    try {
                        response = JSON.parse(response);
                    } catch (e) {
                        // Response is not JSON
                    }
                    
                    // Cache successful responses
                    if (options.cache) {
                        this.cache[url] = response;
                    }
                    
                    callback(null, response);
                } else {
                    callback(new Error('HTTP ' + xhr.status + ': ' + xhr.statusText));
                }
            }
        }.bind(this);
        
        xhr.open(options.method || 'GET', url);
        
        // Set headers
        if (options.headers) {
            for (var header in options.headers) {
                xhr.setRequestHeader(header, options.headers[header]);
            }
        }
        
        xhr.send(options.body || null);
    },
    
    clearCache: function() {
        this.cache = {};
    },
    
    // Batch requests
    batch: function(requests, callback) {
        var completed = 0;
        var results = [];
        var hasError = false;
        
        requests.forEach(function(request, index) {
            this.request(request.url, request.options, function(error, response) {
                if (hasError) return;
                
                if (error) {
                    hasError = true;
                    callback(error);
                    return;
                }
                
                results[index] = response;
                completed++;
                
                if (completed === requests.length) {
                    callback(null, results);
                }
            });
        }.bind(this));
    }
};
```## الأمان

### سياسة أمان المحتوى
```html
<!-- Add to index.html -->
<meta http-equiv="Content-Security-Policy" content="
    default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval';
    style-src 'self' 'unsafe-inline';
    media-src *;
    img-src 'self' data: content:;
    connect-src 'self' https://api.myapp.com;
    script-src 'self' 'unsafe-inline' 'unsafe-eval';
">
```### التخزين الآمن
```javascript
// Secure data storage
var SecureStorage = {
    encrypt: function(data, key) {
        // Use a proper encryption library like CryptoJS
        return CryptoJS.AES.encrypt(JSON.stringify(data), key).toString();
    },
    
    decrypt: function(encryptedData, key) {
        try {
            var bytes = CryptoJS.AES.decrypt(encryptedData, key);
            var decryptedData = bytes.toString(CryptoJS.enc.Utf8);
            return JSON.parse(decryptedData);
        } catch (error) {
            throw new Error('Failed to decrypt data');
        }
    },
    
    store: function(key, data, password) {
        var encryptedData = this.encrypt(data, password);
        localStorage.setItem(key, encryptedData);
    },
    
    retrieve: function(key, password) {
        var encryptedData = localStorage.getItem(key);
        if (!encryptedData) {
            return null;
        }
        
        return this.decrypt(encryptedData, password);
    },
    
    remove: function(key) {
        localStorage.removeItem(key);
    }
};

// Usage
SecureStorage.store('userToken', { token: 'abc123' }, 'myPassword');
var userData = SecureStorage.retrieve('userToken', 'myPassword');
```### التحقق من المدخلات
```javascript
// Input validation utilities
var Validator = {
    email: function(email) {
        var regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
        return regex.test(email);
    },
    
    phone: function(phone) {
        var regex = /^\+?[\d\s\-\(\)]+$/;
        return regex.test(phone) && phone.replace(/\D/g, '').length >= 10;
    },
    
    url: function(url) {
        try {
            new URL(url);
            return true;
        } catch (error) {
            return false;
        }
    },
    
    sanitize: function(input) {
        return input.replace(/[<>'"&]/g, function(match) {
            var entities = {
                '<': '&lt;',
                '>': '&gt;',
                '"': '&quot;',
                "'": '&#x27;',
                '&': '&amp;'
            };
            return entities[match];
        });
    },
    
    length: function(input, min, max) {
        return input.length >= min && input.length <= max;
    },
    
    required: function(input) {
        return input !== null && input !== undefined && input.toString().trim() !== '';
    }
};

// Form validation
var FormValidator = {
    validate: function(form, rules) {
        var errors = {};
        
        for (var field in rules) {
            var value = form[field];
            var fieldRules = rules[field];
            
            for (var rule in fieldRules) {
                var ruleValue = fieldRules[rule];
                var isValid = false;
                
                switch (rule) {
                    case 'required':
                        isValid = ruleValue ? Validator.required(value) : true;
                        break;
                    case 'email':
                        isValid = ruleValue ? Validator.email(value) : true;
                        break;
                    case 'minLength':
                        isValid = value ? value.length >= ruleValue : true;
                        break;
                    case 'maxLength':
                        isValid = value ? value.length <= ruleValue : true;
                        break;
                }
                
                if (!isValid) {
                    errors[field] = errors[field] || [];
                    errors[field].push(rule);
                }
            }
        }
        
        return {
            isValid: Object.keys(errors).length === 0,
            errors: errors
        };
    }
};

// Usage
var formData = {
    email: 'user@example.com',
    password: '123456',
    name: 'John Doe'
};

var rules = {
    email: { required: true, email: true },
    password: { required: true, minLength: 6 },
    name: { required: true, maxLength: 50 }
};

var validation = FormValidator.validate(formData, rules);
if (!validation.isValid) {
    console.log('Validation errors:', validation.errors);
}
```## النشر

### نشر متجر التطبيقات
```bash
# iOS App Store
# 1. Build release version
cordova build ios --release

# 2. Open Xcode project
open platforms/ios/MyApp.xcworkspace

# 3. Configure signing and provisioning
# 4. Archive and upload to App Store Connect

# Google Play Store
# 1. Generate signed APK
cordova build android --release

# 2. Sign APK with keystore
jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore my-release-key.keystore platforms/android/app/build/outputs/apk/release/app-release-unsigned.apk alias_name

# 3. Align APK
zipalign -v 4 platforms/android/app/build/outputs/apk/release/app-release-unsigned.apk MyApp.apk

# 4. Upload to Google Play Console
```### التوزيع المؤسسي
```bash
# iOS Enterprise Distribution
# 1. Build with enterprise certificate
cordova build ios --release

# 2. Create IPA file
# 3. Host on internal server with manifest.plist

# Android Enterprise Distribution
# 1. Build signed APK
cordova build android --release

# 2. Distribute through MDM or direct download
```### التكامل المستمر
```yaml
# .github/workflows/build.yml
name: Build App

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  build:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v2
    
    - name: Setup Node.js
      uses: actions/setup-node@v2
      with:
        node-version: '14'
    
    - name: Install dependencies
      run: npm install
    
    - name: Install Cordova
      run: npm install -g cordova
    
    - name: Add platforms
      run: |
        cordova platform add android
        cordova platform add ios
    
    - name: Build Android
      run: cordova build android
    
    - name: Build iOS
      run: cordova build ios
    
    - name: Run tests
      run: npm test
    
    - name: Upload artifacts
      uses: actions/upload-artifact@v2
      with:
        name: builds
        path: platforms/*/build/
```## أفضل الممارسات

### تنظيم المشروع

src/ ├── js/ │ ├── app.js # Main application logic │ ├── config.js # Configuration │ ├── utils.js # Utility functions │ ├── services/ # API services │ ├── models/ # Data models │ └── views/ # View controllers ├── css/ │ ├── app.css # Main styles │ ├── components/ # Component styles │ └── themes/ # Theme styles ├── templates/ # HTML templates ├── assets/ │ ├── images/ │ ├── fonts/ │ └── sounds/ └── tests/ # Test files

```javascript
// Use strict mode
'use strict';

// Namespace your code
var MyApp = MyApp || {};

MyApp.Utils = {
    // Utility functions
};

MyApp.Services = {
    // Service functions
};

MyApp.Views = {
    // View controllers
};

// Use consistent error handling
MyApp.ErrorHandler = {
    handle: function(error, context) {
        console.error('Error in ' + context + ':', error);
        
        // Log to analytics service
        if (MyApp.Analytics) {
            MyApp.Analytics.trackError(error, context);
        }
        
        // Show user-friendly message
        if (navigator.notification) {
            navigator.notification.alert(
                'An error occurred. Please try again.',
                null,
                'Error',
                'OK'
            );
        } else {
            alert('An error occurred. Please try again.');
        }
    }
};

// Use consistent coding style
var MyApp = {
    init: function() {
        this.bindEvents();
        this.setupUI();
    },
    
    bindEvents: function() {
        document.addEventListener('deviceready', this.onDeviceReady.bind(this), false);
        document.addEventListener('pause', this.onPause.bind(this), false);
        document.addEventListener('resume', this.onResume.bind(this), false);
    },
    
    onDeviceReady: function() {
        console.log('Device ready');
        this.setupPlugins();
    },
    
    onPause: function() {
        console.log('App paused');
        this.saveState();
    },
    
    onResume: function() {
        console.log('App resumed');
        this.restoreState();
    },
    
    setupPlugins: function() {
        // Initialize plugins
    },
    
    setupUI: function() {
        // Setup user interface
    },
    
    saveState: function() {
        // Save application state
    },
    
    restoreState: function() {
        // Restore application state
    }
};
```### إرشادات الأداء
```javascript
// Optimize for mobile performance
var PerformanceOptimizer = {
    // Debounce function calls
    debounce: function(func, wait) {
        var timeout;
        return function() {
            var context = this;
            var args = arguments;
            clearTimeout(timeout);
            timeout = setTimeout(function() {
                func.apply(context, args);
            }, wait);
        };
    },
    
    // Throttle function calls
    throttle: function(func, limit) {
        var inThrottle;
        return function() {
            var args = arguments;
            var context = this;
            if (!inThrottle) {
                func.apply(context, args);
                inThrottle = true;
                setTimeout(function() {
                    inThrottle = false;
                }, limit);
            }
        };
    },
    
    // Optimize scroll events
    optimizeScroll: function(element, callback) {
        var ticking = false;
        
        function update() {
            callback();
            ticking = false;
        }
        
        function requestTick() {
            if (!ticking) {
                requestAnimationFrame(update);
                ticking = true;
            }
        }
        
        element.addEventListener('scroll', requestTick);
    },
    
    // Lazy load content
    lazyLoad: function(elements, callback) {
        var observer = new IntersectionObserver(function(entries) {
            entries.forEach(function(entry) {
                if (entry.isIntersecting) {
                    callback(entry.target);
                    observer.unobserve(entry.target);
                }
            });
        });
        
        elements.forEach(function(element) {
            observer.observe(element);
        });
    }
};
```---

## ملخص

يوفر Apache Cordova/PhoneGap منصة قوية لتطوير تطبيقات الهاتف المحمول الهجينة:

**المميزات:**
- **متعدد المنصات**: اكتب مرة واحدة، شغّل على منصات متعددة
- **تقنيات الويب**: استخدم HTML، CSS، وJavaScript المألوفة
- **نظام الإضافات**: الوصول إلى ميزات الجهاز الأصلية من خلال الإضافات
- **التطوير السريع**: دورة تطوير أسرع من التطبيقات الأصلية
- **فعال من حيث التكلفة**: قاعدة كود واحدة لمنصات متعددة

**أفضل حالات الاستخدام:**
- التطبيقات المعتمدة على المحتوى
- التطبيقات التجارية
- النماذج الأولية وMVP
- التطبيقات ذات متطلبات واجهة مستخدم بسيطة
- التطبيقات متعددة المنصات مع احتياجات محدودة للوظائف الأصلية

**اعتبارات:**
- قد يكون الأداء أبطأ من التطبيقات الأصلية
- وصول محدود إلى أحدث ميزات المنصة
- قد لا تبدو واجهة المستخدم أصلية تمامًا
- يتطلب تحسين دقيق للأداء السلس

يبقى Cordova خيارًا مجديًا للعديد من مشاريع تطبيقات الهاتف المحمول، خاصة عندما تكون سرعة التطوير والتكلفة والتوافق بين المنصات أولوية على الأداء الأقصى والتكامل مع المنصة الأصلية.

<script>
function copyToClipboard() {
    const commands = document.querySelectorAll('code');
    let allCommands = '';
    commands.forEach(cmd => allCommands += cmd.textContent + '\n');
    navigator.clipboard.writeText(allCommands);
    alert('تم نسخ جميع الأوامر إلى الحافظة!');
}

function generatePDF() {
    window.print();
}
</script>